/* ============================================================
   Portail RH — SPE Connect
   Même vocabulaire de composants que Temps Terrain (card, btn,
   puce, tabs, modale, toast) : les deux applications doivent se
   reconnaître au premier coup d'œil. Les jetons de marque
   viennent de brand.css.

   Une différence assumée : Temps Terrain est une application de
   terrain, pensée pour le pouce sur un téléphone. Celle-ci est un
   back-office où l'on lit des tableaux — la colonne centrale est
   donc large, et les tableaux sont denses.
   ============================================================ */

* { box-sizing: border-box; }

/* `hidden` est un attribut du HTML, pas une suggestion. La feuille de style du
   navigateur lui applique `display: none`, mais **toute** règle d'auteur qui
   fixe un display l'emporte : `.btn { display: inline-flex }` suffit à rendre
   visible un élément masqué. Conséquence constatée : l'onglet Paramètres
   s'affichait pour les collaborateurs, et un bouton d'action réservé aux RH
   aussi. Les boutons restaient sans effet — l'API refuse — mais une interface
   qui propose ce qu'elle n'autorise pas est une interface qui ment. */
[hidden] { display: none !important; }

html, body { max-width: 100%; overflow-x: clip; }

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--surface-green);
  color: var(--graphite);
  min-height: 100dvh;
  font-size: 15px;
  line-height: 1.5;
}

input, select, textarea, button { max-width: 100%; }

/* ── Barre supérieure ─────────────────────────────────────── */
/* La barre et les onglets tiennent dans un seul bloc collant. Les coller
   séparément obligeait à connaître la hauteur de la barre pour décaler les
   onglets — une hauteur qui change avec la largeur de l'écran, le chargement
   des polices et l'apparition du lien vers Temps Terrain. Un seul conteneur,
   et le navigateur s'en charge. */
.entete-collante { position: sticky; top: 0; z-index: 60; }
.topbar {
  background: var(--forest);
  padding: 12px 20px;
  display: flex; align-items: center; gap: 14px;
  border-bottom: 3px solid var(--volt);
}
.topbar img { height: 26px; }
.topbar .spacer { flex: 1; }
.topbar .who { text-align: right; line-height: 1.25; }
.topbar .who strong { color: var(--white); font-size: 14px; display: block; }
.topbar .who span { color: var(--sage); font-size: 11.5px; font-family: var(--font-mono); }
.topbar-actions { display: flex; align-items: center; gap: 8px; }

/* ── Onglets ──────────────────────────────────────────────── */
.tabs {
  display: flex; background: var(--white); border-bottom: 1px solid var(--border);
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: 0 0 auto; padding: 13px 18px; border: none; background: none;
  font-family: var(--font-body); font-size: 13.5px; font-weight: 600; color: var(--stone);
  cursor: pointer; border-bottom: 3px solid transparent; white-space: nowrap;
  display: flex; align-items: center; gap: 7px;
}
.tab:hover { color: var(--forest); }
.tab[aria-selected="true"] { color: var(--forest); border-bottom-color: var(--volt); }
.tab .compteur {
  background: var(--danger); color: var(--white); border-radius: 20px;
  padding: 1px 7px; font-size: 10.5px; font-family: var(--font-mono); font-weight: 600;
}
.tab[aria-selected="true"] .compteur { background: var(--forest); }

/* ── Contenu ──────────────────────────────────────────────── */
main { padding: 20px; max-width: 1420px; margin: 0 auto; }
.vue { display: none; }
.vue.active { display: block; }

.entete-vue {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 16px;
}
.entete-vue h1 { font-size: 24px; margin: 0; }
.entete-vue .muted { margin-top: 2px; }
.entete-vue .actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* ── Cartes ───────────────────────────────────────────────── */
.card {
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; margin-bottom: 14px;
}
.card.serre { padding: 0; overflow: hidden; }
.card-titre {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 1.2px;
  text-transform: uppercase; color: var(--stone); margin-bottom: 10px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.card.serre .card-titre { padding: 14px 16px 10px; margin-bottom: 0; }

.grille2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.grille3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.grille4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }

