/* ---------------------------------------------------------------------------
 * alloInfirmière — feuille unique, sans build.
 *
 * Reprend la charte existante et n'en modernise que la matière (conception.md
 * §8) : le bleu marine et le cyan du logo restent, la navigation reste à plat,
 * et surtout la DENSITÉ reste — une infirmière saisit entre deux visites, une
 * modernisation qui aère détruit d'abord ce qu'elle vient chercher.
 *
 * Ce que la refonte corrige : les largeurs figées en pixels, Verdana et
 * Trebuchet MS, les cadres à ombre portée, le pied de page gris sur gris.
 * Les trois premiers points sont tenus par tests/Architecture/StylesheetTest.
 * ------------------------------------------------------------------------- */

/* Figtree (lot 14, §6.3) : sous-ensemble latin, servie depuis public/fonts/. */
@font-face {
    font-family: "Figtree";
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/figtree-latin-400-normal.woff2") format("woff2");
}
@font-face {
    font-family: "Figtree";
    font-weight: 600;
    font-display: swap;
    src: url("/fonts/figtree-latin-600-normal.woff2") format("woff2");
}
@font-face {
    font-family: "Figtree";
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/figtree-latin-700-normal.woff2") format("woff2");
}

:root {
    /* Les deux couleurs du logo, inchangées. */
    --primary: #003f84;
    --primary-hover: #002a58;
    --on-primary: #ffffff;
    --accent: #00b6e8;
    --accent-soft: #e5f5fa;
    --accent-strong: #0087ad;
    /* Contour de focus : 3:1 au moins sur les fonds clairs (WCAG 1.4.11). */
    --focus: #0093bd;
    /* En-tête, onglets et titre de cartouche (palette B : dégradé marine,
       bandeau de cartouche clair). */
    --header-bg: linear-gradient(100deg, #002a58 0%, #003f84 55%, #0a5aa8 100%);
    --header-text: #ffffff;
    --tab-text: #d3e1f1;
    --tab-hover-bg: rgb(255 255 255 / 12%);
    --tab-active-bg: #ffffff;
    --tab-active-text: #003f84;
    --tab-active-shadow: 0 0.125rem 0.5rem rgb(0 20 50 / 25%);
    /* Champ de recherche translucide sur le dégradé de l'en-tête. */
    --header-field-bg: rgb(255 255 255 / 12%);
    --header-field-border: rgb(255 255 255 / 25%);
    --header-field-border-hover: rgb(255 255 255 / 45%);
    --header-field-placeholder: rgb(255 255 255 / 80%);
    /* Bouton « Ajouter » du champ global : cyan du logo, texte marine (spec §6.5). */
    --header-action-bg: #00b6e8;
    --header-action-text: #002a44;
    /* Pastille d'initiales : marine sur blanc (le blanc sur cyan tombe sous AA). */
    --avatar-bg: var(--primary);
    --avatar-text: var(--on-primary);
    --frame-head-bg: #eaf0f8;
    --frame-head-text: #003f84;
    /* Le bleu des noms d'infirmière de la journée au legacy (liste_feuille_route.php l.218). */
    --legacy-nurse: #174867;
    /* Le gris du cadre « Transmission: » de la saisie au legacy (transmissions.php l.712). */
    --legacy-frame: #a4a4a4;

    /* Rampe neutre : le gris sur gris du pied de page venait de n'en avoir
       que deux valeurs, toutes deux claires. */
    --bg: #f4f2ee;
    --text: #1d2430;
    --text-muted: #666b74;
    --border: #e4e0d8;
    --border-soft: #efece6;
    --border-strong: #cdc7bc;
    --surface: #ffffff;
    --surface-muted: #faf9f6;
    --surface-sunken: #efece6;

    --success: #1d7a46;
    --success-soft: #e3f4ea;
    --danger: #b3261e;
    --danger-soft: #fcebea;
    --info-soft: #e6f3fb;
    /* Le jour courant du calendrier du mois : jaune, comme le `ui-state-highlight` du legacy (lot 15, décisions 6 et 11). */
    --calendar-today-bg: #fdf3c4;
    --calendar-today-border: #e0b83c;
    /* Le jour courant de la semaine, et les repères neutres d'une tournée sans couleur. */
    --today-bg: #fdf3c4;
    --round-default: #cdc7bc;
    --round-dot-default: #6a6f78;

    /* Ombres : une variable entière, jamais un rgb() dans une règle. */
    --shadow: 0 0.0625rem 0.1875rem rgb(40 30 10 / 6%);
    --shadow-raised: 0 0.5rem 1.5rem rgb(40 30 10 / 8%);

    /* Figtree d'abord ; le repli système sert le temps du chargement (swap). */
    --font: "Figtree", system-ui, sans-serif;

    /* Échelle d'espacement serrée : c'est elle qui porte la densité. */
    --gap-xs: 0.25rem;
    --gap-sm: 0.5rem;
    --gap: 0.75rem;
    --gap-lg: 1.25rem;

    --radius: 0.5rem;
    --radius-sm: 0.125rem;
    --radius-lg: 0.875rem;
    --radius-pill: 999px;
}

*, *::before, *::after { box-sizing: border-box; }

html { font-size: 100%; }

body {
    margin: 0;
    /* Colonne pleine hauteur : sans cela le pied de page s'arrete au contenu
       et laisse une bande de fond vide en dessous sur les pages courtes. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    font-family: var(--font);
    font-size: 0.875rem;      /* 14px : la taille du legacy, conservée. */
    line-height: 1.35;        /* serré volontairement. */
    color: var(--text);
    background: var(--bg);
}

a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Le clavier est l'outil de saisie rapide : le focus doit se voir partout. */
:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 2px;
}

/* --- Lien d'évitement ---------------------------------------------------- */

.skip-link {
    position: absolute;
    left: -100vw;
    top: 0;
    z-index: 10;
    padding: var(--gap-sm) var(--gap);
    background: var(--primary);
    color: var(--on-primary);
}
.skip-link:focus { left: 0; }

/* --- En-tête ------------------------------------------------------------- */

.app-header {
    background: var(--header-bg);
    color: var(--header-text);
}

.app-header__bar,
.page,
.app-footer > p {
    /* Fluide, borné en rem : plus aucune largeur figée en pixels. */
    width: 100%;
    max-width: 78rem;
    margin-inline: auto;
    padding-inline: var(--gap-lg);
}

/* Bandeau connecte : la meme largeur que la coquille en dessous (.shell n'a
   pas de max-width), pas les 78rem du bandeau de connexion. */
.app-header:has(.tabs) .app-header__bar {
    max-width: none;
}

.app-header__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    padding-block: var(--gap-sm);
}

.brand {
    color: var(--header-text);
    font-size: 1.25rem;
    font-weight: 400;
    letter-spacing: -0.01em;
}
.brand strong { color: var(--accent); font-weight: 700; }
.brand:hover { text-decoration: none; }

/* --- Champ global « Rechercher/Ajouter un patient » ---------------------- */
/* Formulaire GET simple ; public/patient-search.js l'enrichit en combobox
   (aria-expanded, listbox) sans rien lui retirer si le script ne charge pas. */

.patient-search { display: flex; gap: var(--gap-sm); align-items: center; flex: 1 1 24rem; max-width: 36rem; }
.patient-search__box { position: relative; flex: 1 1 auto; }
/* Champ translucide sur le dégradé, loupe en fichier de public/ (la CSP
   bloque les URI data:). */
.app-header .patient-search__box input[type="search"] {
    width: 100%;
    height: 2.1rem;
    padding: 0 0.75rem 0 2rem;
    border: 1px solid var(--header-field-border);
    background: var(--header-field-bg) url("/search.svg") no-repeat 0.65rem center;
    color: var(--header-text);
}
.app-header .patient-search__box input[type="search"]::placeholder { color: var(--header-field-placeholder); }
.app-header .patient-search__box input[type="search"]:hover { border-color: var(--header-field-border-hover); }
.app-header .patient-search__box input[type="search"]:focus {
    background-color: var(--surface);
    color: var(--text);
    outline: 3px solid transparent;
    box-shadow: 0 0 0 3px var(--focus);
}
.app-header .patient-search .button {
    border-radius: var(--radius-pill);
    border-color: var(--header-action-bg);
    background: var(--header-action-bg);
    color: var(--header-action-text);
}
.app-header .patient-search .button:hover {
    border-color: var(--surface);
    background: var(--surface);
    color: var(--primary);
}
/* Le cyan du focus par défaut disparaît sur le marine : le contour passe au cyan du logo. */
.app-header :focus-visible { outline-color: var(--accent); }
.patient-search__list {
    position: absolute; z-index: 10; left: 0; right: 0; top: 100%;
    margin: 0.125rem 0 0; padding: 0; list-style: none;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow-raised);
}
.patient-search__option { padding: var(--gap-xs) var(--gap-sm); cursor: pointer; color: var(--text); }
.patient-search__option:hover,
.patient-search__option[aria-selected="true"] { background: var(--accent); }

/* --- Navigation à plat --------------------------------------------------- */

.tabs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-xs);
    width: 100%;
    padding: 0 var(--gap-lg) 0.6rem;
}

/* Onglets en pastilles posées dans le bandeau (palette B). */
.tabs__tab {
    padding: 0.4rem 0.95rem;
    color: var(--tab-text);
    border-radius: var(--radius-pill);
    font-size: 0.875rem;
    font-weight: 600;
}
.tabs__tab:hover { background: var(--tab-hover-bg); color: var(--header-text); text-decoration: none; }
.tabs__tab.is-active { background: var(--tab-active-bg); color: var(--tab-active-text); box-shadow: var(--tab-active-shadow); }
.tabs__tab.is-active:hover { background: var(--tab-active-bg); color: var(--tab-active-text); }

