/* Mêmes couleurs et même densité que l'app iPhone : la page et l'app doivent se lire pareil. */
:root {
  --fond: #f2f2f7; --carte: #fff; --texte: #1c1c1e; --gris: #6c6c70;
  --separateur: #d1d1d6; --accent: #0a84ff;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --fond: #000; --carte: #1c1c1e; --texte: #f2f2f7;
          --gris: #98989d; --separateur: #38383a; }
}
:root[data-theme="dark"] { --fond: #000; --carte: #1c1c1e; --texte: #f2f2f7;
        --gris: #98989d; --separateur: #38383a; }
* { box-sizing: border-box; }
body {
  margin: 0; background: var(--fond); color: var(--texte);
  font: 16px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  padding-bottom: 3rem;
}
header {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1rem 1rem .5rem;
}
h1 { font-size: 1.3rem; margin: 0; }
#soustitre { margin: .15rem 0 0; color: var(--gris); font-size: .85rem; }
.lien { background: none; border: 0; color: var(--accent); font-size: .9rem; cursor: pointer; }

nav { padding: 0 1rem 1rem; display: grid; gap: .6rem; }
.onglets { display: flex; background: var(--separateur); border-radius: .6rem; padding: .15rem; }
.onglets button {
  flex: 1; border: 0; background: none; color: var(--texte); padding: .4rem;
  border-radius: .5rem; cursor: pointer; font-size: .9rem;
}
.onglets .actif { background: var(--carte); font-weight: 600; }
.dates { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.dates button {
  border: 0; background: var(--carte); color: var(--accent); width: 2.2rem; height: 2.2rem;
  border-radius: .5rem; font-size: 1.2rem; cursor: pointer;
}
input[type=date], select {
  background: var(--carte); color: var(--texte); border: 1px solid var(--separateur);
  border-radius: .5rem; padding: .4rem .6rem; font-size: .9rem;
}

main { padding: 0 1rem; }
.vide { text-align: center; padding: 3rem 1rem; color: var(--gris); }
.principal {
  background: var(--accent); color: #fff; border: 0; border-radius: .6rem;
  padding: .7rem 1.2rem; font-size: 1rem; cursor: pointer; margin: 1rem 0;
}
.note { font-size: .8rem; }

/* Blocs par poste, comme la vue d'ensemble de l'app. */
.bloc { background: var(--carte); border-radius: .75rem; overflow: hidden; margin-bottom: .9rem; }
.bloc > h2 {
  margin: 0; padding: .6rem .8rem; color: #fff; font-size: 1rem;
  display: flex; justify-content: space-between; align-items: baseline; gap: .5rem;
}
.bloc h2 .horaire { font-size: .75rem; opacity: .85; font-weight: 400; }
.personne { display: flex; gap: .6rem; padding: .55rem .8rem; border-top: 1px solid var(--separateur); }
.personne:first-of-type { border-top: 0; }
.pastille { width: 1.6rem; height: 1.6rem; border-radius: 50%; flex: none; }
.personne .qui { font-size: .95rem; }
.personne .quoi { font-size: .78rem; color: var(--gris); }

/* Grille du mois. */
.grille { overflow-x: auto; background: var(--carte); border-radius: .75rem; padding: .5rem; }
table { border-collapse: collapse; font-size: .7rem; }
th, td { padding: 1px 2px; text-align: center; white-space: nowrap; }
th.nom, td.nom { text-align: left; position: sticky; left: 0; background: var(--carte); padding-right: .5rem; }
td .code {
  display: block; border-radius: .25rem; padding: .12rem .2rem; margin: 1px 0;
  font-size: .62rem; font-weight: 600;
}
.repos { opacity: .45; }
footer { position: fixed; bottom: 0; left: 0; right: 0; padding: .4rem 1rem;
         font-size: .75rem; color: var(--gris); background: var(--fond); }

/* Accès */
.liste { background: var(--carte); border-radius: .75rem; overflow: hidden; margin-bottom: .9rem; }
.liste h2 { margin: 0; padding: .6rem .8rem; font-size: .8rem; color: var(--gris);
            text-transform: uppercase; letter-spacing: .04em; }
.membre { display: flex; justify-content: space-between; align-items: center; gap: .8rem;
          padding: .6rem .8rem; border-top: 1px solid var(--separateur); width: 100%;
          background: none; border-left: 0; border-right: 0; border-bottom: 0; color: var(--texte);
          font: inherit; text-align: left; cursor: pointer; }
.membre .droits { font-size: .78rem; color: var(--gris); }
.membre.attente .droits { color: #c2410c; }
dialog {
  border: 0; border-radius: .9rem; padding: 1.2rem; max-width: 26rem; width: calc(100% - 2rem);
  background: var(--carte); color: var(--texte);
}
dialog::backdrop { background: rgba(0,0,0,.4); }
dialog h2 { margin: 0; font-size: 1.1rem; }
dialog fieldset { border: 0; padding: 0; margin: 1rem 0 0; }
dialog legend { font-size: .8rem; color: var(--gris); padding: 0; }
dialog label { display: block; padding: .4rem 0; font-size: .92rem; }
dialog label .note { display: block; margin: 0 0 0 1.5rem; }
menu { display: flex; align-items: center; gap: .5rem; padding: 0; margin: 1.2rem 0 0; }
menu .pousse { flex: 1; }
menu button { border: 0; background: var(--separateur); color: var(--texte);
              border-radius: .5rem; padding: .5rem .8rem; font-size: .9rem; cursor: pointer; }
menu .principal.petit { padding: .5rem .9rem; margin: 0; }
menu .danger { background: none; color: #d33; }

.identifiants { display: grid; gap: .5rem; max-width: 18rem; margin: .5rem auto 0; }
.identifiants input {
  background: var(--carte); color: var(--texte); border: 1px solid var(--separateur);
  border-radius: .5rem; padding: .6rem .7rem; font-size: .95rem; width: 100%;
}
.identifiants button {
  border: 0; background: var(--separateur); color: var(--texte); border-radius: .5rem;
  padding: .6rem; font-size: .95rem; cursor: pointer;
}

/* Saisie d'une journée */
.codes { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .8rem; }
.codes button {
  border: 2px solid transparent; border-radius: .5rem; padding: .35rem .6rem;
  font-size: .85rem; font-weight: 600; cursor: pointer;
}
.codes button.pose { border-color: var(--accent); }
#saisiePosees { margin-top: .8rem; display: grid; gap: .4rem; }
.posee { display: flex; gap: .5rem; align-items: center; }
.posee .etiquette { border-radius: .4rem; padding: .3rem .5rem; font-size: .8rem; font-weight: 600;
                    min-width: 4.5rem; text-align: center; }
.posee input {
  flex: 1; background: var(--fond); color: var(--texte); border: 1px solid var(--separateur);
  border-radius: .45rem; padding: .4rem .5rem; font-size: .85rem;
}
td.modifiable { cursor: pointer; }
td.modifiable:hover { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Fiches de paramétrage */
#ficheChamps { display: grid; gap: .7rem; margin-top: .9rem; }
#ficheChamps label { display: grid; gap: .25rem; font-size: .8rem; color: var(--gris); }
#ficheChamps input, #ficheChamps select {
  background: var(--fond); color: var(--texte); border: 1px solid var(--separateur);
  border-radius: .5rem; padding: .5rem .6rem; font-size: .95rem; width: 100%;
}
#ficheChamps .deuxColonnes { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; }
.palette { display: flex; flex-wrap: wrap; gap: .35rem; }
.palette button { width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 2px solid transparent;
                  cursor: pointer; padding: 0; }
.palette button.choisie { border-color: var(--texte); }
.ajout { width: 100%; border: 0; background: var(--carte); color: var(--accent);
         border-radius: .75rem; padding: .7rem; font-size: .95rem; cursor: pointer;
         margin-bottom: .9rem; }

/* Qui je suis, visible partout : plusieurs comptes tournent sur le même écran. */
.moi { display: grid; justify-items: end; gap: .1rem; text-align: right; }
#moiCourriel { font-size: .82rem; font-weight: 600; }
#moiRole { font-size: .72rem; color: var(--gris); }
.moi .lien { font-size: .78rem; padding: 0; }
@media (max-width: 30rem) {
  #moiCourriel { max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* Cycle : postes en lignes, jours en colonnes */
.cycle { overflow-x: auto; background: var(--carte); border-radius: .75rem; padding: .5rem; }
.cycle table { width: 100%; }
.cycle th { font-size: .75rem; padding: .3rem; }
.cycle td.poste { text-align: left; min-width: 7rem; }
.cycle td.poste strong { font-size: .82rem; }
.cycle td.poste span { display: block; font-size: .7rem; color: var(--gris); }
.cycle td.case { padding: 2px; min-width: 6rem; vertical-align: top; }
.jeton { display: block; border-radius: .4rem; padding: .28rem .3rem; margin: 1px 0;
         font-size: .72rem; font-weight: 600; color: #fff; }
.jeton small { display: block; font-weight: 400; opacity: .9; font-size: .65rem; }
.periodes { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: .6rem; }
.periodes button { border: 0; border-radius: 1rem; padding: .35rem .8rem; font-size: .8rem;
                   background: var(--separateur); color: var(--texte); cursor: pointer; }
.periodes button.actif { background: var(--accent); color: #fff; font-weight: 600; }
#caseAgents { display: grid; gap: .4rem; margin-top: .9rem; max-height: 55vh; overflow-y: auto; }
.choixAgent { display: flex; align-items: center; gap: .5rem; }
.choixAgent input[type=text] {
  flex: 1; background: var(--fond); color: var(--texte); border: 1px solid var(--separateur);
  border-radius: .45rem; padding: .35rem .5rem; font-size: .82rem;
}

/* Bilan */
.bilan { overflow-x: auto; background: var(--carte); border-radius: .75rem; padding: .5rem; }
.bilan table { width: 100%; font-size: .85rem; }
.bilan th { color: var(--gris); font-weight: 600; font-size: .72rem; text-transform: uppercase; }
.bilan td, .bilan th { padding: .45rem .5rem; }
.bilan td:not(.nom), .bilan th:not(.nom) { text-align: right; }

/* Agendas */
.agenda-lien { font-size: .7rem; color: var(--gris); word-break: break-all; }
.agenda-actions { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .3rem; }
.agenda-actions button { border: 0; border-radius: .45rem; padding: .3rem .6rem; font-size: .78rem;
                         background: var(--separateur); color: var(--texte); cursor: pointer; }
.agenda-actions .danger { background: none; color: #d33; }
.membre .colonne { display: grid; gap: .15rem; width: 100%; }

/* Onglets nombreux : qu'ils se replient plutôt que déborder. */
.onglets { flex-wrap: wrap; }

/* Impression : la page devient la feuille. */
@page { size: A4 landscape; margin: 10mm; }
@media print {
  nav, .moi, footer, .ajout, header button { display: none !important; }
  body { background: #fff; color: #000; padding: 0; }
  .grille, .cycle, .bilan { overflow: visible; box-shadow: none; }
  .grille table { font-size: 6.5pt; }
  td .code { padding: .05rem .1rem; font-size: 5.8pt; }
  .bloc, .liste, tr { break-inside: avoid; }
  .personne, .membre { border-color: #ccc; }
}

/* Capsules de métiers : un tap pour changer de vue, la couleur du métier en aplat.
   Conteneur propre, pour ne pas hériter de la largeur fixe des boutons de dates. */
.capsules { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
button.capsuleMetier {
  border: 1px solid var(--separateur); border-radius: 1rem; padding: .4rem .9rem;
  font-size: .84rem; cursor: pointer; background: var(--carte); color: var(--texte);
  width: auto; height: auto; white-space: nowrap;
}
button.capsuleMetier.actif { border-color: transparent; color: #fff; font-weight: 600; }

/* Jour de vacances scolaires : une barre rouge franche sous l'en-tête — demande du terrain,
   le liseré ambre passait inaperçu. Le padding garde le numéro du jour au-dessus de la barre. */
th.vacances { box-shadow: inset 0 -10px 0 #dc2626; padding-bottom: .8rem !important; }

/* Rang de métier dans les grilles en « Tous » : un titre coloré, pas une ligne de données. */
tr.groupe td { padding-top: .6rem; font-weight: 700; font-size: .7rem; text-transform: uppercase;
               letter-spacing: .05em; box-shadow: inset 0 -2px 0 currentColor; }

/* Sélecteur de couleur libre, aligné sur les pastilles de la palette. */
.palette input[type=color] {
  width: 1.9rem; height: 1.9rem; padding: 0; border: 2px dashed var(--separateur);
  border-radius: 50%; background: none; cursor: pointer;
}

/* Une ligne sur deux légèrement ombrée : sur des rangées larges, l'œil perd sa ligne sans repère.
   Teinte mélangée au thème, pour rester juste dans les deux modes ; les titres de groupe et la
   colonne des noms — collante, donc opaque — reçoivent leur propre version. */
.bilan tbody tr:nth-child(even):not(.groupe) td,
.grille tbody tr:nth-child(even):not(.groupe) td {
  background: color-mix(in srgb, var(--texte) 5%, transparent);
}
.grille tbody tr:nth-child(even):not(.groupe) td.nom {
  background: color-mix(in srgb, var(--texte) 5%, var(--carte));
}

/* Vue mensuelle adaptative : sur grand écran, les colonnes se partagent la largeur à égalité et
   les étiquettes trop longues s'abrègent d'elles-mêmes — le nom complet reste en infobulle.
   Sur petit écran, on garde le défilement : trente et une colonnes comprimées seraient illisibles. */
@media (min-width: 900px) {
  .grille table { width: 100%; table-layout: fixed; }
  .grille th.nom, .grille td.nom { width: 9.5rem; }
}
td .code { overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* Cycle : colonnes égales, jetons centrés — des cases de largeurs disparates se lisent mal.
   La colonne des postes retient son texte chez elle : en disposition fixe, ce qui déborde
   chevauche la colonne voisine, d'où les noms qui passaient sous les jetons. */
.cycle table { table-layout: fixed; width: 100%; }
.cycle td.poste { width: 12rem; overflow: hidden; }
.cycle td.poste strong { white-space: normal; overflow-wrap: break-word; }
.cycle td.case { vertical-align: middle; text-align: center; }
.cycle .jeton { margin: .15rem auto; min-height: 2.15rem; display: flex; flex-direction: column;
                justify-content: center; }

/* Impression prête à l'emploi : la grille prend la page, sans réglage à faire. */
@media print {
  .capsules, #annuler, .ajout, .note { display: none !important; }
  h1 { font-size: 15pt; }
  #soustitre { font-size: 10pt; }
  .grille table { width: 100%; table-layout: fixed; }
  .grille th.nom, .grille td.nom { width: 6rem; }
  td .code { font-size: 5.6pt; padding: .04rem .08rem; }
  .bilan table { width: 100%; }

  /* Les rangées d'outils — périodes, Reporter, Rotation, pinceau — ne s'impriment pas : le
     papier montre le planning, pas les boutons qui l'ont fabriqué. */
  .periodes { display: none !important; }

  /* Le cycle tient sur SA page : jetons compacts (le !important reprend la main sur les
     hauteurs égalisées en ligne), colonne des postes resserrée, et une réduction d'ensemble. */
  .cycle .jeton { min-height: 0 !important; font-size: 7pt !important; padding: .12rem .2rem; }
  .cycle .jeton small { font-size: 5.5pt; }
  .cycle td.poste { width: 8.5rem; }
  body[data-vue="cycle"] main { zoom: .78; }
  body[data-vue="mois"] main, body[data-vue="semaine"] main { zoom: .92; }
}

/* L'accueil du jour : l'essentiel sans défiler. */
.accueilJour { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
.accueilJour h2 { color: #fff; }
.accueilJour .membre { cursor: default; }
.accueilJour .poste { font-weight: 600; min-width: 9rem; }
.accueilJour .noms { color: var(--texte); }

/* Bandeau peint : le texte passe en blanc, les liens aussi. */
header.peint { border-radius: 0 0 .9rem .9rem; padding-bottom: .7rem; }
header.peint h1, header.peint #soustitre, header.peint #moiCourriel, header.peint #moiRole {
  color: #fff;
}
header.peint .lien { color: #fff; text-decoration: underline; }

/* Le nom de l'agent se lit avant tout le reste de la ligne ; la quotité s'aligne au bord
   droit de la colonne, en colonne propre — les 50 % se comparent alors d'un coup d'œil. */
.grille tbody td.nom { display: flex; align-items: center; justify-content: space-between;
                       gap: .3rem; }
.grille td.nom .nomAgent { font-size: .88rem; font-weight: 600; overflow: hidden;
                           text-overflow: ellipsis; white-space: nowrap; }
.grille td.nom .pct { font-size: .68rem; color: var(--gris); white-space: nowrap; flex: none; }

/* Un nom cliquable se signale sans crier : le soulignement n'apparaît qu'au survol. */
.nomCliquable { cursor: pointer; }
.nomCliquable:hover, td.nom[data-agent]:hover .nomAgent { text-decoration: underline; }
[data-fiche-agent].personne:hover .qui { text-decoration: underline; }

/* Lignes d'effectif sous les grilles : détachées des agents par un trait net. */
.grille tfoot tr:first-child td { border-top: 2px solid var(--separateur); }
.grille tfoot td.nom { font-size: .82rem; color: var(--gris); }

/* Bandes d'outils : chaque rangée de boutons vit dans son propre cadre étiqueté — Métier,
   Mois, Pinceau… — au lieu de s'empiler en vrac. */
.bande {
  border: 1px solid var(--separateur);
  border-radius: .75rem;
  padding: .45rem .6rem;
  margin: 0 0 .55rem;
}
.bandeTitre {
  flex: none;
  min-width: 4rem;
  font-size: .66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--gris);
}

/* Sur téléphone, une bande = une seule ligne qui défile du pouce : plus rien ne s'empile. */
@media (max-width: 48rem) {
  .bande { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .bande::-webkit-scrollbar { display: none; }
  .bande .capsuleMetier { flex: none; }
}

/* Chaque bande a sa couleur : l'œil retrouve la bonne rangée avant même de lire l'étiquette.
   Teintes mélangées au fond du thème — discrètes en clair comme en sombre. */
.bande { border-width: 2px; }
.bandeMetier   { border-color: color-mix(in srgb, #2563eb 40%, var(--separateur));
                 background: color-mix(in srgb, #2563eb 6%, transparent); }
.bandeMois     { border-color: color-mix(in srgb, #d97706 45%, var(--separateur));
                 background: color-mix(in srgb, #d97706 7%, transparent); }
.bandePinceau  { border-color: color-mix(in srgb, #16a34a 45%, var(--separateur));
                 background: color-mix(in srgb, #16a34a 6%, transparent); }
.bandeColonnes { border-color: color-mix(in srgb, #7c3aed 40%, var(--separateur));
                 background: color-mix(in srgb, #7c3aed 6%, transparent); }
.bandeMetier   .bandeTitre { color: color-mix(in srgb, #2563eb 65%, var(--texte)); }
.bandeMois     .bandeTitre { color: color-mix(in srgb, #d97706 65%, var(--texte)); }
.bandePinceau  .bandeTitre { color: color-mix(in srgb, #16a34a 65%, var(--texte)); }
.bandeColonnes .bandeTitre { color: color-mix(in srgb, #7c3aed 65%, var(--texte)); }

/* Sous-effectif : une pastille rouge pleine, pas un chiffre qui murmure. Cliquée, elle propose
   du renfort. */
.alerteEffectif {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.6rem; height: 1.6rem; padding: 0 .3rem;
  background: #dc2626; color: #fff; font-weight: 800; font-size: .85rem;
  border: 0; border-radius: .5rem;
}
button.alerteEffectif { cursor: pointer; box-shadow: 0 0 0 2px color-mix(in srgb, #dc2626 35%, transparent); }
button.alerteEffectif:hover { background: #b91c1c; }

.renfortChoix {
  display: flex; justify-content: space-between; align-items: center; gap: .6rem;
  width: 100%; text-align: left; padding: .5rem .6rem; margin-top: .3rem;
  background: var(--fond); color: var(--texte);
  border: 1px solid var(--separateur); border-radius: .55rem;
  font-size: .9rem; cursor: pointer;
}
.renfortChoix:hover { border-color: var(--accent); }

/* ============================================================
   Couche moderne : profondeur, verre, contraste, mouvement.
   Posée en fin de feuille pour surcharger proprement la base.
   ============================================================ */

/* Contraste relevé : gris plus francs, séparations plus nettes — sans toucher aux teintes. */
:root { --gris: #55555b; --separateur: #c5c5cd;
        --ombre: 0 1px 2px rgba(0,0,0,.05), 0 6px 20px rgba(0,0,0,.07); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --gris: #a6a6ad; --separateur: #46464c;
        --ombre: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35); }
}
:root[data-theme="dark"] { --gris: #a6a6ad; --separateur: #46464c;
        --ombre: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35); }

/* Profondeur : les cartes flottent au lieu d'être posées à plat. */
.grille, .liste, .bloc, dialog { box-shadow: var(--ombre); }
.grille, .liste, .bloc { border-radius: .9rem; }

/* Verre dépoli : bandes d'outils, onglets et pied de page laissent deviner ce qui passe
   dessous. Le fond translucide existait ; le flou lui donne sa matière. */
.bande, .onglets, footer {
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
}
.onglets { background: color-mix(in srgb, var(--separateur) 55%, transparent); }
footer { background: color-mix(in srgb, var(--fond) 70%, transparent);
         border-top: 1px solid color-mix(in srgb, var(--separateur) 60%, transparent); }
.onglets .actif { box-shadow: 0 1px 4px rgba(0,0,0,.12); }

/* Boîtes de dialogue : arrière-plan flouté, arrivée en douceur. */
dialog::backdrop {
  background: rgba(0, 0, 0, .35);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Mouvement : bref, discret, jamais imposé à qui préfère le calme. */
button, .capsuleMetier, .onglets button, .membre, .renfortChoix {
  transition: transform .12s ease, box-shadow .12s ease,
              background-color .15s ease, border-color .15s ease, opacity .15s ease;
}
@media (prefers-reduced-motion: no-preference) {
  .capsuleMetier:hover, .dates button:hover, .renfortChoix:hover, .principal:hover {
    transform: translateY(-1px);
    box-shadow: 0 3px 10px rgba(0,0,0,.14);
  }
  .capsuleMetier:active, .dates button:active, .onglets button:active, .principal:active {
    transform: translateY(0) scale(.96);
  }
  dialog[open] { animation: boiteArrive .18s cubic-bezier(.2, .9, .3, 1.15); }
  @keyframes boiteArrive {
    from { opacity: 0; transform: translateY(12px) scale(.97); }
  }
  /* Le sous-effectif respire : assez pour attirer l'œil, pas assez pour agacer. */
  button.alerteEffectif { animation: alertePulse 2.4s ease-in-out infinite; }
  @keyframes alertePulse {
    0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, #dc2626 35%, transparent); }
    50%      { box-shadow: 0 0 0 5px color-mix(in srgb, #dc2626 18%, transparent); }
  }
}

/* Suivre sa ligne dans les grandes grilles : la ligne survolée se teinte, nom compris. */
.grille tbody tr:hover td { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.grille tbody tr:hover td.nom { background: color-mix(in srgb, var(--accent) 8%, var(--carte)); }

/* Clavier : un anneau net plutôt qu'un halo flou. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: .3rem; }

/* Le papier ignore tout ça : ni ombres, ni flou, ni battements. */
@media print {
  * { box-shadow: none !important; animation: none !important; transition: none !important;
      backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
  /* Les colonnes collantes font ramer — parfois geler — le moteur d'impression sur les
     grands tableaux : sur le papier, rien ne défile, rien n'a besoin de coller. */
  th.nom, td.nom { position: static !important; }
  .grille tbody tr:hover td { background: none; }
}

/* Les années aux extrémités de la bande des mois : sombres, en gras — des bornes, pas des
   mois. L'œil ne les confond plus avec Janv et Déc. */
button.capsuleAnnee {
  background: #334155; color: #fff; border-color: #334155; font-weight: 700;
}
button.capsuleAnnee:hover { background: #1e293b; }

/* Le centre du bandeau : la date en gros titre, le métier de la vue juste dessous. Centré
   pour de vrai — position absolue au milieu du bandeau, quelle que soit la largeur des côtés. */
header { position: relative; }
.centreBandeau {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  text-align: center; pointer-events: none; max-width: 40%;
}
.centreBandeau #soustitre {
  margin: 0; font-size: 1.5rem; font-weight: 800; color: var(--texte);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.centreBandeau #soustitre::first-letter { text-transform: uppercase; }
#titreMetier {
  margin: .1rem 0 0; font-size: 1.05rem; font-weight: 700; color: var(--gris);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
header.peint .centreBandeau #soustitre, header.peint #titreMetier { color: #fff; }

/* Petit écran : plus de place au centre — le bloc redescend dans le flux, sous le titre. */
@media (max-width: 48rem) {
  header { flex-wrap: wrap; }
  .centreBandeau {
    position: static; transform: none; order: 3; width: 100%; max-width: none;
    text-align: left;
  }
  .centreBandeau #soustitre { font-size: 1.25rem; }
}

@media print {
  .centreBandeau { position: static; transform: none; max-width: none; text-align: left; }
  .centreBandeau #soustitre { font-size: 12pt; }
  #titreMetier { font-size: 10pt; }
}

/* Le logo du service : un badge à droite du bandeau, hors des textes. Sur bandeau peint, il
   gagne un anneau blanc et un halo de la couleur choisie — l'effet suit le réglage. */
#logoService {
  width: 3.4rem; height: 3.4rem; border-radius: 26%; flex: none; margin-left: auto;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .16);
  transition: transform .2s ease, box-shadow .2s ease;
}
header.peint #logoService {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .65),
              0 0 22px color-mix(in srgb, var(--bandeau, #0a84ff) 85%, #fff),
              0 4px 14px rgba(0, 0, 0, .28);
}
@media (prefers-reduced-motion: no-preference) {
  #logoService:hover { transform: rotate(-4deg) scale(1.07); }
}
@media (max-width: 48rem) {
  #logoService { width: 2.6rem; height: 2.6rem; }
}
@media print {
  #logoService { display: none !important; }
}

/* La règle qui manquait depuis le début : l'attribut hidden vient de la feuille du
   NAVIGATEUR, et n'importe quel display posé par la nôtre (nav en grid, capsules en flex…)
   l'écrase silencieusement. D'où des barres d'onglets et des bandeaux fantômes sur l'écran
   de connexion. Ici, caché veut dire caché — pour tout le monde, définitivement. */
[hidden] { display: none !important; }

/* Demande de repos : la main levée dans le coin de la case, et un liseré pour la repérer. */
.grille td.aDemande { position: relative; box-shadow: inset 0 0 0 2px #f59e0b; }
.badgeDemande {
  position: absolute; top: -2px; right: -1px; font-size: .6rem; line-height: 1;
  background: #f59e0b; color: #fff; border-radius: .3rem; padding: 1px 2px;
}
@media print { .badgeDemande { display: none !important; } .grille td.aDemande { box-shadow: none !important; } }

/* Sur le papier, le planning ne se colle plus au plafond : bandeau et grille forment un bloc
   centré dans la hauteur de la page. Les marges automatiques s'annulent d'elles-mêmes quand le
   contenu dépasse une page — rien n'est jamais poussé hors feuille. */
@media print {
  html, body { height: 100%; }
  body { display: flex; flex-direction: column; min-height: 100vh; }
  header { margin-top: auto; }
  main { margin-bottom: auto; }
}

/* Semaines types sur papier : une affiche A4 paysage, pas un timbre. Pleine largeur, jetons
   grands et lisibles, postes en colonne nette — et le bloc centré dans la hauteur (marges
   automatiques du bandeau et du contenu, posées plus haut). Ces règles, placées en fin de
   feuille, reprennent la main sur la version compacte précédente. */
@media print {
  body[data-vue="cycle"] main { zoom: 1; }
  body[data-vue="cycle"] .cycle { padding: 0; }
  body[data-vue="cycle"] .cycle table { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 2mm; }
  body[data-vue="cycle"] .cycle th { font-size: 13pt; padding: 2mm 0 3mm; }
  body[data-vue="cycle"] .cycle td.poste { width: 38mm; padding: 0; }
  body[data-vue="cycle"] .cycle td.poste strong { font-size: 12pt; }
  body[data-vue="cycle"] .cycle td.poste span { font-size: 9.5pt; }
  body[data-vue="cycle"] .cycle td.case { padding: 0; }
  body[data-vue="cycle"] .cycle .jeton {
    min-height: 15mm !important; font-size: 12.5pt !important; font-weight: 700;
    padding: 2mm 3mm; margin: 0; border-radius: 3mm;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  body[data-vue="cycle"] .cycle .jeton small { font-size: 9pt; }
  /* Le bandeau annonce la semaine et le métier : un vrai titre d'affiche. */
  body[data-vue="cycle"] .centreBandeau #soustitre { font-size: 18pt; }
  body[data-vue="cycle"] #titreMetier { font-size: 13pt; }
}

/* Centrage vertical, version sans page blanche : la règle précédente (min-height: 100vh sur
   un body en flux) débordait d'un cheveu et fabriquait une seconde feuille vide. Ici, le corps
   fait EXACTEMENT la hauteur de la page et masque tout débordement — réservé aux vues conçues
   pour tenir sur une feuille ; les vues longues (Bilan, Jour) restent en flux normal. */
@media print {
  html, body { height: auto; min-height: 0; }
  body { display: block; }
  header { margin-top: 0; }
  main { margin-bottom: 0; }
  body[data-vue="cycle"], body[data-vue="semaine"], body[data-vue="mois"] {
    display: flex; flex-direction: column;
    height: 100vh; box-sizing: border-box; overflow: hidden;
  }
  body[data-vue="cycle"] header, body[data-vue="semaine"] header, body[data-vue="mois"] header {
    margin-top: auto;
  }
  body[data-vue="cycle"] main, body[data-vue="semaine"] main, body[data-vue="mois"] main {
    margin-bottom: auto;
  }
}

/* Safari calcule 100vh à l'impression sur la fenêtre, pas sur la feuille : hauteur physique,
   donc. A4 paysage = 210 mm, moins 2 × 10 mm de marges de page → 189 mm, un cheveu de marge. */
@media print {
  body[data-vue="cycle"], body[data-vue="semaine"], body[data-vue="mois"] {
    height: 189mm; max-height: 189mm;
  }
}

/* Les notes sous le planning imprimé : une liste serrée sur plusieurs colonnes, en petit — le
   papier est pour la grille, les notes sont des renvois. À l'écran, rien ne change. */
@media print {
  .notesMois { margin-top: 3mm; break-inside: auto; }
  .notesMois h2 { font-size: 7.5pt; padding: 1mm 0; }
  .notesMois { column-count: 3; column-gap: 6mm; }
  .notesMois h2 { column-span: all; }
  .notesMois .personne { padding: .4mm 0; border: 0; gap: 2mm; break-inside: avoid; }
  .notesMois .personne .qui { font-size: 6.5pt; min-width: 9mm !important; }
  .notesMois .personne .quoi { font-size: 6.5pt; }
  .notesMois .personne br { display: none; }

  /* Safari réserve ses en-têtes/pieds de page DANS la zone imprimable : on lui laisse la place. */
  body[data-vue="cycle"], body[data-vue="semaine"], body[data-vue="mois"] {
    height: 178mm; max-height: 178mm;
  }
}