/* ── Indicateurs ──────────────────────────────────────────── */
.kpi { background: var(--white); border: 1px solid var(--border); border-radius: var(--radius); padding: 15px 17px; }
.kpi .k {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--stone);
}
.kpi .v { font-family: var(--font-display); font-size: 30px; font-weight: 700; color: var(--forest); line-height: 1.1; margin-top: 5px; }
.kpi .d { font-size: 12.5px; color: var(--stone); margin-top: 3px; }
.kpi.danger .v { color: var(--danger); }
.kpi.warn .v { color: var(--warn); }
.kpi.ok .v { color: var(--ok); }
.kpi.volt { background: var(--forest); border-color: var(--forest); }
.kpi.volt .k { color: var(--sage); }
.kpi.volt .v { color: var(--volt); }
.kpi.volt .d { color: var(--sage); }

/* ── Boutons ──────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 16px; border: none; border-radius: var(--radius-sm);
  font-family: var(--font-body); font-size: 14px; font-weight: 600;
  cursor: pointer; transition: filter .15s, transform .05s;
  background: var(--surface-warm); color: var(--forest); text-decoration: none;
}
.btn:hover { filter: brightness(.97); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn-primaire { background: var(--volt); color: var(--forest); font-weight: 700; }
.btn-primaire:hover { background: var(--volt-deep); filter: none; }
.btn-sombre { background: var(--forest); color: var(--white); }
.btn-contour { background: transparent; border: 1.5px solid var(--border-strong); color: var(--forest); }
.btn-danger { background: var(--danger-bg); color: var(--danger); }
.btn-ok { background: var(--ok-bg); color: var(--ok); }
.btn-sm { padding: 6px 11px; font-size: 12.5px; }
.btn-bloc { width: 100%; }

/* ── Pastilles ────────────────────────────────────────────── */
.puce {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  border-radius: 20px; font-family: var(--font-mono); font-size: 10px;
  font-weight: 500; letter-spacing: .5px; text-transform: uppercase; white-space: nowrap;
}
.puce-ok { background: var(--ok-bg); color: var(--ok); }
.puce-warn { background: var(--warn-bg); color: var(--warn); }
.puce-danger { background: var(--danger-bg); color: var(--danger); }
.puce-neutre { background: var(--surface-warm); color: var(--stone); }
.puce-volt { background: var(--volt); color: var(--forest); }
.puce-forest { background: var(--ok-bg); color: var(--forest); }
.point { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: 0 0 9px; }

/* ── Tableaux ─────────────────────────────────────────────── */
.tableau-conteneur { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .8px; text-transform: uppercase;
  color: var(--stone); text-align: left; padding: 10px 12px; border-bottom: 1.5px solid var(--border);
  white-space: nowrap; font-weight: 500; background: var(--white);
  position: sticky; top: 0; z-index: 2;
}
td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:hover { background: var(--surface-green); }
tr.cliquable { cursor: pointer; }
.num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.pile { display: flex; flex-direction: column; gap: 2px; }
.pile .p { font-weight: 600; }
.pile .s { font-size: 11.5px; color: var(--stone); }

/* ── Formulaires ──────────────────────────────────────────── */
.champ { margin-bottom: 13px; }
.champ label {
  display: block; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .8px;
  text-transform: uppercase; color: var(--stone); margin-bottom: 5px;
}
.champ .aide { font-size: 11.5px; color: var(--stone); margin-top: 4px; }
/* Une aide isolée, hors formulaire — même voix, même discrétion. */
.aide { font-size: 11.5px; color: var(--stone); }

/* Un lien d'export sans sélection ne mène nulle part : plutôt que de le laisser
   exporter le contraire de ce qui est coché, on le neutralise visiblement. */
a.desactive { opacity: .45; pointer-events: none; cursor: default; }

/* Cocher les occupants d'une réservation : une chambre double, un gîte pour
   quatre. En colonnes plutôt qu'en liste — seize noms empilés font défiler la
   fenêtre au point de perdre le bouton d'enregistrement. */
.cases-occupants {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 2px 12px; max-height: 210px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px;
}
.cases-occupants .case { margin: 0; }
.mono { font-family: var(--font-mono); font-size: 11.5px; word-break: break-all; }

/* ── Calendrier d'octroi des primes ──────────────────────────────────────────
   Le motif d'octroi n'est pas régulier — lundi oui, mardi non, mercredi et
   jeudi oui — et une liste de dates ne le montre pas. Une grille où les lundis
   sont les uns sous les autres, si. C'est toute la raison d'être de cet écran :
   il est fait pour être lu en diagonale autant que coché. */