/* --- Page ---------------------------------------------------------------- */

.page {
    flex: 1 0 auto;
    padding-block: var(--gap-lg);
}

/* --- Lot 5 : la coquille du legacy, modernisee ---------------------------
   Onglets en haut, colonne gauche de cartouches, cartouche central titre.
   Pas de largeur maximale : la densite sur grand ecran rend la preparation
   rapide (conception §8, « Ou l'on travaille »). */
.shell {
    display: grid;
    grid-template-columns: 12rem minmax(0, 1fr);
    gap: var(--gap-lg);
    padding: var(--gap-lg);
    align-items: start;
}
.sidebar { display: grid; gap: var(--gap); }
.frame {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}
/* `overflow: hidden` sur .frame rognait tout contenu central trop large
   (compose de la feuille de route, tables larges) : restreint aux
   cartouches de la colonne, qui n'ont pas ce besoin. Les coins de
   .frame__head restent propres grace a son propre rayon, ci-dessous. */
.sidebar .frame { overflow: hidden; }
.frame__head,
.frame__head h1 {
    margin: 0;
    padding: var(--gap-sm) var(--gap);
    background: var(--frame-head-bg);
    color: var(--frame-head-text);
    font-size: 0.8125rem;
    font-weight: 700;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.frame__head { display: flex; align-items: center; gap: var(--gap-sm); }
.frame__head h1 { padding: 0; font-size: 1.125rem; }
.frame__body { padding: var(--gap); }

/* Le cartouche du nom : fond blanc, nom en clair, pastille d'initiales. */
.frame--nurse .frame__head { background: var(--surface); font-size: 0.9rem; }
.avatar {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: var(--avatar-bg);
    color: var(--avatar-text);
    font-size: 0.7rem;
    font-weight: 700;
}

/* Sous-menu : l'entrée courante porte un trait cyan à gauche. */
.submenu { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.125rem; }
.submenu__item a {
    display: block;
    padding: 0.45rem 0.6rem;
    border-radius: var(--radius);
    color: var(--text);
    text-decoration: none;
}
.submenu__item a:hover { background: var(--surface-muted); }
.submenu__item a.is-current {
    background: var(--accent-soft);
    color: var(--primary);
    font-weight: 700;
    box-shadow: inset 0.1875rem 0 0 var(--accent);
}
.tabs__signout { margin: 0 0 0 auto; }
.tabs__signout button { background: none; border: 0; cursor: pointer; font: inherit; }

.tabbar { display: none; }

@media (max-width: 45rem) {
    .shell { grid-template-columns: minmax(0, 1fr); }
    /* Téléphone : la colonne, le pied de page et les onglets du haut cèdent la
       place à la barre du bas. */
    .sidebar { display: none; }
    /* Réservé aux pages à barre du bas : /login et le 403 gardent leur pied de page. */
    body:has(.tabbar) .app-footer { display: none; }
    .app-menu { display: none; }
    /* En-tête sur une ligne : la marque à gauche, la recherche à droite, la
       loupe remplaçant le mot « Ajouter » (toujours lu : visuellement masqué). */
    .app-header__bar { flex-wrap: nowrap; gap: var(--gap-sm); }
    .patient-search { flex: 1 1 auto; min-width: 0; max-width: none; }
    .patient-search__label {
        position: absolute; width: 0.0625rem; height: 0.0625rem; overflow: hidden;
        clip: rect(0 0 0 0); white-space: nowrap;
    }
    /* Le contenu garde une marge basse égale à la hauteur de la barre. */
    body:has(.tabbar) { padding-bottom: calc(3.5rem + env(safe-area-inset-bottom)); }
    .tabbar {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 20;
        height: calc(3.5rem + env(safe-area-inset-bottom));
        padding-bottom: env(safe-area-inset-bottom);
        background: var(--surface);
        border-top: 1px solid var(--border);
    }
    .tabbar__tab, .tabbar__more { flex: 1 1 0; min-width: 0; }
    .tabbar__tab {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.125rem;
        height: 100%;
        padding: 0 0.125rem;
        border-bottom: 0.1875rem solid transparent;
        color: var(--text-muted);
        font-size: 0.6875rem;
        font-weight: 600;
        line-height: 1.1;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
    }
    .tabbar__tab[aria-current="page"], .tabbar__tab.is-active {
        color: var(--primary);
        border-bottom-color: var(--accent);
    }
    .tabbar__more { position: relative; }
    .tabbar__more summary { list-style: none; }
    .tabbar__more summary::-webkit-details-marker { display: none; }
    /* Le panneau s'ouvre vers le haut, au-dessus de la barre. */
    .tabbar__panel {
        position: absolute;
        right: 0;
        bottom: 100%;
        width: min(18rem, 100vw);
        max-height: 70vh;
        overflow-y: auto;
        padding: var(--gap-sm);
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        box-shadow: var(--shadow-raised);
    }
    .tabbar__nurse { margin: 0 0 var(--gap-sm); font-weight: 700; color: var(--primary); }
    .tabbar__signout { margin: var(--gap-sm) 0 0; }
    .tabbar__signout button { width: 100%; }
}

h1 {
    margin: 0 0 var(--gap) 0;
    font-size: 1.375rem;
    color: var(--primary);
    font-weight: 600;
}

h2 {
    margin: var(--gap-lg) 0 var(--gap-sm) 0;
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--gap-xs);
}

/* --- Blocs de contenu ---------------------------------------------------- */

.panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--gap-lg);
}
/* Un titre de section ouvrant un panneau n'a rien a decoller. */
.panel > h2:first-child { margin-top: 0; }
/* Deux panneaux empilés dans la page ne se collent pas bord contre bord. Pas
   ceux d'une grille côte à côte : la marge décalerait le second vers le bas. */
.frame__body > .panel + .panel { margin-top: var(--gap); }

.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap);
    margin-bottom: var(--gap);
}
.toolbar > * { margin: 0; }
.toolbar__spacer { flex: 1 1 auto; }

/* Le nom sur la fiche patient : le titre du cartouche dit deja « Fiche
   administrative », ce n'est plus un <h1> mais il reste le premier repere
   visuel du contenu. */
.record-name { margin: 0 0 var(--gap); font-size: 1.25rem; }

.backlink {
    display: inline-block;
    margin-bottom: var(--gap-sm);
    color: var(--text-muted);
}

/* --- Messages ------------------------------------------------------------ */

.alert {
    margin: 0 0 var(--gap) 0;
    padding: var(--gap-sm) var(--gap);
    border: 1px solid var(--danger);
    border-left-width: 4px;
    border-radius: var(--radius);
    background: var(--danger-soft);
    color: var(--danger);
}

/* .offline-banner : bandeau de la copie hors ligne (lot 16b), montré par
   offline-state.js (attribut hidden retiré) ; même habillage que l'avis. */
.notice,
.offline-banner {
    margin: 0 0 var(--gap) 0;
    padding: var(--gap-sm) var(--gap);
    border: 1px solid var(--border);
    border-left: 4px solid var(--primary);
    border-radius: var(--radius);
    background: var(--info-soft);
    color: var(--text);
    font-weight: 700;
}

/* --- Consultation hors ligne (lot 16b) ------------------------------------ */

/* Le bandeau de la copie partage la règle de .notice (Messages, ci-dessus). */

/* Case « Garder la tournée du jour » : montrée par offline-keep.js. Le label
   reste en ligne pour que le statut suive la case. */
.offline-keep {
    margin: 0 0 var(--gap) 0;
    color: var(--text);
}

.offline-keep label {
    display: inline-flex;
    align-items: center;
    gap: var(--gap-xs);
    margin: 0;
}

.offline-keep__status { color: var(--text-muted); }

/* Gestes d'écriture grisés sur la copie : offline-state.js pose aria-disabled. */
[data-offline-write][aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}

.muted { color: var(--text-muted); }

.visually-hidden { position: absolute; width: 0.0625rem; height: 0.0625rem; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

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

form { margin: 0; }

label {
    display: block;
    margin-bottom: var(--gap-xs);
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--text);
}

/* L'habillage commun de TOUS les contrôles de saisie (lot 9, plan A) : même
   hauteur (≈ 33 px), même bordure, même police. select et number en étaient
   absents — contrôles natifs de 18 px à côté de champs de 34 px, la première
   cause de l'impression d'« inachevé ». Le champ date-heure de la saisie est
   devenu une date seule au lot 11 (§6.3). */
input[type="text"], input[type="email"], input[type="password"],
input[type="tel"], input[type="date"], input[type="search"],
input[type="number"], textarea, select {
    padding: 0.375rem 0.5rem;
    font: inherit;
    color: var(--text);
    background-color: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    transition: border-color 0.12s, box-shadow 0.12s;
}

/* Aucune largeur figée : le champ remplit sa colonne de grille. Dans une
   barre de filtres, 100 % se résout à la taille native du champ. */
input[type="text"], input[type="email"], input[type="password"],
input[type="tel"], input[type="date"], input[type="search"],
input[type="number"], textarea {
    width: 100%;
}

/* La liste déroulante garde sa largeur naturelle : dans une ligne d'actions
   (assignation, tournée de la fiche, déplacement d'une note) elle ne prend
   pas toute la place. Dans une grille de formulaire, elle la remplit.
   La flèche est un FICHIER de public/ : une URI data: serait bloquée par la
   CSP default-src 'self' (journal du lot 9, décision 2). */
select {
    max-width: 100%;
    appearance: none;
    padding-right: 1.75rem;
    background-image: url("/select-arrow.svg");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
    background-size: 0.75rem;
    cursor: pointer;
}
.field-grid select { width: 100%; }

input:hover, textarea:hover, select:hover { border-color: var(--text-muted); }
/* Le contour de :focus-visible (règle globale) reste le signal clavier ; la
   bordure et le halo disent « champ actif » à la souris aussi. */