.legende-primes { display: grid; gap: 8px; margin: 12px 0; }
.legende-prime {
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; background: var(--surface-warm);
}
.pastille {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto;
}
.semaine-bascules { gap: 4px; margin-top: 6px; flex-wrap: wrap; }
.semaine-bascules .btn { min-width: 30px; padding: 2px 6px; }

table.calendrier-primes { width: 100%; border-collapse: collapse; table-layout: fixed; }
table.calendrier-primes th {
  padding: 5px 4px; font-size: 10px; letter-spacing: .6px; text-transform: uppercase;
  color: var(--stone); font-family: var(--font-mono); border: 1px solid var(--border);
  background: var(--surface-warm); position: static;
}
table.calendrier-primes th.we { color: var(--stone); opacity: .7; }
table.calendrier-primes td {
  border: 1px solid var(--border); vertical-align: top; padding: 4px;
  height: 72px; background: var(--surface);
}
table.calendrier-primes td.we { background: var(--surface-warm); }
/* Hors mois ou sans pointage validé : rien à décider, et il faut que cela se
   voie sans avoir à cliquer pour s'en apercevoir. */
table.calendrier-primes td.hors-mois { background: var(--surface-warm); opacity: .4; }
table.calendrier-primes td.sans-journee { background: var(--surface-warm); }
.tete-jour { display: flex; align-items: baseline; justify-content: space-between; gap: 4px; }
.tete-jour .numero { font-weight: 600; font-size: 12px; }
.tete-jour .s { font-size: 9.5px; color: var(--stone); font-family: var(--font-mono); }
/* En grille, la colonne dit le jour de la semaine ; le répéter dans chaque case
   serait du bruit. Il redevient nécessaire dès que l'en-tête disparaît. */
.tete-jour .nom-jour { display: none; }

.prime-case {
  display: flex; align-items: center; gap: 4px;
  margin-top: 3px; font-size: 10px; cursor: pointer; line-height: 1.2;
}
.prime-case input[type="checkbox"] { width: 14px; height: 14px; margin: 0; flex: 0 0 auto; }
.prime-case .code {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Ce que le calcul n'avait pas dit : un ajout, un retrait. Le signe tient dans
   la place disponible là où un mot ne tiendrait pas. */
.prime-case .marque {
  margin-left: auto; font-weight: 700; font-size: 11px; color: var(--moss);
}

@media (max-width: 700px) {
  /* Sept colonnes ne tiennent pas sur un téléphone sans devenir illisibles :
     le calendrier se déroule alors en une colonne, une journée par bloc, et
     l'en-tête des jours disparaît puisque chaque bloc porte sa date. */
  table.calendrier-primes, table.calendrier-primes tbody,
  table.calendrier-primes tr, table.calendrier-primes td { display: block; width: auto; }
  table.calendrier-primes thead { display: none; }
  table.calendrier-primes td { height: auto; margin-bottom: 6px; border-radius: 6px; }
  /* Une journée sans pointage validé n'appelle aucune décision : sur un
     téléphone, la montrer quand même noierait les quinze qui en appellent une. */
  table.calendrier-primes td.hors-mois,
  table.calendrier-primes td.sans-journee { display: none; }
  .prime-case { font-size: 13px; margin-top: 6px; }
  .prime-case input[type="checkbox"] { width: 20px; height: 20px; }
  .prime-case .code { font-size: 11px; }
  .tete-jour .numero { font-size: 14px; }
  .tete-jour .s { font-size: 11px; }
  /* L'en-tête des colonnes n'existe plus : sans le nom du jour, une prime due
     le lundi et pas le mardi ne se vérifie plus. */
  .tete-jour .nom-jour {
    display: inline; margin-right: auto; font-size: 12px; font-weight: 600; color: var(--moss);
  }
}

/* Un nombre se saisit dans le tableau, pas dans une fenêtre : les barèmes se
   lisent sur une grille et se corrigent ligne à ligne. Le champ reste étroit et
   aligné à droite pour que la colonne se compare d'un regard. */
.saisie-nombre {
  width: 5.5rem; text-align: right; padding: 4px 6px;
  font-variant-numeric: tabular-nums;
}
.cellule-prime { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.cellule-prime input[type="number"]:disabled { opacity: .4; }

@media (max-width: 700px) {
  /* Repliée en fiche, la cellule est un flex où l'intitulé occupe le premier
     rang : sans base explicite, la saisie s'écrasait à quelques pixels et
     devenait intouchable au doigt. */
  .saisie-nombre { width: 100%; min-width: 4.5rem; }
  .cellule-prime { flex: 1 1 auto; min-width: 0; justify-content: flex-end; }
  .cellule-prime input[type="checkbox"] { flex: 0 0 auto; width: 20px; height: 20px; }
}
input, select, textarea {
  width: 100%; padding: 10px 12px; font-family: var(--font-body); font-size: 14px;
  color: var(--graphite); background: var(--white);
  border: 1.5px solid var(--border-strong); border-radius: var(--radius-sm);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--moss); box-shadow: 0 0 0 3px rgba(45, 95, 88, .13);
}
input[type="checkbox"] { width: auto; accent-color: var(--moss); }
input[type="color"] { padding: 3px; height: 40px; }
textarea { resize: vertical; min-height: 68px; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 15px 2px; margin: 0 0 14px; }
legend {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--stone); padding: 0 6px;
}
.case { display: flex; align-items: center; gap: 9px; font-size: 14px; margin-bottom: 11px; cursor: pointer; }
.case input { flex: 0 0 auto; }

.filtres {
  display: flex; gap: 11px; align-items: flex-end; flex-wrap: wrap;
  padding: 13px 16px; background: var(--surface-warm); border-bottom: 1px solid var(--border);
}
.filtres .champ { margin-bottom: 0; min-width: 145px; }
/* Sur grand écran, le repli ne se voit pas : le résumé disparaît et les trois
   champs reprennent leur rangée. On ne peut pas s'appuyer sur
   `display: contents` pour les remonter dans la barre — le navigateur glisse
   une boîte `::details-content` entre les deux, que « contents » ne traverse
   pas, et les champs s'empilaient. La rangée est donc reconstruite ici. */
.filtres-repli { display: flex; gap: 11px; align-items: flex-end; }
.filtres-repli-corps { display: flex; gap: 11px; align-items: flex-end; }
.filtres-repli > summary { display: none; }
.filtres .champ.large { flex: 1; min-width: 230px; }

/* ── Fenêtre modale ───────────────────────────────────────── */
.modale {
  position: fixed; inset: 0; z-index: 200; background: rgba(20, 18, 16, .62);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px 20px; overflow-y: auto; backdrop-filter: blur(2px);
}
.modale[hidden] { display: none; }
.modale-boite {
  background: var(--surface-warm); border-radius: var(--radius); width: 100%;
  max-width: 620px; padding: 20px;
  animation: monte .22s cubic-bezier(.2, .8, .3, 1);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .3);
}
.modale-boite.large { max-width: 980px; }
.modale-titre { font-family: var(--font-display); font-size: 19px; color: var(--forest); margin-bottom: 3px; }
.modale-pied {
  border-top: 1px solid var(--border); margin-top: 14px; padding-top: 14px;
  display: flex; gap: 9px; justify-content: flex-end; flex-wrap: wrap;
}
@keyframes monte { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ── Messages ─────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(160%);
  background: var(--forest); color: var(--white); padding: 13px 20px;
  border-radius: var(--radius); font-size: 14px; font-weight: 500; z-index: 500;
  transition: transform .28s cubic-bezier(.2, .8, .3, 1); max-width: min(92vw, 480px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .28); border-left: 3px solid var(--volt);
}
.toast.visible { transform: translateX(-50%) translateY(0); }
.toast.erreur { border-left-color: var(--danger); }

.encart {
  padding: 12px 14px; border-radius: var(--radius-sm); font-size: 13.5px;
  margin-bottom: 14px; border-left: 3px solid var(--moss); background: var(--ok-bg); color: var(--ok);
}
.encart.warn { background: var(--warn-bg); color: var(--warn); border-left-color: var(--warn); }
.encart.danger { background: var(--danger-bg); color: var(--danger); border-left-color: var(--danger); }
.encart a { color: inherit; font-weight: 600; }