input:focus, textarea:focus, select:focus {
    border-color: var(--focus);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { resize: vertical; }

fieldset {
    margin: var(--gap-lg) 0;
    padding: var(--gap) var(--gap-lg) var(--gap-lg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-sunken);
}
legend {
    padding-inline: var(--gap-sm);
    font-weight: 600;
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

/* Deux colonnes tant que la place le permet, une seule ensuite. Les champs
   courts (code postal, dates) ne consomment pas une ligne entière pour rien :
   c'est là que la densité se gagne sur un formulaire. */
.field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
    gap: var(--gap) var(--gap-lg);
}
.field { margin-bottom: 0; }
.field--wide { grid-column: 1 / -1; }
.field--check {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
}
.field--check label { margin-bottom: 0; }

.form-actions {
    display: flex;
    gap: var(--gap);
    align-items: center;
    margin-top: var(--gap-lg);
    padding-top: var(--gap);
    border-top: 1px solid var(--border-soft);
}
/* Sur téléphone, les boutons passent à la ligne au lieu de dépasser l'écran
   (lot 16a) ; au-dessus de 45rem, rien ne change. */
@media (max-width: 45rem) {
    .form-actions { flex-wrap: wrap; }
}

/* --- Boutons ------------------------------------------------------------- */

button, .button {
    display: inline-block;
    padding: 0.375rem 0.875rem;
    font: inherit;
    font-weight: 600;
    color: var(--on-primary);
    background: var(--primary);
    border: 1px solid var(--primary);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s;
}
button:hover, .button:hover { background: var(--primary-hover); border-color: var(--primary-hover); text-decoration: none; }

.button--secondary {
    color: var(--primary);
    background: var(--surface);
    border-color: var(--border-strong);
}
.button--secondary:hover { background: var(--surface-muted); border-color: var(--primary); color: var(--primary-hover); }

/* Une écriture qui doit se lire comme un lien : archiver une transmission vaut
   sa modification, et un bouton encadré à côté d'un lien nu ferait croire à une
   différence qui n'existe pas. Reste un <button> dans un <form> — c'est une
   écriture, elle passe par un POST protégé. */
.link-button {
    padding: 0;
    color: var(--primary);
    background: none;
    border: 0;
    font-weight: 400;
    /* Exactement le style d'un <a> de cette feuille : souligné au survol
       seulement. Un soulignement permanent le distinguerait de « Modifier »,
       juste à côté, sans qu'aucune différence ne le justifie. */
    text-decoration: none;
}
.link-button:hover { background: none; color: var(--primary); text-decoration: underline; }

/* Discret, mais toujours un bouton : les gestes répétés de la feuille de
   route (Fait, Retirer, flèches, second passage) et des écrans de
   référence et de répartition, sur les panneaux blancs ou grisés. Texte
   bleu marine : contraste ≈ 10:1 (WCAG AA exige 4,5:1) — l'ancien bleu
   pâle #cfe3f7 tombait à 1,3:1 (lot 8, décision 64). */
.button--quiet {
    color: var(--primary);
    background: transparent;
    border-color: var(--border-strong);
    font-weight: 600;
}
.button--quiet:hover { background: var(--primary-hover); color: var(--on-primary); }

/* Compact : les gestes répétés d'une ligne de feuille de route (lot 9,
   plan A). Plus petit, jamais sous 28 px de haut — la cible de clic minimale
   de la spec (§11), au doigt comme à la souris. */
.button--compact {
    display: inline-flex;
    align-items: center;
    min-height: 1.75rem;
    padding: 0.125rem 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.2;
}

/* --- Recherche ----------------------------------------------------------- */

.search {
    margin-bottom: var(--gap);
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--gap-sm);
}
.search__field { flex: 0 1 28rem; }
.search label { margin-bottom: var(--gap-xs); }

/* --- Répertoire ---------------------------------------------------------- */

/* Cinq colonnes tabulaires avec en-têtes : une <table>, dans un conteneur qui
   défile seul sur un téléphone — jamais la page (même règle que le journal). */
.directory-scroll {
    overflow-x: auto;
    border-radius: var(--radius-lg);
    /* Le filet en ombre pleine : une bordure ajouterait 2 px à la hauteur. */
    box-shadow: 0 0 0 1px var(--border);
}

/* Dense (lot 9, plan A ; lot 14, tâche 9) : ≈ 24 px la ligne, contre 33 au
   départ et 26 avant le lot 14 — au moins 16 lignes visibles à 1366x768,
   comme les ~17 du legacy. */
.directory {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    font-size: 0.875rem;
}
.directory th,
.directory td {
    padding: 0.125rem var(--gap-sm);
    border-bottom: 1px solid var(--surface-sunken);
    text-align: left;
    white-space: nowrap;
}
.directory thead th {
    background: var(--surface-muted);
    border-bottom: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.directory tbody tr:hover { background: var(--surface-muted); }
.directory tbody tr:last-child td { border-bottom: 0; }
.directory strong { color: var(--primary); text-transform: uppercase; }

.letters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-xs);
    margin: var(--gap-sm) 0;
}
.letters a { padding: 0 var(--gap-xs); border-radius: var(--radius-pill); text-decoration: none; }
.letters a:hover { background: var(--accent-soft); }
.letters a.is-current { background: var(--primary); color: var(--on-primary); font-weight: 700; }

/* Une rangée d'outils, puis une rangée A–Z + total : le tableau remonte. */
.directory-toolbar .search { flex: 1 1 auto; align-items: center; margin: 0; }
.directory-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap-xs) var(--gap);
    margin-bottom: var(--gap-xs);
}
.directory-bar .letters { margin: 0; }
.directory-bar__total { margin: 0; }

.pager {
    display: flex;
    gap: var(--gap);
    align-items: baseline;
    margin-top: var(--gap);
}

/* --- Fiche patient ------------------------------------------------------- */

/* Étiquette et valeur sur la même ligne : une <dl> empilée doublerait la
   hauteur de la fiche pour la même information. */
.data-list {
    display: grid;
    grid-template-columns: minmax(7rem, 11rem) minmax(0, 1fr);
    gap: var(--gap-xs) var(--gap);
    margin: 0;
}
.data-list dt { color: var(--text-muted); }
.data-list dd { margin: 0; font-weight: 700; overflow-wrap: anywhere; }

/* Deux colonnes de panneaux ; les titres de section en --primary, comme la
   maquette (écran 3). */
.record-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--gap);
    align-items: start;
    margin-bottom: var(--gap);
}
.record-columns p { margin: 0; }
.panel > h2,
.record-columns h2,
.panel .toolbar h2 {
    font-size: 0.95rem;
    color: var(--primary);
}
.record-columns h2 { margin: 0 0 var(--gap-sm); }
.record-columns .panel h2:not(:first-child) { margin-top: var(--gap-lg); }
.panel .toolbar h2 { margin: 0; }
#passages { margin-bottom: var(--gap); }
/* Les passages : la date prend un rang large, sans toucher à la hauteur de la
   ligne ; la liste va au bord du panneau, qui porte déjà sa marge. */
#passages .round-entry__rank { min-width: 6rem; }
#passages .round-entries .round-entry { padding-inline: 0; }
.civility { color: var(--text-muted); font-weight: 400; }

/* --- Transmissions -------------------------------------------------------- */

/* La densité d'abord : une infirmière lit une pile de transmissions entre deux
   visites, et un interligne généreux la ferait défiler au lieu de lire. */
.care-notes {
    list-style: none;
    margin: 0;
    padding: 0;
}
.care-note {
    padding-block: var(--gap);
    border-top: 1px solid var(--border-soft);
}
.care-note:first-child { border-top: 0; }

/* Archivée : atténuée, jamais cachée. Aucune suppression physique n'existe
   dans la v2, et une note mise de côté doit rester lisible. */
.care-note--archived { color: var(--text-muted); }

.care-note__meta {
    margin: 0 0 var(--gap-xs);
    color: var(--text-muted);
    font-size: 0.8125rem;
}
.care-note__meta time { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }

/* Le texte de la transmission : c'est LUI qu'on vient lire, il porte donc la
   taille de base et non celle des métadonnées. */
.care-note__text { margin: 0; }

.care-note__actions {
    display: flex;
    align-items: baseline;
    gap: var(--gap);
    margin-top: var(--gap-xs);
    font-size: 0.8125rem;
}
.care-note__actions form { margin: 0; }

.care-notes__toggle { margin: var(--gap) 0 0; font-size: 0.8125rem; }

/* L'historique d'un patient, un mois à la fois (lot 8, §6.2). */
.care-notes__months { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap); margin: 0 0 var(--gap-sm); padding: var(--gap-sm) 0.1rem; border-bottom: 1px solid var(--border); font-size: 0.8125rem; }
.care-notes__months form { display: flex; align-items: center; gap: var(--gap-xs); margin: 0; }
.care-notes__month-title { margin: 0 0 var(--gap-sm); font-size: 1rem; color: var(--primary); }
.care-notes__day { margin: var(--gap) 0 var(--gap-xs); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }

/* La vue par date, un bloc par patient (lot 8, §6.3). */
.care-note-group + .care-note-group { margin-top: var(--gap-lg); }
.care-note-group__patient { display: flex; align-items: baseline; gap: var(--gap-xs); margin: 0 0 var(--gap-xs); padding-bottom: var(--gap-xs); border-bottom: 1px solid var(--border); }
.care-note-group__round { color: var(--text-muted); font-size: 0.8125rem; font-weight: normal; }

/* La saisie du soir (lot 8, §6.4) : la liste du jour à gauche, la saisie au centre. */
.care-note-entry { display: grid; grid-template-columns: minmax(min(14rem, 100%), 1fr) 2fr; gap: var(--gap); align-items: start; }
@media (max-width: 48rem) { .care-note-entry { grid-template-columns: 1fr; } }
/* Patient choisi : la liste est masquée (lot 9, plan C, décision 65), la saisie prend la largeur. */
.care-note-entry--patient { grid-template-columns: 1fr; }
.care-note-entry__round { display: flex; align-items: baseline; gap: var(--gap-xs); margin: var(--gap) 0 var(--gap-xs); font-size: 0.9375rem; font-weight: 700; }
.care-note-entry__patients { margin: 0; padding-left: 1.5rem; }
.care-note-entry__patients .is-noted a { color: var(--text-muted); }
/* La fiche au-dessus de la saisie (lot 9, plan C) : les cadres du legacy
   (transmissions.php l.429-549, infirm.css l.11-22) — intitulé en petit
   au-dessus de sa valeur, valeur sur fond clair, cadres côte à côte qui
   s'empilent sur un téléphone. */
.patient-context { margin: 0 0 var(--gap); }
.patient-context__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--gap-xs) var(--gap); margin: 0 0 var(--gap-xs); }
.patient-context__title { margin: 0; font-size: 0.95rem; color: var(--primary); }
.patient-context__edit { margin-left: auto; font-size: 0.875rem; }
.patient-context__box { margin: 0 0 var(--gap-sm); padding: var(--gap-sm) var(--gap); background: var(--surface-muted); border: 1px solid var(--border); border-radius: var(--radius); }
.patient-context__row { display: flex; flex-wrap: wrap; gap: var(--gap-xs) var(--gap-sm); margin: 0; }
.patient-context__row + .patient-context__row { margin-top: var(--gap-xs); }
.patient-context__field { flex: 1 1 9rem; min-width: 0; margin: 0; }
.patient-context__field--short { flex: 0 1 7rem; }
.patient-context__field--wide { flex: 2 1 14rem; }
.patient-context__field--notes { flex: 1 1 100%; }
.patient-context__field dt { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.patient-context__field dd { margin: 0.125rem 0 0; min-height: 1.25rem; font-weight: 700; overflow-wrap: anywhere; }
.patient-context__field--notes dd { font-weight: 400; max-height: 9.375rem; overflow-y: auto; }
.patient-context__groups { display: flex; flex-wrap: wrap; gap: var(--gap-sm) var(--gap); }
.patient-context__groups + .patient-context__group-title { margin-top: var(--gap-sm); }
.patient-context__group { flex: 2 1 20rem; min-width: 0; }
.patient-context__group--narrow { flex: 1 1 14rem; }
.patient-context__group-title { margin: 0 0 var(--gap-xs); font-size: 0.8rem; color: var(--primary); }
.patient-context__box > .patient-context__group-title { margin-top: var(--gap-sm); padding-top: var(--gap-sm); border-top: 1px dashed var(--border-strong); }
.patient-picker { margin-bottom: var(--gap); }

.badge {
    display: inline-block;
    padding: 0 var(--gap-sm);
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Statut inactif ou archivé sur la fiche patient (lot 6, §6.1) : les mêmes
   tokens que .alert, déjà utilisés pour signaler un état qui mérite l'oeil. */
.badge--alert { background: var(--danger-soft); color: var(--danger); }

.alert-text { color: var(--danger); }

/* Les filtres de la journée, sur une ligne tant que la place le permet. Les
   champs s'alignent par le BAS pour que les contrôles soient sur une ligne
   commune, quelle que soit la hauteur des étiquettes. */
.filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--gap) var(--gap-lg);
}
/* Le séparateur de .form-actions sépare un formulaire de ses boutons ; dans une
   barre de filtres, il tracerait un trait au milieu d'une ligne. */
.filters .form-actions {
    margin: 0;
    padding-top: 0;
    border-top: 0;
}
.filters .field { display: flex; flex-direction: column; }
/* La barre de filtres de la journée : un panneau bas, comme la maquette. */
.panel.filters { padding: var(--gap-sm) var(--gap); }

/* Le formulaire de transmission n'a pas de grille : sans cela ses champs se
   collent, .field portant margin-bottom:0 pour le compte de .field-grid. */
.care-note-fields .field + .field,
.care-note-fields .field-readonly + .field { margin-top: var(--gap); }

/* Le cadre « Transmissions » (écran 1 de la maquette) : filet clair, légende
   en --primary. Seul le fieldset DIRECT : le cadre gris imbriqué reste celui
   du legacy, ci-dessous. */
.care-note-fields > fieldset {
    margin: 0;
    border-radius: var(--radius-lg);
    background: transparent;
}
.care-note-fields > fieldset > legend {
    font-size: 0.95rem;
    font-weight: 700;
    text-transform: none;
    letter-spacing: normal;
    color: var(--primary);
}

/* Le cadre gris de « Transmission: », imbriqué dans le cadre « Transmissions »
   des deux écrans d'ajout, comme le legacy (transmissions.php l.712-715 :
   background-color:#A4A4A4;width:95%) ; spec lot 12, §6.2. La zone de texte
   garde le fond blanc de tous les champs (--surface). */
.care-note-fields__text-frame {
    width: 95%;
    background: var(--legacy-frame);
}

.subtitle { margin-top: 0; color: var(--text-muted); }

/* La date d'un passage, montrée sans être reprise : la modification ne porte
   que sur le texte. */
.field-readonly { margin: 0 0 var(--gap); color: var(--text-muted); }

/* --- Connexion ----------------------------------------------------------- */

.login {
    max-width: 24rem;
    margin: 3rem auto;
    padding: 1.75rem;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-raised);
}
.login h1 { margin-top: 0; font-size: 1.5rem; color: var(--primary); text-align: center; }
.login .field { margin-bottom: var(--gap); }
.login button { width: 100%; }

/* --- Pied de page -------------------------------------------------------- */

.app-footer {
    margin-top: 2rem;
    background: transparent;
}
.app-footer > p {
    /* Le legacy écrivait #CCC sur blanc. Ici le contraste passe AA
       (--text-muted sur --bg est dans rolePairsMeetTheAaContrast). */
    margin: 0;
    padding-block: var(--gap);
    color: var(--text-muted);
    font-size: 0.78rem;
}

/* --- Journal d'accès ------------------------------------------------------ */

/* Un texte d'aide sous un titre : il dit à quoi sert l'écran, pas ce qui va
   mal. D'où --text-muted et non --danger. */
.hint {
    margin-top: 0;
    color: var(--text-muted);
    font-size: 0.9375rem;
}

/* Ni erreur ni résultat : l'écran attend une question, ou n'a rien trouvé. */
.empty {
    padding: var(--gap-lg);
    background: var(--surface-sunken);
    border-radius: var(--radius);
    color: var(--text-muted);
}

/* La PREMIÈRE table de l'application, et elle est justifiée : quatre colonnes
   de données tabulaires avec en-têtes, qu'une liste rendrait illisibles.

   Le conteneur défilant n'est pas un détail : sur un téléphone, quatre
   colonnes débordent, et sans lui c'est la PAGE ENTIÈRE qui défilerait de
   travers. Le legacy n'avait pas de viewport ; on ne va pas le rejouer. */
.audit-scroll {
    overflow-x: auto;
    margin-top: var(--gap);
    border-radius: var(--radius-lg);
    box-shadow: 0 0 0 1px var(--border);
}