/* ── Divers ───────────────────────────────────────────────── */
.muted { color: var(--stone); font-size: 13px; }
.mono { font-family: var(--font-mono); }
.rangee { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rangee.espace { justify-content: space-between; }
.sep { height: 1px; background: var(--border); margin: 13px 0; }
.vide { text-align: center; padding: 38px 20px; color: var(--stone); font-size: 14px; }
.vide strong { display: block; color: var(--graphite); margin-bottom: 4px; font-size: 15px; }

.avatar {
  width: 34px; height: 34px; border-radius: 50%; background: var(--ok-bg); color: var(--forest);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-weight: 600; font-size: 12px; flex: 0 0 34px;
}
.avatar.grand { width: 54px; height: 54px; flex-basis: 54px; font-size: 18px; }

.jauge { height: 6px; background: var(--border); border-radius: 3px; overflow: hidden; margin-top: 6px; }
.jauge span { display: block; height: 100%; background: var(--moss); }

.liste { list-style: none; margin: 0; padding: 0; }
.liste li { padding: 9px 0; border-bottom: 1px solid var(--border); display: flex; gap: 10px; align-items: center; }
.liste li:last-child { border-bottom: none; }

.zone-depot {
  border: 2px dashed var(--border-strong); border-radius: var(--radius); padding: 26px;
  text-align: center; color: var(--stone); cursor: pointer; background: var(--white);
}
.zone-depot:hover, .zone-depot.survol { border-color: var(--moss); background: var(--ok-bg); color: var(--ok); }

.spinner {
  width: 16px; height: 16px; border: 2px solid var(--sage); border-top-color: transparent;
  border-radius: 50%; animation: tourne .7s linear infinite; display: inline-block;
}
@keyframes tourne { to { transform: rotate(360deg); } }

/* ── Matrice de couverture ────────────────────────────────── */
table.matrice td.cellule { text-align: center; padding: 4px 5px; }
.etat {
  display: inline-flex; align-items: center; justify-content: center; width: 100%;
  padding: 4px 6px; border-radius: var(--radius-sm); min-width: 64px;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
}
.etat.ok, .etat.permanente { background: var(--ok-bg); color: var(--ok); }
.etat.a_prevoir { background: var(--warn-bg); color: var(--warn); }
.etat.urgente { background: #F5E4D8; color: #8A4A12; }
.etat.expiree { background: var(--danger-bg); color: var(--danger); }
.etat.manquante { background: var(--surface-warm); color: var(--stone); }
.etat.sans_objet { background: transparent; color: var(--border-strong); }

/* ── Projection des soldes ────────────────────────────────────
   Trois types de congés côte à côte, quatre mois chacun : douze colonnes de
   chiffres où l'œil se perd. Chaque type porte donc sa couleur — celle qu'il a
   déjà au calendrier —, en fond très clair pour que le rouge d'un solde négatif
   reste le seul accent fort. Un filet sépare les blocs : la teinte seule ne
   suffit pas quand deux types ont des couleurs voisines. */
table.projection th.groupe {
  text-align: center; color: var(--forest); font-size: 10px; padding-bottom: 6px;
}
table.projection .separateur { border-left: 2px solid var(--border-strong); }
table.projection tbody tr:hover td { filter: brightness(.97); }

/* ── Calendrier des absences ──────────────────────────────── */
table.calendrier { border-collapse: collapse; font-size: 11.5px; }
table.calendrier th, table.calendrier td { border: 1px solid var(--border); padding: 0; text-align: center; }
table.calendrier th.jour { width: 27px; padding: 4px 0; font-size: 9px; position: static; }
table.calendrier th.nom, table.calendrier td.nom {
  text-align: left; padding: 6px 10px; min-width: 195px;
  position: sticky; left: 0; background: var(--white); z-index: 3;
}
table.calendrier th.nom { z-index: 4; }
table.calendrier td.case-jour { height: 27px; }
table.calendrier td.we { background: var(--surface-warm); }
table.calendrier td.ferie { background: var(--warn-bg); }
.bande { display: block; width: 100%; height: 25px; }
.bande.attente {
  background-image: repeating-linear-gradient(45deg, transparent, transparent 3px,
    rgba(255, 255, 255, .6) 3px, rgba(255, 255, 255, .6) 6px);
}

/* ── Connexion ────────────────────────────────────────────── */
.connexion { min-height: 100dvh; display: grid; grid-template-columns: 1.1fr 1fr; }
.connexion .visuel {
  background: var(--forest); color: var(--white); padding: 56px;
  display: flex; flex-direction: column; justify-content: center; gap: 20px;
}
.connexion .visuel img { height: 34px; align-self: flex-start; }
.connexion .visuel h1 { font-size: 34px; color: var(--white); line-height: 1.15; margin: 0; }
.connexion .visuel p { color: var(--sage); font-size: 15.5px; line-height: 1.6; max-width: 440px; margin: 0; }
.connexion .visuel ul { color: var(--sage); line-height: 2; padding-left: 20px; margin: 0; font-size: 14.5px; }
.connexion .visuel li::marker { color: var(--volt); }
.connexion .boite { display: flex; align-items: center; justify-content: center; padding: 40px; }
.connexion form { width: 100%; max-width: 350px; }
.connexion form h2 { font-size: 22px; margin-bottom: 4px; }

/* ── Écrans étroits ───────────────────────────────────────── */
@media (max-width: 1100px) {
  .grille4 { grid-template-columns: 1fr 1fr; }
  .grille3 { grid-template-columns: 1fr; }
}
@media (max-width: 800px) {
  main { padding: 14px; }
  /* Les indicateurs gardent deux colonnes : ils sont compacts, et les empiler
     repousserait le contenu utile sous la ligne de flottaison. */
  .grille2, .grille3 { grid-template-columns: 1fr; }
  .grille4 { grid-template-columns: 1fr 1fr; }
  .topbar { padding: 11px 14px; }
  .tab { padding: 12px 13px; font-size: 12.5px; }
  th, td { padding: 8px 7px; font-size: 12.5px; }
  .connexion { grid-template-columns: 1fr; }
  .connexion .visuel { display: none; }
  .entete-vue h1 { font-size: 20px; }
}

/* ── Téléphone ────────────────────────────────────────────────
   Le portail reste un back-office : personne ne saisira une fiche de paie au
   doigt. Mais on consulte une échéance depuis un chantier, on valide un congé
   entre deux rendez-vous — et cela doit marcher sans pincer l'écran.
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 700px) {
  /* La barre passe sur deux lignes : identité, puis actions. Sur une seule,
     « Mon compte » et « Quitter » sortaient de l'écran à 375 px — on ne
     pouvait plus se déconnecter. */
  .topbar { flex-wrap: wrap; gap: 7px 10px; padding: 8px 12px; }
  .topbar .spacer { display: none; }
  .topbar img { height: 22px; }
  .topbar .who { margin-left: auto; }
  /* L'en-tête collant occupe déjà 18 % de la hauteur d'un téléphone. Le profil
     part : il ne change pas d'une minute à l'autre, et « Mon compte » le
     rappelle à qui l'oublie. */
  .topbar .who span { display: none; }
  .topbar-actions { flex: 1 0 100%; }
  /* Trois boutons à se partager la largeur : sans « nowrap » leurs libellés
     se coupaient en deux et la barre gagnait une ligne de plus. */
  .topbar-actions .btn { flex: 1; white-space: nowrap; padding: 8px 6px; font-size: 12px; }

  /* 16 px : en deçà, iOS zoome à chaque prise de focus et ne revient jamais. */
  input, select, textarea { font-size: 16px; }

  /* Les indicateurs restent sur deux colonnes. Empilés, ils repoussaient le
     contenu utile à un écran et demi de défilement. */
  .grille4 { grid-template-columns: 1fr 1fr; gap: 10px; }
  .kpi { padding: 12px 13px; }
  .kpi .v { font-size: 25px; }

  /* Les filtres aussi : quatre champs pleine largeur occupaient 235 px avant
     le premier nom de la liste. */
  .filtres { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 10px; padding: 11px 12px; }
  .filtres .champ, .filtres .champ.large { min-width: 0; }
  .filtres .champ.large { grid-column: 1 / -1; }
  /* Quatre champs dépliés occupaient 235 px avant le premier nom de la liste,
     sur un écran qui en fait 812. La recherche reste visible, le reste se
     replie — c'est le filtre qu'on utilise neuf fois sur dix. */
  /* Le `details` reste un bloc : lui donner `display: grid` fait échapper ses
     champs du repli — ils se dessinaient sous la boîte, par-dessus la liste.
     La grille va donc dans un conteneur interne. */
  .filtres-repli { display: block; grid-column: 1 / -1; }
  .filtres-repli-corps { display: grid; }
  .filtres-repli-corps { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 10px; margin-top: 9px; }
  .filtres-repli > summary {
    display: block; cursor: pointer; list-style: none;
    font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .8px;
    text-transform: uppercase; color: var(--stone); padding: 3px 0;
  }
  .filtres-repli > summary::-webkit-details-marker { display: none; }
  .filtres-repli > summary::after { content: ' ▾'; }
  .filtres-repli[open] > summary::after { content: ' ▴'; }

  /* Cibles tactiles : 31 px de haut se rate une fois sur trois. */
  .btn { min-height: 42px; }
  .btn-sm { min-height: 36px; padding: 8px 12px; }

  /* Fenêtres en plein écran : 40 px de marge autour d'un formulaire sur un
     écran de 375 px, cela fait un formulaire de 295 px. */
  .modale { padding: 0; align-items: stretch; }
  .modale-boite, .modale-boite.large {
    max-width: none; border-radius: 0; min-height: 100dvh; padding: 16px 14px 22px;
  }
  .modale-pied { position: sticky; bottom: 0; background: var(--surface-warm); padding-bottom: 6px; }
  .modale-pied .btn { flex: 1 1 auto; }

  /* Le calendrier garde son défilement, mais la colonne des noms prenait la
     moitié de la largeur : il ne restait que six jours à l'écran. */
  .connexion .boite { padding: 26px 20px; }

  table.calendrier th.nom, table.calendrier td.nom { min-width: 112px; padding: 6px 8px; font-size: 11px; }
  table.calendrier th.jour { width: 22px; }

  /* ── Tableaux repliés en fiches ──────────────────────────────
     Huit colonnes ne rentrent pas dans 375 px. Le conteneur défilait bien,
     mais on perdait la colonne des noms au deuxième glissement : on lisait
     des chiffres sans savoir de qui. Chaque ligne devient donc une fiche, et
     chaque valeur emporte l'intitulé de sa colonne (data-col, posé par
     etiqueterTableau dans app.js). */
  table.tableau-fiches { display: block; }
  table.tableau-fiches thead { display: none; }
  table.tableau-fiches tbody { display: block; }
  table.tableau-fiches tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0 9px;
    padding: 10px 12px; border-bottom: 1px solid var(--border); line-height: 1.4;
  }
  table.tableau-fiches tbody tr:last-child { border-bottom: none; }
  table.tableau-fiches td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    flex: 1 1 100%; padding: 2px 0; border: none; text-align: left;
  }
  table.tableau-fiches td::before {
    content: attr(data-col); flex: 0 0 auto;
    font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .8px;
    text-transform: uppercase; color: var(--stone); white-space: nowrap;
  }
  /* Les cellules du premier groupe forment le titre de la fiche : pas
     d'intitulé, et elles restent côte à côte (l'avatar puis le nom). */
  table.tableau-fiches td.entete { flex: 0 0 auto; padding: 0 0 3px; }
  table.tableau-fiches td.entete + td.entete { flex: 1 1 auto; min-width: 0; }
  table.tableau-fiches td.entete::before { content: none; }
  table.tableau-fiches td.num { font-family: var(--font-body); }
  table.tableau-fiches td.num > * { font-family: var(--font-mono); }
  /* Sans en-tête à afficher, une cellule vide n'est plus qu'un blanc. */
  table.tableau-fiches td[data-col=""]:empty { display: none; }
  /* Une cellule de saisie s'aligne sur le haut : la ligne de base placerait le
     champ à cheval sur l'intitulé. */
  table.tableau-fiches td:has(.cellule-prime),
  table.tableau-fiches td:has(.saisie-nombre) { align-items: center; }
  table.tableau-fiches .saisie-nombre { flex: 1 1 auto; }
}

@media print {
  .topbar, .tabs, .entete-vue .actions, .btn { display: none !important; }
  main { padding: 0; max-width: none; }
  .card { border: none; padding: 0; }
}