.audit {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    font-size: 0.9375rem;
}
.audit th,
.audit td {
    padding: var(--gap-sm) var(--gap);
    border-bottom: 1px solid var(--surface-sunken);
    text-align: left;
    vertical-align: top;
    white-space: nowrap;
}
.audit tbody tr:hover { background: var(--surface-muted); }
.audit thead th {
    background: var(--surface-muted);
    border-bottom: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.audit tbody tr:last-child td { border-bottom: 0; }

/* ---------------------------------------------------------------------------
 * LES TOURNÉES (lot 3) — la journée, tournée par tournée, côte à côte.
 *
 * C'est l'écran principal du lot, et sa forme n'est pas négociable (§8.2) :
 * c'est ainsi que le legacy la rend (`float:left` par tournée), et c'est ainsi
 * qu'une journée de cabinet se lit — on compare les tournées, on voit qui fait
 * quoi, on repère le patient qui manque.
 *
 * ⚠️ Ce que le legacy ne tient PAS, et qui est corrigé ici : ses colonnes
 * flottantes ont une largeur FIXE en pixels, et débordent sur un téléphone.
 * Ici elles s'empilent sous le seuil, et au-dessus c'est le CONTENEUR qui
 * défile — jamais la page. Même règle que la table du journal d'audit.
 * ------------------------------------------------------------------------- */
.rounds-day {
    display: grid;
    /* Empilées par défaut : mobile-first, la tournée est le moment le plus
       contraint. */
    grid-template-columns: 1fr;
    gap: var(--gap);
    margin-top: var(--gap);
}

@media (min-width: 60rem) {
    .rounds-day {
        /* Au-delà du seuil, autant de colonnes que de tournées, toutes de
           largeur égale, et le conteneur défile si elles ne tiennent pas.
           `minmax(18rem, 1fr)` plutôt qu'une largeur fixe : trois tournées
           occupent l'écran, huit défilent sans jamais se tasser. */
        grid-auto-flow: column;
        grid-auto-columns: minmax(18rem, 1fr);
        grid-template-columns: none;
        overflow-x: auto;
        /* Une colonne coupée en deux au bord de l'écran ne se lit pas : ce
           calage arrête le défilement sur une colonne entière. */
        scroll-snap-type: x proximity;
    }
    .round-column { scroll-snap-align: start; }
}

.round-column {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
/* Le cadre n'a plus de marge intérieure : l'en-tête, la liste et le pied
   vont jusqu'au bord. Les messages seuls (« Aucun patient… », « Pas de feuille
   ce jour-là ») gardent la leur. */
.round-column > p.muted { margin: 0; padding: var(--gap-sm) var(--gap); }

/* La couleur de la tournée, reprise du legacy, sur le liseré du haut : elle
   distingue les colonnes d'un coup d'œil, et c'est sa seule raison d'être.
   La bordure par défaut sert aux tournées sans couleur — 11 sur 14. */
.round-column__header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 var(--gap);
    padding: var(--gap-sm) var(--gap);
    border-top: 5px solid var(--primary);
    border-top-color: var(--round-color, var(--primary));
    border-bottom: 1px solid var(--border-soft);
    background: color-mix(in srgb, var(--round-color, var(--primary)) 10%, var(--surface));
}
/* Le texte de l'en-tête reste en --text : une couleur de tournée claire doit
   rester lisible, elle ne teinte que le trait et le fond. */
.round-column__name { margin: 0; font-size: 1rem; color: var(--text); }
.round-column__nurse,
.round-column__count,
.round-column__archived {
    margin: 0;
    font-size: 0.875rem;
    color: var(--text-muted);
}
/* Le compte et « archivées » en --text : --text-muted sur le fond teinté de
   l'en-tête tombait sous 4,5:1 (revue finale). */
.round-column__count,
.round-column__archived {
    color: var(--text);
}
/* « Tournée faite par » en italique, le nom en gras bleu #174867, toujours
   italique : le legacy posait toute la ligne dans un div en italique
   (liste_feuille_route.php l.216-218). */
.round-column__nurse {
    font-style: italic;
    font-size: inherit;
    color: var(--text);
    line-height: 1.5;
}
.round-column__nurse strong { color: var(--legacy-nurse); padding: 3px; }

/* Archivée : présente parce qu'elle porte des feuilles, mais visiblement hors
   service. Les onze fabriquées par la reprise sont dans ce cas. */
.round-column--archived { opacity: 0.75; }

.round-column__observation {
    margin: 0;
    padding: var(--gap-sm) var(--gap);
    background: var(--info-soft);
    border-bottom: 1px solid var(--border-soft);
    font-size: 0.9375rem;
    /* Dans le même div italique que « Tournée faite par » au legacy (l.216-221). */
    font-style: italic;
}

.round-entries,
.round-sheet-entries {
    margin: 0;
    padding: 0;
    list-style: none;
}

.round-entry {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-xs) var(--gap-sm);
    padding: var(--gap-xs) 0;
    border-bottom: 1px solid var(--border-soft);
}
.round-entry:last-child { border-bottom: 0; }
/* Dans la journée, la liste va jusqu'au bord de la colonne : c'est la ligne
   qui porte la marge latérale. */
.round-entries .round-entry { padding: var(--gap-xs) var(--gap); }
.round-entries .round-entry:hover { background: var(--surface-muted); }

/* Le rang du passage, en pastille. Il compte : l'ORDRE est l'information de
   la feuille de route, pas un confort d'affichage. Vert quand c'est fait. */
.round-entry__rank {
    flex: none;
    display: inline-grid;
    place-items: center;
    min-width: 1.5rem;
    height: 1.25rem;
    padding: 0 0.3125rem;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    font-size: 0.75rem;
    font-weight: 700;
}
.round-entry.is-done .round-entry__rank { background: var(--success-soft); color: var(--success); }

.round-entry__patient { font-weight: 600; }

/* Prise de sang à jeun (lot 8, §13.5) : le nom en rouge ET la mention, pour ne
   pas reposer sur la seule couleur. */
.round-entry__patient--fasting { color: var(--danger); }
.round-entry__fasting { font-weight: 400; font-size: 0.875rem; }

/* Fait. Le legacy l'encodait par un signe négatif dans un CSV ; ici c'est une
   date, et à l'écran une marque discrète — 69 soins pointés en quatorze ans,
   la fonction existe et ne domine pas. */
.round-entry.is-done .round-entry__patient { text-decoration: line-through; }
.round-entry__done,
.round-entry__noted {
    padding: 0 var(--gap-sm);
    border-radius: var(--radius-pill);
    background: var(--success-soft);
    color: var(--success);
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Les notes par patient sur la feuille (lot 8, §13.5) : en italique sous le
   nom, chacune avec ses deux gestes ; « + Note » quand il n'y en a pas. */
.round-entry__notes {
    flex-basis: 100%;
    margin-left: 2rem;
    font-size: 0.9375rem;
}
.round-note { margin: var(--gap-xs) 0 0; }
.round-note__text { font-style: italic; }
/* Une note est une étiquette --accent-soft : sur la journée c'est le <p>
   (heure + texte), sur la préparation et les orphelines c'est le texte seul. */
.round-entry__body .round-note,
.round-note__text {
    padding: 0 var(--gap-sm);
    border-radius: var(--radius);
    background: var(--accent-soft);
    color: var(--text);
}
.round-entry__body .round-note { display: inline-block; }
.round-note__actions {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--gap-sm);
    margin-left: var(--gap-sm);
    font-size: 0.8125rem;
}
.round-entry__add-note { font-size: 0.8125rem; }

/* Confirmer sans script : <details> déplie le vrai bouton (CSP). */
.confirm { display: inline-block; }
.confirm summary {
    cursor: pointer;
    color: var(--danger);
    font-size: 0.8125rem;
}
.round-sheet__orphans summary { cursor: pointer; }
.round-sheet__orphan-list { margin: var(--gap) 0 0; padding-left: var(--gap-lg); }

/* L'aide sous un champ. */
.field__hint { margin: var(--gap-xs) 0 0; font-size: 0.8125rem; }

/* Les gestes d'une colonne de la journée (lot 9, plan B) : une rangée qui
   passe à la ligne ; « Dupliquer » se déplie dessous, sur toute la largeur.
   Le « Planifier » d'une colonne vide porte la même classe. */
.round-column__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--gap-xs);
    margin: 0;
    padding: var(--gap-sm) var(--gap);
    border-top: 1px solid var(--border);
    background: var(--surface-muted);
}
.round-column__actions .button,
.round-column__actions button { padding-block: 0.25rem; font-size: 0.8125rem; }
.round-column__duplicate > summary { list-style: none; }
.round-column__duplicate > summary::-webkit-details-marker { display: none; }
.round-column__duplicate[open] { flex-basis: 100%; }
.round-column__duplicate[open] > summary { margin-bottom: var(--gap-sm); }

/* L'impression de la journee (lot 9, plan B2), comme le legacy : un seul
   formulaire, une tournee cochee ; une rangee qui passe a la ligne. */
.day-print {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-sm) var(--gap-lg);
    padding: var(--gap-sm) var(--gap);
    background: var(--surface-muted);
}
.day-print label { font-weight: 400; }
.day-print__title { flex-basis: 100%; margin: 0; }
.day-print__rounds {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-sm);
    margin: 0;
    padding: 0;
    border: 0;
    /* Pas la plaque des fieldsets : sans marge, elle collait au texte. */
    background: transparent;
}
/* « Tournees: » en gras, comme le legacy. */
.day-print__rounds > legend { float: left; padding: 0; font-weight: bold; }

/* Les notes d'un patient sur la journée et son « + note » (lot 9, plan B).
   Le bloc vide (aucune note) ne prend aucune place : sinon une ligne de flex
   vide, et un écart de plus, sous chaque passage. */
.round-entry__day-notes { flex-basis: 100%; }
.round-entry__day-notes:empty { display: none; }
/* Le bloc remplaçable d'un passage (lot 9, plan B2) : un enveloppement pour
   round-day.js, sans effet de mise en page — ses enfants restent des
   éléments de la ligne flexible. */
.round-entry__body { display: contents; }
/* Coordonnées et « fait » d'un passage, pour le TÉLÉPHONE seulement (lot 16a) :
   caché au-dessus de 45rem, la journée large reste ce qu'elle était. */
.round-entry__mobile { display: none; }
@media (max-width: 45rem) {
    .round-entry__mobile {
        display: flex;
        flex-basis: 100%;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--gap-xs) var(--gap);
        font-size: 0.9375rem;
    }
    .round-entry__mobile .inline-form { margin-left: auto; }
}
/* Vue condensée du téléphone (lot 21, §2) : le bouton de bascule (caché sans
   script par l'attribut hidden, et au-dessus de 45rem par .phone-only) et le
   repère « * » d'une note de feuille, visible seulement en condensé. Condensé :
   restent le rang, le nom, « (à jeun) », « * », « fait » et « transmis »
   (barré compris) ; coordonnées, « fait » à pousser, notes et « + note » se
   masquent. Au-dessus de 45rem rien ne change. */
.round-entry__note-flag { display: none; }
.round-view-toggle { margin-bottom: var(--gap); }
/* `button { display: inline-block }` l'emporte sur le [hidden] du navigateur :
   sans cette règle le bouton s'afficherait sans script. */
.round-view-toggle[hidden] { display: none; }
@media (max-width: 45rem) {
    /* Les coordonnées portent l'ancre #passage-{id} : une boîte sans taille ni
       focus la garde atteignable (display: none la ferait ne plus défiler). */
    .rounds-day--condensed .round-entry__mobile {
        display: block;
        flex-basis: 0;
        width: 0;
        height: 0;
        overflow: hidden;
        visibility: hidden;
    }
    .rounds-day--condensed .round-entry__day-notes,
    .rounds-day--condensed .round-entry__day-note { display: none; }
    .rounds-day--condensed .round-entry__note-flag {
        display: inline;
        font-weight: 700;
        color: var(--text-muted);
    }
}
/* Modifier / Supprimer une note sur la journée (lot 9, plan B2), comme le
   legacy : sous la note, dépliés sur place. */
.round-entry__notes .round-note__actions { margin-left: 0; }
.round-entry__notes .round-entry__day-note { flex-basis: auto; margin-left: 0; }
.round-entry__notes .round-entry__day-note[open] { flex-basis: 100%; }
.round-entry__day-note {
    flex-basis: 100%;
    margin-left: 2rem;
    font-size: 0.8125rem;
}
.round-entry__day-note > summary { cursor: pointer; color: var(--text-muted); }
/* « + note » d'un passage sans note : visible mais atténué, au bout de la
   ligne du nom au lieu d'une ligne à lui seul (une ligne de la journée passe
   d'environ 60 px à une ligne de texte). Déplié, il reprend toute la largeur
   pour son formulaire. */
.round-entry__body > .round-entry__day-note { flex-basis: auto; margin-left: auto; }
.round-entry__body > .round-entry__day-note[open] { flex-basis: 100%; margin-left: 2rem; }
.day-note-form { margin-top: var(--gap-xs); }
.day-note-form .form-actions { margin-top: var(--gap-xs); }

/* Les commandes de la préparation. Elles vivent sur la même ligne que le
   passage : l'écran de préparation est un écran de PC (§8.0), et la densité
   y est la raison d'être — voir trois tournées et 81 patients d'un coup est ce
   qui rend la préparation rapide. */
.round-entry__controls {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-xs);
    margin-left: auto;
}
.inline-form { display: inline; }

/* Le rang en liste déroulante (lot 22, §3) : au téléphone seulement
   (.phone-only le masque au-dessus de 45rem). Le select et « Placer » restent
   sur une ligne ; le select garde une cible tactile confortable. */
.round-entry__rank-form {
    display: inline-flex;
    align-items: center;
    gap: var(--gap-xs);
}
.round-entry__rank-select { min-width: 3.5rem; min-height: 2.75rem; }

/* Préparation sans rechargement (lot 22, §2 et §4) : round-sheet-phone.js
   cache « Placer » et « Chercher » au téléphone (`button { display:
   inline-block }` l'emporte sinon sur [hidden]). La zone de statut est vide et
   sans marge tant qu'aucun geste n'a eu lieu : le PC ne la voit pas ; remplie,
   elle reste en haut de l'écran pendant qu'on fait défiler les listes. */
.round-entry__place[hidden],
[data-compose-search][hidden] { display: none; }
.compose__status { margin: 0; }
@media (max-width: 45rem) {
    .compose__status:not(:empty) {
        position: sticky;
        top: 0;
        z-index: 1;
        margin: 0 0 var(--gap-sm);
        padding: var(--gap-xs) var(--gap-sm);
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
    }
}

/* --- Préparation : l'en-tête compact (lot 9, plan A, spec §6.1) ---------- */

/* Une ligne : Retour · Imprimer · Répartir · … · Plus. Sous le seuil, elle
   passe à la ligne plutôt que de faire défiler la page de travers. */
.sheet-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-sm);
    margin-bottom: var(--gap-sm);
}
.sheet-bar__print { display: flex; align-items: center; gap: var(--gap-sm); }
.sheet-bar__print label {
    display: inline-flex;
    align-items: center;
    gap: var(--gap-xs);
    margin: 0;
    font-weight: 400;
    color: var(--text);
}

/* « Plus » : un <details> dont le panneau se déroule PAR-DESSUS la page,
   ancré à droite. Sa largeur est bornée par la fenêtre : jamais de
   défilement horizontal, même au téléphone. « Plus » est poussé au bout de
   sa ligne : si la barre passe à la ligne, le panneau ne sort pas par la
   gauche (revue finale du plan A). */
.sheet-more { position: relative; margin-left: auto; }
.sheet-more > summary { list-style: none; }
.sheet-more > summary::-webkit-details-marker { display: none; }
.sheet-more__panel {
    position: absolute;
    right: 0;
    top: calc(100% + var(--gap-xs));
    z-index: 5;
    display: grid;
    gap: var(--gap);
    width: min(30rem, calc(100vw - 3rem));
    padding: var(--gap);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-raised);
}
.sheet-more__panel .field__hint { margin: 0; }

/* Sous le titre : l'infirmière, puis l'observation, sur une ligne. */
.sheet-info {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--gap-xs) var(--gap-lg);
    margin-bottom: var(--gap-sm);
}
.sheet-info__nurse { margin: 0; }
.sheet-observation { flex: 1 1 20rem; min-width: 0; }
.sheet-observation > summary { cursor: pointer; color: var(--primary); }
.sheet-observation__form {
    display: flex;
    align-items: flex-start;
    gap: var(--gap-sm);
    margin-top: var(--gap-xs);
}
.sheet-observation__form textarea { flex: 1 1 auto; }

/* Le glisser-déposer (§8.3). Ces trois règles ne s'appliquent QUE si
   rounds.js a chargé : c'est lui qui pose `is-draggable`, pas le gabarit.
   Un curseur de préhension rendu par le serveur promettrait un geste que
   personne n'honorerait. */
.round-entry.is-draggable { cursor: grab; }
.round-entry.is-dragging {
    opacity: 0.5;
    cursor: grabbing;
}
/* Le survol pendant le glissement réorganise la liste sous le doigt : sans
   transition, les lignes sautent et on perd de vue celle qu'on déplace. */
@media (prefers-reduced-motion: no-preference) {
    .round-sheet-entries .round-entry { transition: transform 0.12s ease; }
}

/* ---------------------------------------------------------------------------
 * LES DEUX COLONNES DE LA COMPOSITION (§8.3).
 *
 * « Les patients disponibles à gauche, la tournée à droite » — la forme du
 * legacy, et le seul agencement où le glisser-déposer a un sens : il lui faut
 * une source et une cible.
 *
 * C'est un écran de PC (§8.0) : la préparation se fait à la maison, au clavier
 * et à la souris. Sous le seuil, les deux colonnes s'empilent — on ne prépare
 * pas une tournée au téléphone, mais on doit pouvoir la relire.
 * ------------------------------------------------------------------------- */
.compose {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--gap);
}

@media (min-width: 60rem) {
    .compose { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
}

.compose__column { display: flex; flex-direction: column; }
/* Le <details> du téléphone (lot 21) est l'unique enfant de la colonne : il en
   reprend la mise en colonne (sans gap, comme .compose__column) pour que
   l'espacement PC reste celui d'avant. */
.compose__candidates-phone { display: flex; flex-direction: column; }
.compose__count { margin: 0 0 var(--gap-sm); font-size: 0.8125rem; }

/* La colonne défile DANS son cadre : 200 patients à gauche ne doivent pas
   faire défiler la feuille de droite hors de l'écran. */
.compose__list {
    max-height: 60vh;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* ⚠️ LA COLONNE DE DROITE EST UNE CIBLE DE DÉPÔT, et sa taille ne doit PAS
   dépendre de ce qu'on y a déjà mis — sinon elle est au plus petit quand on en
   a le plus besoin, au premier patient.

   Signalé par le porteur du projet : on attrapait un patient au bas d'une
   colonne de 200 à gauche, et il fallait REMONTER pour trouver où le lâcher.
   Elle occupe désormais la hauteur de la colonne, quel que soit son contenu. */
.compose__list--sheet {
    min-height: 60vh;
    flex: 1;
}

/* Une feuille vide se voit comme une zone qui attend quelque chose. */
.compose__list--empty {
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
}

/* Le bouton d'ajout occupe la ligne : c'est lui la surface de clic, et le
   `<li>` autour est la surface de préhension. Coins de ligne : des pastilles
   empilées se lisaient comme un mur de capsules. */
.compose__add {
    flex: 1;
    text-align: left;
    border-radius: var(--radius);
}

/* La feuille pendant qu'on lui apporte un patient. Elle ne réorganise PAS ses
   rangs sous le doigt dans ce cas : le patient venu de gauche est ajouté à la
   FIN, et le montrer ailleurs promettrait un rang que le serveur ne donnera
   pas. */
.compose__list.is-receiving {
    outline: 2px dashed var(--accent-strong);
    outline-offset: 2px;
}

/* --- Préparation : la densité (lot 9, plan A, spec §6.1) ----------------
   La feuille prend deux parts contre une aux candidats : une ligne compacte
   y tient avec un nom long. Référence et répartition, qui partagent
   .compose et .round-entry, ne changent pas : tout passe par un modificateur. */
@media (min-width: 60rem) {
    .compose--sheet { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
}
.compose--sheet .panel { padding: var(--gap-sm) var(--gap); }
.compose--sheet h2 { margin-bottom: var(--gap-xs); }

/* Un candidat : un bouton compact, sans marge autour (~29 px la ligne). */
.round-entry--candidate { padding: 0 0 0.0625rem; border-bottom: 0; }

/* Un passage : UNE ligne — rang, nom, note abrégée, gestes à droite. Une
   note ne rétrécit pas sous 10rem : ses deux gestes y tiennent toujours, et
   une seconde note (doublon repris) passe DESSOUS au lieu de chevaucher. Sans
   note, aucun bloc : le nom garde la place. S'il n'y a pas la place, les
   gestes passent dessous et à la ligne : la ligne grandit, rien ne défile de
   travers, ni la page ni la liste (revue finale du plan A). */
.round-entry--compact {
    align-items: center;
    gap: var(--gap-xs) var(--gap-sm);
    padding: 1px 0;
}
.round-entry--compact .round-entry__notes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-xs) var(--gap-sm);
    flex: 1 1 12rem;
    min-width: 10rem;
    margin-left: 0;
    font-size: 0.8125rem;
}
.round-entry--compact .round-note {
    display: flex;
    align-items: baseline;
    gap: var(--gap-xs);
    flex: 1 1 12rem;
    min-width: 10rem;
    margin: 0;
}
/* Le début de la note, sur une ligne ; le title la porte entière. Les <br>
   de nl2br sont tus : le saut de ligne qui les suit devient un espace. */
.round-entry--compact .round-note__text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.round-entry--compact .round-note__text br { display: none; }
.round-entry--compact .round-note__actions { flex: 0 1 auto; margin-left: 0; }
.round-entry--compact .round-entry__controls { flex: 0 1 auto; max-width: 100%; align-items: center; }

.calendar {
    padding: var(--gap-sm);
    background: var(--surface);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    font-size: 0.8125rem;
}
/* Dans le cartouche du widget (lot 5, vague de correction finale), le
   calendrier touche directement les bords du .frame : sa propre bordure
   double celle du cartouche. Le cartouche suffit. */
.sidebar .calendar { border: 0; }
.calendar__nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--gap-xs);
}
.calendar__month { font-weight: 600; color: var(--primary); }
.calendar__arrow {
    padding: 0 var(--gap-sm);
    font-size: 1.125rem;
    line-height: 1;
    text-decoration: none;
}
.calendar__grid {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    text-align: center;
}
.calendar__grid th {
    padding-block: var(--gap-xs);
    font-weight: 600;
    color: var(--text-muted);
}
.calendar__day, .calendar__empty { padding-block: var(--gap-xs); }
/* Les jours porteurs d'une note : en gras et cliquables. Les autres sont des
   liens gris eux aussi — comme le legacy, où `affiche_agenda_notes.php` rend
   un `<a>` dans les deux cas : on ouvre un jour vide pour y ajouter quelque
   chose. */
.calendar__day--marked a { font-weight: 700; }
/* Un jour vide : un lien quand même, mais gris et sans gras. */
.calendar__quiet { color: var(--text-muted); text-decoration: none; }
/* Le legacy posait `cursor: pointer` sur chaque jour ; le soulignement au
   survol en est l'équivalent v2. */
.calendar__quiet:hover, .calendar__quiet:focus-visible { text-decoration: underline; }
/* Le jour choisi : plein marine, texte clair (le lien et son <strong> héritent). */
.calendar__day.is-selected {
    background: var(--primary);
    border-radius: var(--radius);
}
.calendar__day.is-selected a { color: var(--on-primary); }
/* Le jour courant : jaune à contour, comme le `ui-state-highlight` du legacy ; il
   l'emporte sur le jour choisi (le gabarit ne pose jamais les deux classes).
   Le contour est un box-shadow inset, pas une bordure : aucune autre case n'en a,
   la ligne et la colonne ne bougent pas d'un pixel. */
.calendar__day.is-today {
    background: var(--calendar-today-bg);
    box-shadow: inset 0 0 0 1px var(--calendar-today-border);
    border-radius: var(--radius);
}
.calendar__day.is-today a { color: var(--text); }

/* Contraste forcé : les fonds sont écrasés par le système, l'onglet actif et
   le jour choisi ne se distinguent plus que par un contour. */
@media (forced-colors: active) {
    .tabs__tab.is-active, .calendar__day.is-selected {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
    }
    /* Le jour courant : contour en tirets, distinct du plein du jour choisi. */
    .calendar__day.is-today {
        outline: 2px dashed CanvasText;
        outline-offset: -2px;
    }
}

/* Le filtre : « Toutes les notes » puis une radio par tournée, sur une ligne. */
.agenda__rounds,
/* Tournées et infirmières chacune sur sa ligne : sur une seule, avec la
   journée et les boutons, la barre ne se lisait plus. */
.filters__choices {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-sm) var(--gap);
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
}
.agenda__rounds legend,
.filters__choices legend { padding: 0; margin-bottom: var(--gap-xs); }
.agenda__rounds label,
.filters__choices label {
    display: inline-flex;
    align-items: center;
    gap: var(--gap-xs);
    margin: 0;
    font-weight: 400;
    color: var(--text);
}

/* Les notes du jour : la densité d'abord, comme les transmissions. */
.agenda-notes { list-style: none; margin: 0; padding: 0; }
.agenda-note {
    padding: var(--gap) var(--gap-lg);
    border-top: 1px solid var(--border-soft);
}
.agenda-note:first-child { border-top: 0; }
.agenda-note__round { margin: 0 0 var(--gap-xs); font-size: 0.8125rem; }
/* La couleur de la tournée (reprise au lot 3) en liseré ; une tournée archivée
   la garde. Sans couleur en base, le liseré est neutre. */
.agenda-note__round-name {
    display: inline-block;
    padding-left: var(--gap-sm);
    border-left: 0.3125rem solid var(--border);
    border-left-color: var(--round-color, var(--border));
    font-weight: 600;
    color: var(--primary);
}
.agenda-note__text { margin: 0; }
.agenda-note__meta {
    margin: var(--gap-xs) 0 0;
    color: var(--text-muted);
    font-size: 0.8125rem;
}
/* Les commandes par note (lot 4, phase 4) : en ligne, discrètes, sans script. */
.agenda-note__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-top: 0.5rem; }
.agenda-note__actions form { display: inline-flex; gap: 0.5rem; align-items: center; margin: 0; }
.agenda-note__move select { max-width: 12rem; }
/* Une note archivée, vue par ?archived=1 (décision 14) : grisée, lisible. */
.agenda-note.is-archived { opacity: 0.6; }
.agenda-note.is-archived .agenda-note__text { text-decoration: line-through; }

.agenda-form { margin-top: var(--gap-lg); }

/* La semaine (lot 4, phase 4) : sept colonnes, la barre de 5 px du legacy. */
.week-nav { display: flex; flex-wrap: wrap; gap: var(--gap-sm); margin-bottom: var(--gap); }
.week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--gap-sm); }
@media (max-width: 45rem) { .week { grid-template-columns: 1fr; } }
.week__day { min-width: 0; padding: var(--gap-xs); border-radius: var(--radius); }
.week__day.is-today { background: var(--today-bg); }
.week__day-title { font-size: 0.95rem; text-align: center; margin: 0 0 var(--gap-sm); color: var(--primary); }
/* La barre gauche porte la couleur de la tournée (--round-color) : le repère
   du legacy, gardé tel quel. */
.week-note { display: block; border: 1px solid var(--border-soft); border-left: 5px solid var(--round-default); border-left-color: var(--round-color, var(--round-default)); border-radius: var(--radius); padding: 0.25rem 0.4rem; margin-bottom: 0.4rem; font-size: 0.85rem; color: inherit; text-decoration: none; background: var(--surface-muted); word-break: break-word; }
.week-note:hover, .week-note:focus-visible { background: var(--surface-sunken); }
.round-dot { display: inline-block; width: 0.8em; height: 0.8em; background: var(--round-color, var(--round-dot-default)); border-radius: 50%; margin-right: 0.4em; vertical-align: baseline; }

/* --- Écran tactile (lot 16a) : cibles de 44 px au doigt ------------------
   À la souris rien ne change (les boutons compacts gardent 28 px). Placé en
   fin de feuille pour l'emporter sur .button--compact. Les liens en ligne
   deviennent flex pour que min-height les agrandisse vraiment, texte centré. */
@media (pointer: coarse) {
    button, .button, .button--compact, .tabs__tab {
        min-height: 2.75rem;
    }
    /* Un <button> centre son texte de lui-même, pas un <a class="button"> :
       en flex, les deux le centrent (largeur inchangée). */
    .button {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    .tabs__tab {
        display: inline-flex;
        align-items: center;
    }
    /* Téléphone, courriel et plan de la fiche : liens d'action au doigt. */
    .contact-link {
        display: inline-flex;
        align-items: center;
        min-height: 2.75rem;
    }
    .submenu__item a {
        display: flex;
        align-items: center;
        min-height: 2.75rem;
    }
    /* Le retour nommé de l'en-tête (lot 16a-bis). */
    .phone-back {
        display: inline-flex;
        align-items: center;
        min-height: 2.75rem;
    }
    /* La barre de jour (lot 16a-bis) : flèches, « Aujourd'hui » et champ date. */
    .day-bar__step, .day-bar__today, .day-bar__field {
        min-height: 2.75rem;
    }
    /* Les résumés des blocs repliés (lot 16a-bis) : « Filtres », « Infos
       patient », « + Ajouter une note », « ⋯ ». */
    details[data-phone-collapsed] > summary {
        min-height: 2.75rem;
    }
    .calendar__day a {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 2.75rem;
    }
    /* Les liens de liste (lot 16a-bis, §9.5) : passages, patients d'une
       transmission, répertoire, lettres, notes du jour, semaine, archivées.
       Flex pour que min-height agrandisse vraiment un lien en ligne ; l'écart
       sépare le nom en gras du prénom (le blanc entre eux n'est plus rendu). */
    .care-note-entry__patients a,
    .letters a,
    .week__day-title a,
    .care-notes__toggle a,
    .brand,
    .agenda-archived-link,
    .patient-context__edit,
    .care-note-patient-link {
        display: inline-flex;
        align-items: center;
        min-height: 2.75rem;
    }
    /* Le lien seul (pas les <span> du même nom) ; l'écart rend le blanc
       perdu entre le nom et « (à jeun) », que le flex ne rend plus. */
    a.round-entry__patient {
        display: inline-flex;
        align-items: center;
        gap: 0.25em;
        min-height: 2.75rem;
    }
    .letters a {
        justify-content: center;
        min-width: 2.75rem;
    }
    .directory a {
        display: inline-flex;
        align-items: center;
        gap: 0.25em;
        min-height: 2.75rem;
    }
    /* Le résumé « + note pour NOM Prénom » : un summary est en list-item, et
       min-height laisse alors texte et triangle natifs en haut de la cible.
       On le passe en flex centré, sans marqueur natif ; la flèche est dessinée
       en ::before avec les glyphes des replis du téléphone (« ▸ » fermé,
       « ▾ » ouvert), avant le texte comme avant. */
    .round-entry__day-note > summary {
        display: flex;
        align-items: center;
        list-style: none;
        min-height: 2.75rem;
    }
    .round-entry__day-note > summary::-webkit-details-marker { display: none; }
    .round-entry__day-note > summary::before {
        content: "▸";
        margin-right: 0.4em;
    }
    .round-entry__day-note[open] > summary::before { content: "▾"; }
    .week-note {
        min-height: 2.75rem;
    }
}

/* --- Bascule de sous-menu et retour nommé (lot 16a-bis, spec §9.2) ---------
   La bascule n'existe que sur téléphone, pour Transmissions et Notes : des
   entrées de largeur égale, sans défilement de côté. Le retour nommé remplace
   la marque dans l'en-tête (.phone-only le réserve au téléphone) ; le lien
   « ← Retour » de la page, devenu redondant, se masque. */
.segments { display: none; }
.phone-back {
    color: var(--header-text);
    font-size: 1.125rem;
    font-weight: 600;
    white-space: nowrap;
}
.phone-back:hover { text-decoration: none; }

@media (max-width: 45rem) {
    .segments {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 1fr;
        background: var(--surface);
        border-bottom: 1px solid var(--border);
    }
    .segments__item {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 2.75rem;
        padding-inline: var(--gap-sm);
        color: var(--text-muted);
        text-align: center;
        border-bottom: 3px solid transparent;
    }
    .segments__item:hover { text-decoration: none; }
    .segments__item[aria-current="page"] {
        color: var(--primary);
        font-weight: 600;
        border-bottom-color: var(--primary);
    }
    /* Seulement à côté du retour de l'en-tête : une page sans phone_back
       (par ex. la vérification d'une fusion) garde son lien. */
    body:has(.phone-back) .backlink { display: none; }
}

/* --- Barre de jour (lot 16a-bis, spec §9.3) ---------------------------------
   Une ligne : ‹ date › Aujourd'hui. Le nav porte .phone-only : au-dessus de
   45rem il n'existe pas, le PC garde son champ date et ses boutons. */
.day-bar {
    display: grid;
    grid-template-columns: 2.75rem 1fr 2.75rem auto;
    align-items: center;
    gap: var(--gap-sm);
    margin-bottom: var(--gap);
}
.day-bar__step {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    font-size: 1.5rem;
    line-height: 1;
}
.day-bar__step:hover { text-decoration: none; }
.day-bar__date { margin: 0; min-width: 0; text-align: center; font-weight: 600; }
.day-bar__field { width: 100%; min-height: 2.75rem; }
.day-bar__today {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
    padding-inline: var(--gap-sm);
    white-space: nowrap;
}

/* --- Une tournée à la fois sur la journée (lot 16a-bis, spec §9.4) ----------
   Le sélecteur n'existe que sur téléphone ; sous 45rem, dès qu'une colonne est
   retenue (.is-phone-selected), les autres se masquent. Depuis le lot 22 (§1),
   une colonne est toujours retenue dès qu'il y a une pastille (la première
   qui a des passages, sinon la première ; RoundSheetDayAction::
   selectedRoundOf), même un jour sans passage. La couleur de la tournée
   (--round-color, posée par .round-color-N) ne teinte que le trait et le fond :
   le texte reste en --text. */
.round-picker { display: none; }

@media (max-width: 45rem) {
    .round-picker {
        display: flex;
        flex-wrap: wrap;
        gap: var(--gap-sm);
        margin-bottom: var(--gap);
    }
    .round-picker__pill {
        display: inline-flex;
        align-items: center;
        gap: var(--gap-xs);
        min-height: 2.75rem;
        padding-inline: var(--gap);
        color: var(--text);
        border: 1px solid var(--border);
        border-bottom: 4px solid var(--round-color, var(--primary));
        border-radius: var(--radius);
        background: color-mix(in srgb, var(--round-color, var(--primary)) 10%, var(--surface));
    }
    .round-picker__pill:hover { text-decoration: none; }
    .round-picker__pill.is-current { font-weight: 600; border-color: var(--text); border-bottom-color: var(--round-color, var(--primary)); }
    .round-picker__count { color: var(--text-muted); }
    .rounds-day:has(.is-phone-selected) .round-column:not(.is-phone-selected) { display: none; }
}

/* --- Blocs repliés sur téléphone (lot 16a-bis, spec §9.5) -------------------
   Un <details open data-phone-collapsed> dont le <summary> est .phone-only :
   sur PC le résumé n'existe pas et le bloc reste ouvert, comme avant. Le
   script phone-collapse.js retire `open` sous 45rem, au chargement. Les règles
   d'affichage du résumé sont toutes sous 45rem : hors de là, .phone-only le
   masque. Les groupes de filtres gardent, dans le bloc, l'écart qu'ils avaient
   dans le formulaire. */
.filters .filters__fold { flex-basis: 100%; }
.filters__fold > .filters__choices + .filters__choices { margin-top: var(--gap); }

@media (max-width: 45rem) {
    details[data-phone-collapsed] > summary {
        display: flex;
        align-items: center;
        min-height: 2.75rem;
        padding-inline: var(--gap);
        color: var(--primary);
        font-weight: 600;
        cursor: pointer;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        background: var(--surface);
    }
    details[data-phone-collapsed] > summary::after {
        content: "▾";
        margin-left: auto;
    }
    details[data-phone-collapsed]:not([open]) > summary::after { content: "▸"; }
    details[data-phone-collapsed][open] > summary { margin-bottom: var(--gap-sm); }
    /* Les actions d'une note : un « ⋯ » carré, à droite, sans flèche. */
    details.agenda-note__more > summary {
        justify-content: center;
        width: 2.75rem;
        margin-left: auto;
        padding-inline: 0;
    }
    details.agenda-note__more > summary::after,
    details.agenda-note__more:not([open]) > summary::after { content: none; }

    /* Ajouter une transmission : le champ et le bouton passent avant les
       infos du patient (ordre CSS, le HTML garde la fiche d'abord). */
    .care-note-entry--patient > .care-note-entry__form {
        display: flex;
        flex-direction: column;
    }
    .care-note-entry--patient .patient-context-fold { order: 1; }

    /* Notes par jour : le formulaire d'ajout passe en tête de la liste. */
    .agenda-day {
        display: flex;
        flex-direction: column;
    }
    .agenda-day__add { order: -1; margin-bottom: var(--gap); }
}

/* Préparation au téléphone (lot 21, §3) : le panneau des patients, replié sous
   « Ajouter un patient », passe avant la feuille (il l'est déjà dans le HTML ;
   une seule colonne sous 60rem) ; le titre du panneau devient inutile. */
@media (max-width: 45rem) {
    .compose__candidates-phone > h2 { display: none; }
}

/* --- Répertoire en liste et gestes de la fiche (lot 16a-bis, spec §9.5) ------
   Sous 45rem, le tableau devient une liste « nom, numéro à appeler » : plus de
   largeur minimale, plus de retour à la ligne interdit, et les colonnes autres
   que le nom (1re cellule) et « Appeler » se masquent. La colonne « Appeler » est
   .phone-only. La rangée d'actions de la fiche est .phone-only aussi. */
.record-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-sm);
    margin-bottom: var(--gap);
}

@media (max-width: 45rem) {
    .directory th,
    .directory td { white-space: normal; }
    .directory th:not(:first-child):not(.directory__call),
    .directory td:not(:first-child):not(.directory__call) { display: none; }
    .directory td.directory__call { text-align: right; }
    .record-actions .button { flex: 1 1 auto; text-align: center; }
}

/* --- Saisie d'une transmission depuis un passage (lot 21, §4) --------------
   Classe posée par _care_note_fields.twig quand le champ caché `entry` est
   présent. Au téléphone : le nom du patient en gras et lisible, la zone de
   texte à la moitié de la hauteur d'écran, le bouton pleine largeur dessous.
   Au-dessus de 45rem, rien ne change. */
@media (max-width: 45rem) {
    .care-note-form--from-entry textarea { min-height: 50vh; }
    .care-note-form--from-entry .form-actions button { width: 100%; }
    [data-testid="care-note-patient"] { font-size: 1.25rem; font-weight: 700; color: var(--text); }
}

/* --- Calendrier replié au téléphone (lot 22, spec §5) ------------------------
   Le même calendrier que la colonne de gauche (cachée sous 45rem), dans un
   <details> fermé sous la barre de jour. Résumé de 44 px, calendrier pleine
   largeur. .phone-only le masque au-dessus de 45rem. */
@media (max-width: 45rem) {
    .phone-calendar { margin-bottom: var(--gap); }
    .phone-calendar > summary {
        display: flex;
        align-items: center;
        min-height: 2.75rem;
        padding-inline: var(--gap);
        color: var(--primary);
        font-weight: 600;
        cursor: pointer;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        background: var(--surface);
    }
    .phone-calendar[open] > summary { margin-bottom: var(--gap-sm); }
    .phone-calendar .calendar { width: 100%; }
}

/* --- Utilitaires de largeur (lot 16a-bis) ---------------------------------
   .phone-only n'existe que sous 45rem, .desktop-only que au-dessus. En FIN de
   feuille et en !important : aucune règle de composant (par ex. `.button {
   display: inline-block }`) ne doit les contredire. Du côté où l'élément doit
   se voir, rien n'est déclaré : il garde son propre affichage. */
/* Complément exact de la requête téléphone : ni trou ni recouvrement, même aux
   largeurs fractionnaires (zoom, densité non entière). */
@media not all and (max-width: 45rem) {
    .phone-only { display: none !important; }
}

@media (max-width: 45rem) {
    .desktop-only { display: none !important; }
}
