/* Chrome partagé pl-* — commun aux pages /planning/ ET /tasks/.
   Navbar, modale, récurrence, boutons, flash… chargé par
   lib/planning/render.php et lib/tasks/render.php AVANT le CSS propre à
   chaque page (tasks-page.css). Utilise EXCLUSIVEMENT les tokens --ba-*
   déclarés dans badgeuse-app.css (chargé avant ce fichier). Aucun
   hardcoding de couleur. */

/* Body BLEU comme les autres pages (badgeuse-app.css : html,body{background:--ba-primary}).
   En PWA viewport-fit=cover, le <body> descend sous l'encoche (caméra frontale) : c'est
   SON fond qui colore la safe-area. Le gris du contenu vit donc sur .pl-app (pleine
   largeur, sous la navbar), pas sur le body — sinon la safe-area redevient grise. */
.pl-body{background:var(--ba-primary);color:var(--ba-text-strong);margin:0}
/* margin-top compensatoire : la navbar étant position:fixed (hors flux), le
   contenu démarrerait sous elle. On le décale de la hauteur navbar (80px) + la
   safe-area du haut, exactement ce que la navbar occupe. Total page inchangé :
   margin-top + min-height = 100dvh. */
.pl-app{background:var(--ba-bg-subtle);padding:0 0 64px;
  margin-top:calc(80px + env(safe-area-inset-top));
  min-height:calc(100vh - 80px - env(safe-area-inset-top));
  min-height:calc(100dvh - 80px - env(safe-area-inset-top))}

/* Navbar — alignée 1:1 sur la navbar badgeuse (index-page.css). La BARRE fait 80px
   = hauteur réelle de la navbar UIkit de l'index (.uk-navbar-nav>li>a a min-height:80px,
   non overridé). La boîte wordmark 520x70 desktop / 360x58 mobile est centrée dedans,
   exactement comme .navbar-title (70/58px) l'est dans l'ancre 80px de l'index. Même
   object-fit contain + transform pour que "le planning" tombe au MÊME NIVEAU que
   "la badgeuse". (Avant : barre 70/58px → 10px/22px plus courte que l'index.) */
/* padding-top safe-area : le bleu remonte dans l'encoche (caméra frontale iPhone),
   comme la navbar standard (.app-navbar-shell .uk-navbar-container). box-sizing
   content-box explicite : la barre garde ses 80px visibles + l'inset au-dessus. */
/* position:fixed : la barre reste collée en haut du viewport pendant le scroll
   (mobile ET desktop). On NE peut PAS utiliser position:sticky ici : badgeuse-app.css
   pose `html,body{overflow-x:hidden}`, ce qui force overflow-y à `auto` et fait du
   <body> un conteneur de défilement — sticky se collerait alors au body (qui ne
   défile pas, c'est le viewport qui scrolle) et la navbar suivrait le contenu.
   fixed est immunisé contre l'overflow des ancêtres. .pl-app porte un margin-top
   compensatoire (= hauteur navbar + safe-area) pour que le contenu démarre dessous.
   La navbar reste le bloc conteneur de .pl-back (position:absolute). */
.pl-navbar{background:var(--ba-primary);height:80px;box-sizing:content-box;
  padding-top:env(safe-area-inset-top);display:flex;align-items:center;
  justify-content:center;position:fixed;top:0;left:0;right:0;z-index:var(--ba-z-navbar);
  color:var(--ba-bg-white);box-shadow:var(--ba-shadow-soft)}
/* Lockup de marque : pictogramme mini-agenda + wordmark "la badgeuse". Le wordmark
   doit rester EXACTEMENT au même endroit que sur l'index (aucun déplacement du logo
   au passage index <-> planning). Pour ça : un spacer invisible (::after) de la même
   largeur que l'icône est ajouté À DROITE du wordmark. Le lockup [icône|gap|wordmark|
   gap|spacer] est symétrique → le wordmark tombe pile au centre de la navbar, comme
   .navbar-title centré sur l'index. Le wordmark garde sa taille (boîte 70/58px). */
.pl-navbar .pl-wordmark{display:flex;align-items:center;justify-content:center;gap:var(--ba-space-3);
  max-width:calc(100vw - 120px);height:70px;overflow:hidden;line-height:0}
.pl-navbar .pl-brand-icon{flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.pl-navbar .pl-brand-icon svg{width:36px;height:36px;display:block;color:var(--ba-bg-white);
  transform:translateY(1px)}
.pl-navbar .pl-wordmark::after{content:"";flex:0 0 auto;width:36px;height:1px}
.pl-navbar .pl-wordmark-image{flex:0 0 auto;height:100%;width:auto;display:block;
  object-fit:contain;object-position:center;
  transform:translateY(-1px) scale(1.08);transform-origin:center center}

/* Bouton retour : identique à .app-navbar-back-button (badgeuse-app.css) —
   pastille transparente, flèche arrow-left UIkit, opacity .92 + hover. */
.pl-navbar .pl-back{position:absolute;left:max(14px, env(safe-area-inset-left));
  top:calc(env(safe-area-inset-top) + 40px);
  transform:translateY(-50%);width:42px;height:42px;padding:0;border:0;border-radius:var(--ba-radius-pill);
  background:transparent;color:var(--ba-bg-white);text-decoration:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;opacity:.92;
  transition:opacity .18s ease, filter .18s ease, transform .18s ease}
.pl-navbar .pl-back:hover{opacity:1;color:var(--ba-bg-white);
  filter:drop-shadow(0 6px 12px rgba(0,0,0,.24));transform:translateY(-50%) scale(1.06)}
.pl-navbar .pl-back:focus-visible{opacity:1;color:var(--ba-bg-white);outline:2px solid rgba(255,255,255,.86);
  outline-offset:3px;filter:drop-shadow(0 6px 12px rgba(0,0,0,.24));transform:translateY(-50%) scale(1.06)}
.pl-navbar .pl-back svg{width:20px;height:20px;display:block}

/* Bascules rapides à droite, en miroir de .pl-back : cluster de pictogrammes
   vers les autres modules du salarié — check-list = Tâches, agenda = Le Planning,
   livre = Historique, engrenage = Administration. Pictogrammes repris à
   l'identique de la page de badge (index.php). Jusqu'à deux icônes côte à côte
   (module + historique/admin) tenues par un conteneur flex absolu ; les liens
   sont donc en flux (pas de position:absolute individuelle). */
.pl-navbar .pl-navquick{position:absolute;right:max(8px, env(safe-area-inset-right));
  top:calc(env(safe-area-inset-top) + 40px);transform:translateY(-50%);
  display:flex;align-items:center;gap:2px}
.pl-navbar .pl-history,
.pl-navbar .pl-admin,
.pl-navbar .pl-planning,
.pl-navbar .pl-tasks{width:40px;height:42px;padding:0;border:0;border-radius:var(--ba-radius-pill);
  background:transparent;color:var(--ba-bg-white);text-decoration:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;opacity:.92;
  transition:opacity .18s ease, filter .18s ease, transform .18s ease}
.pl-navbar .pl-history:hover,
.pl-navbar .pl-admin:hover,
.pl-navbar .pl-planning:hover,
.pl-navbar .pl-tasks:hover{opacity:1;color:var(--ba-bg-white);
  filter:drop-shadow(0 6px 12px rgba(0,0,0,.24));transform:scale(1.06)}
.pl-navbar .pl-history:focus-visible,
.pl-navbar .pl-admin:focus-visible,
.pl-navbar .pl-planning:focus-visible,
.pl-navbar .pl-tasks:focus-visible{opacity:1;color:var(--ba-bg-white);outline:2px solid rgba(255,255,255,.86);
  outline-offset:3px;filter:drop-shadow(0 6px 12px rgba(0,0,0,.24));transform:scale(1.06)}
.pl-navbar .pl-history svg,
.pl-navbar .pl-admin svg,
.pl-navbar .pl-planning svg,
.pl-navbar .pl-tasks svg{height:23px;width:auto;display:block}

@media (max-width: 640px){
  /* La barre reste à 80px (l'index ne réduit pas : UIkit garde min-height:80px en mobile) ;
     seule la boîte wordmark passe à 58px, centrée — comme .navbar-title de l'index. */
  .pl-navbar .pl-wordmark{gap:11px;max-width:calc(100vw - 96px);height:58px}
  .pl-navbar .pl-brand-icon svg{width:30px;height:30px}
  .pl-navbar .pl-wordmark::after{width:30px}
  .pl-navbar .pl-wordmark-image{transform:translateY(-1px) scale(1.06)}
}

/* Centrage du contenu déplacé de .pl-app vers .pl-wrap (.pl-app est désormais
   pleine largeur pour porter le fond gris jusqu'aux bords). Rendu identique. */
/* padding-top compensatoire : la barre d'outils d'édition (.pl-toolbar--edit) est
   épinglée en position:fixed (hors flux) ; --pl-toolbar-offset (posé en JS = sa
   hauteur réelle, qui varie au wrap mobile) pousse la grille sous la barre. Vaut
   0 hors vue d'édition (variable absente -> repli). */
.pl-wrap{max-width:1280px;margin:0 auto;padding:calc(22px + var(--pl-toolbar-offset,0px)) 16px 22px}
.pl-phone .pl-wrap{max-width:480px}
.pl-h{font-size:var(--ba-font-4xl);font-weight:800;margin:0 0 2px}
.pl-sub{color:var(--ba-text-muted);font-size:var(--ba-font-base);margin:0 0 18px}

.pl-card{background:var(--ba-surface);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-card);box-shadow:var(--ba-shadow-card);padding:20px;margin:0 0 18px}
.pl-card h2{font-size:var(--ba-font-xl);margin:0 0 4px}
.pl-row{display:flex;align-items:center;justify-content:space-between;gap:var(--ba-space-3)}

.pl-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}
.pl-weekpick{display:flex;align-items:center;gap:8px;background:var(--ba-surface);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-pill);padding:6px 8px;margin-left:auto}
.pl-weekpick a{width:32px;height:32px;border-radius:50%;border:1px solid var(--ba-border);
  background:var(--ba-surface);color:var(--ba-primary);font-size:var(--ba-font-xl);text-decoration:none;
  display:flex;align-items:center;justify-content:center}
.pl-weekpick .pl-week-label{font-weight:700;font-size:var(--ba-font-base);padding:0 6px}
/* Toolbar d'édition admin (desktop) : 3 enfants (groupe boutons · Dupliquer S-1 ·
   sélecteur de semaine). On neutralise le margin-left:auto du sélecteur pour laisser
   justify-content:space-between répartir l'espace → Dupliquer à équidistance du
   groupe de boutons (gauche) et du sélecteur (droite). Scopé desktop : en mobile,
   le sélecteur reste centré sur sa propre ligne (cf. @media max-width:640px). */
@media (min-width: 641px){
  .pl-toolbar--edit .pl-weekpick{margin-left:0}
}

/* Barre d'outils d'édition épinglée pendant le scroll (mobile ET desktop) : de
   « Pré-réglages » jusqu'au sélecteur « Semaine … ». Même contrainte que la
   navbar (cf. .pl-navbar) : badgeuse-app.css pose `html,body{overflow-x:hidden}`,
   ce qui fait du <body> un conteneur de défilement non défilant -> position:sticky
   se collerait au body et suivrait le contenu. On reprend donc position:fixed,
   calée juste sous la navbar (top = sa hauteur + safe-area, comme le margin-top de
   .pl-app). La barre wrap sur mobile : sa hauteur réelle est mesurée en JS
   (planning-page.js) et reportée en --pl-toolbar-offset, que .pl-wrap ajoute à son
   padding-top pour que la grille démarre dessous. Contenu centré sur 1280 comme
   .pl-wrap via un padding latéral calculé (100% = largeur du viewport, hors
   scrollbar, car left/right:0). */
.pl-toolbar--edit{position:fixed;top:calc(80px + env(safe-area-inset-top));left:0;right:0;
  z-index:calc(var(--ba-z-navbar) - 1);margin:0;
  padding:12px max(16px, calc((100% - 1280px) / 2 + 16px));
  background:var(--ba-bg-subtle);border-bottom:1px solid var(--ba-border);
  box-shadow:var(--ba-shadow-soft)}

/* Stats */
/* Pills */
/* Legal box */
/* Grid */
.pl-scroll{overflow-x:auto}
.pl-grid{width:100%;border-collapse:separate;border-spacing:0;background:var(--ba-surface);
  border:1px solid var(--ba-border);border-radius:var(--ba-radius-card);overflow:hidden;
  box-shadow:var(--ba-shadow-card)}
/* Largeur plancher des colonnes de jours (vue étendue) : sans ça, en layout
   auto, une colonne ne contenant que des présences vierges (texte masqué, donc
   contenu plus étroit) se rétrécit et ses encadrés sont plus étroits que ceux
   des colonnes horodatées du même rang. Un min-width calé sur la largeur
   naturelle d'un créneau horodaté aligne toutes les colonnes sans imposer une
   largeur fixe qui ferait wrapper les horaires (≠ table-layout:fixed). */
.pl-grid:not(.pl-compact) td:not(.pl-emp):not(.pl-colsum),
.pl-grid:not(.pl-compact) thead th:not(.pl-emp):not(.pl-colsum){min-width:104px}
/* Protège la colonne Salarié : sans min-width strict, le min-width des jours lui
   volait de l'espace (nom du salarié replié sur 2 lignes). */
.pl-grid:not(.pl-compact) .pl-emp{min-width:185px}
/* Ordinateur : la grille étendue tient TOUJOURS dans la largeur de l'écran —
   aucune barre de défilement horizontale, le week-end (sam./dim.) et la colonne
   « Semaine » restent visibles sans défiler à droite. table-layout:fixed répartit
   la largeur disponible entre les 7 jours (colonnes égales, ce qui aligne aussi
   les colonnes vierges sans le min-width plancher) ; on neutralise donc les
   min-width plancher qui, sur une fenêtre plus étroite que la grille naturelle
   (~1060px), forçaient le débordement. Salarié/Semaine gardent leur largeur
   préférée (width:185/148) mais peuvent se compresser si la fenêtre l'exige
   (min-width:0). Sous 641px, la vue compacte (pastilles) prend le relais. */
@media (min-width: 641px){
  .pl-grid:not(.pl-compact){table-layout:fixed}
  .pl-grid:not(.pl-compact) td:not(.pl-emp):not(.pl-colsum),
  .pl-grid:not(.pl-compact) thead th:not(.pl-emp):not(.pl-colsum){min-width:0}
  .pl-grid:not(.pl-compact) .pl-emp{min-width:0}
}
.pl-grid th,.pl-grid td{padding:0;text-align:left;vertical-align:top;
  border-bottom:1px solid var(--ba-border-light);border-right:1px solid var(--ba-border-light)}
.pl-grid thead th{background:var(--ba-surface-subtle);font-size:var(--ba-font-xs);color:var(--ba-text-muted);
  font-weight:700;padding:10px 12px;text-align:center}
.pl-grid thead th .pl-dnum{display:block;font-size:var(--ba-font-xl);color:var(--ba-text-strong);font-weight:800}
.pl-grid thead th.pl-today{color:var(--ba-primary)}
.pl-grid thead th.pl-today .pl-dnum{color:var(--ba-primary)}
.pl-grid .pl-emp{width:185px;padding:12px 14px;background:var(--ba-surface);text-align:center}
.pl-emp .pl-nm{font-weight:700;font-size:var(--ba-font-base)}
.pl-emp .pl-rl{font-size:var(--ba-font-xs);color:var(--ba-text-muted)}
.pl-av{display:inline-flex;width:30px;height:30px;border-radius:50%;background:var(--ba-bg-info);
  color:var(--ba-primary);align-items:center;justify-content:center;font-weight:800;font-size:var(--ba-font-xs);margin-right:8px}
.pl-av.pl-admin{background:var(--ba-warning-bg);color:var(--ba-warning-text)}
.pl-cell{min-height:72px;padding:8px}
/* Vue étendue : on centre verticalement l'encadré du créneau dans la case
   (un créneau court ne flotte plus en haut quand la ligne est plus haute).
   Le .pl-dot est display:none ici, donc hors flux flex. Le mode compact
   redéfinit .pl-cell (centrage de la pastille) plus bas. */
.pl-grid:not(.pl-compact) .pl-cell{display:flex;flex-direction:column;justify-content:center}
/* idem pour les colonnes « Salarié » (.pl-emp) et « Semaine » (.pl-colsum) :
   leur contenu (td à contenu direct) est centré verticalement dans la ligne,
   au lieu de coller en haut via le vertical-align:top générique de la grille. */
.pl-grid:not(.pl-compact) .pl-emp,
.pl-grid:not(.pl-compact) .pl-colsum{vertical-align:middle}
.pl-shift{background:var(--ba-bg-info);border:1px solid #cfe0ef;border-left:3px solid var(--ba-primary);
  border-radius:10px;padding:6px 8px;font-size:var(--ba-font-xs);margin-bottom:var(--ba-space-1);text-align:center}
.pl-shift .pl-t{font-weight:800;color:var(--ba-primary-dark)}
.pl-shift .pl-br{color:var(--ba-text-muted);font-size:var(--ba-font-2xs);margin-top:1px}
.pl-shift.pl-done{background:var(--ba-success-bg);border-color:#bfe3cc;border-left-color:var(--ba-success-text)}
.pl-shift.pl-done .pl-t{color:var(--ba-success-text)}
/* Poste affecté à un créneau : étiquette colorée (background/color inline, posés
   au rendu depuis les pré-réglages). Reste visible sur une présence sans horaire
   (où .pl-t/.pl-br sont masqués) : le poste y est l'info utile. */
.pl-pos{display:inline-block;max-width:100%;box-sizing:border-box;
  font-size:var(--ba-font-3xs);font-weight:800;line-height:1.35;
  padding:1px 8px;border-radius:var(--ba-radius-pill);margin-bottom:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.02em}
.pl-day-shift .pl-pos{font-size:var(--ba-font-2xs);padding:2px 9px;margin-bottom:4px}
.pl-empty{color:#aab6c3;font-size:var(--ba-font-2xl);text-align:center;padding:18px 0}
/* Présence sans horaire (mode non compact) : encadré PLEIN de même dimension
   qu'un créneau horodaté, mais VIERGE. On réutilise tel quel le style .pl-shift
   (couleur selon l'état : bleu = à venir, vert .pl-done = jour réalisé) et on
   masque seulement le texte « Prévu / horaires libres » en conservant la hauteur
   des deux lignes (visibility:hidden, pas display:none). En vue compacte, ce sont
   les pastilles .pl-dot qui priment : ce style ne s'y applique pas. */
.pl-grid:not(.pl-compact) .pl-shift--presence .pl-t,
.pl-grid:not(.pl-compact) .pl-shift--presence .pl-br{visibility:hidden;white-space:nowrap}
/* Absence typée (CP, RTT, arrêt…) : pastille pleine à la couleur du type
   (background/color inline, posés au rendu depuis le catalogue fixe de
   lib/planning/absences.php — même pattern que la couleur des postes). PAS un
   créneau éditable : jamais de .pl-shift-edit ni de drag ; côté admin le clic
   ouvre la modale pl-absence-modal (consultation / suppression). */
.pl-shift--absence{border:none}
.pl-cell-edit .pl-shift--absence{cursor:pointer}
.pl-cell-edit .pl-shift--absence:hover{filter:brightness(.94)}
.pl-shift--absence .pl-abs-abbr{font-weight:800;font-size:var(--ba-font-sm);letter-spacing:.04em;line-height:1.3}
.pl-shift--absence .pl-abs-label{font-size:var(--ba-font-3xs);opacity:.9;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pl-grid:not(.pl-compact) .pl-cell-multi .pl-shift--absence .pl-abs-label{display:none}
/* Modale absence : puces de choix du type (radio-like, couleur du type inline).
   Sélection SANS AMBIGUÏTÉ : coche « ✓ » + anneau primaire + pleine opacité —
   les puces non retenues restent estompées. */
.pl-abs-types{display:flex;flex-wrap:wrap;gap:8px;margin:6px 0 14px}
.pl-abs-type{border:2px solid transparent;border-radius:var(--ba-radius-pill);
  font-size:var(--ba-font-xs);font-weight:700;padding:6px 12px;cursor:pointer;opacity:.5}
.pl-abs-type:hover{opacity:.85}
.pl-abs-type.is-selected{opacity:1;border-color:var(--ba-bg-white);
  box-shadow:0 0 0 2px var(--ba-primary-dark)}
.pl-abs-type.is-selected::before{content:"✓ ";font-weight:800}
/* CTA « Poser une absence » des modales créneau (création + édition) : bouton
   pleine largeur en teinte warning, repérable au premier regard. */
.pl-absence-cta{display:block;width:100%;box-sizing:border-box;margin:-2px 0 14px;
  padding:9px 12px;border:1px solid var(--ba-warning-text);border-radius:var(--ba-radius-control);
  background:var(--ba-warning-bg);color:var(--ba-warning-text);
  font-size:var(--ba-font-sm);font-weight:700;cursor:pointer;text-align:center}
.pl-absence-cta:hover{filter:brightness(.97)}
/* Appui long mobile (menu contextuel) : pas de sélection de texte ni de
   callout iOS pendant la pression sur une case. */
.pl-cell-edit{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
/* Case « pleine » (>= 2 créneaux), vue étendue : on condense chaque créneau à
   « poste + horaires seuls » pour que 2-3 bandeaux tiennent sans gonfler la case.
   La ligne détail pause·net (.pl-br) est masquée (le détail complet reste visible
   à l'édition du créneau). Empilement depuis le haut (liste) plutôt que centré.
   La classe est posée au rendu (render.php) et resynchronisée côté client après
   les mutations AJAX (planning-page.js : syncCellMulti). Ne s'applique pas en vue
   compacte (pastilles), qui montre 1 seul voyant par jour. */
.pl-grid:not(.pl-compact) .pl-cell-multi{justify-content:flex-start;gap:4px}
.pl-grid:not(.pl-compact) .pl-cell-multi .pl-shift{margin-bottom:0;padding:4px 8px}
.pl-grid:not(.pl-compact) .pl-cell-multi .pl-shift .pl-br{display:none}
.pl-grid:not(.pl-compact) .pl-cell-multi .pl-shift .pl-t{font-size:var(--ba-font-2xs);white-space:nowrap}
.pl-grid:not(.pl-compact) .pl-cell-multi .pl-pos{margin-bottom:1px}
.pl-colsum{width:148px;background:var(--ba-surface-subtle)}
.pl-colsum .pl-box{padding:8px 12px}
.pl-colsum .pl-line{display:flex;justify-content:space-between;font-size:var(--ba-font-xs);padding:2px 0}
.pl-colsum .pl-line .pl-lab{color:var(--ba-text-muted)}
.pl-colsum .pl-line .pl-val{font-weight:700}
.pl-colsum .pl-line.pl-sup .pl-val{color:var(--ba-warning-text)}

/* List rows (employee) */
.pl-muted{color:var(--ba-text-muted)}
.pl-legend{font-size:var(--ba-font-xs);color:var(--ba-text-muted);margin-top:12px}

/* Gate */
.pl-gate{max-width:420px;margin:60px auto;text-align:center;padding:0 16px}
.pl-gate .pl-card{padding:28px}
.pl-btn{display:inline-flex;align-items:center;gap:8px;border-radius:var(--ba-radius-control);
  font-weight:700;font-size:var(--ba-font-base);padding:12px 20px;cursor:pointer;text-decoration:none;
  background:var(--ba-primary);border:1px solid var(--ba-primary);color:var(--ba-bg-white)}
.pl-btn:hover{background:var(--ba-primary-dark)}

/* ---- Édition de créneaux (grille admin) ---- */
.pl-flash{background:var(--ba-success-bg);color:var(--ba-success-text);border:1px solid #bfe3cc;
  border-radius:var(--ba-radius-panel);padding:10px 14px;font-size:var(--ba-font-sm);font-weight:600;margin-bottom:var(--ba-space-3)}
.pl-cell-edit{cursor:pointer;transition:background .12s}
.pl-cell-edit:hover{background:var(--ba-surface-subtle)}
.pl-cell-edit:focus{outline:2px solid var(--ba-primary);outline-offset:-2px}
.pl-emp-edit{cursor:pointer;transition:background .12s}
.pl-emp-edit:hover{background:var(--ba-surface-subtle)}
.pl-emp-edit:focus{outline:2px solid var(--ba-primary);outline-offset:-2px}
.pl-shift-edit{cursor:pointer}
.pl-shift-edit:hover{filter:brightness(.97)}
/* Glisser-déposer d'un créneau (vue étendue uniquement) : poignée de saisie sur
   un créneau déplaçable (ponctuel), case-cible mise en évidence au survol pendant
   le glisser, créneau en cours de déplacement estompé. */
.pl-grid:not(.pl-compact) .pl-shift-edit[draggable="true"]{cursor:grab}
.pl-grid:not(.pl-compact) .pl-shift-edit[draggable="true"]:active{cursor:grabbing}
.pl-shift-dragging{opacity:.4}
.pl-cell-edit.pl-cell-drop{background:var(--ba-bg-info);box-shadow:inset 0 0 0 2px var(--ba-primary)}

/* Menu contextuel (clic droit) : copier un créneau, le coller dans une autre case
   (vue étendue uniquement — cf. planning-page.js). Flotte au-dessus de la grille. */
.pl-ctx{position:fixed;z-index:var(--ba-z-popover);min-width:172px;
  background:var(--ba-surface);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-control);box-shadow:var(--ba-shadow-card);
  padding:5px;display:flex;flex-direction:column;gap:2px}
.pl-ctx[hidden]{display:none}
.pl-ctx-item{appearance:none;-webkit-appearance:none;border:0;background:transparent;
  text-align:left;font:inherit;color:var(--ba-text-strong);padding:9px 12px;
  border-radius:var(--ba-radius-control);cursor:pointer;white-space:nowrap}
.pl-ctx-item:hover,.pl-ctx-item:focus{background:var(--ba-bg-info);outline:none}
.pl-ctx-item[hidden]{display:none}
/* Action destructive (supprimer) : couleur danger + léger trait de séparation
   quand elle suit une autre entrée visible. */
.pl-ctx-danger{color:var(--ba-danger-text)}
.pl-ctx-danger:hover,.pl-ctx-danger:focus{background:var(--ba-danger-bg)}
.pl-ctx-item:not([hidden])~.pl-ctx-danger{margin-top:4px;border-top:1px solid var(--ba-border-light);padding-top:11px}

.pl-modal-bg{position:fixed;inset:0;background:rgba(15,23,42,.5);display:flex;align-items:center;
  justify-content:center;padding:20px;z-index:1000}
.pl-modal-bg[hidden]{display:none}
/* box-sizing:border-box sur la modale et TOUS ses enfants : sans ça, les
   champs en width:100% + padding débordaient à droite (Début/Fin/Pause/Note). */
.pl-modal, .pl-modal *{box-sizing:border-box}
/* overflow-x:hidden : la modale ne scrolle QUE verticalement. Sans ça, sur
   mobile, la grille « Modèles de créneau » (colonnes fixes) débordait et
   autorisait un scroll horizontal gauche/droite parasite. */
.pl-modal{position:relative;background:var(--ba-surface);border-radius:var(--ba-radius-card);box-shadow:0 24px 60px rgba(15,23,42,.3);
  width:100%;max-width:420px;padding:22px;max-height:92vh;overflow-y:auto;overflow-x:hidden}
.pl-modal h3{margin:0 0 16px;padding-right:30px;font-size:17px}
/* Petite croix de fermeture en coin (comme les autres pop-up La Badgeuse).
   position:sticky (et NON absolute) : .pl-modal est le conteneur de scroll
   (overflow-y:auto), donc une croix en absolute défilerait avec le contenu et
   sortirait du cadre quand la modale (ex. Pré-réglages) est plus haute que
   l'écran. En sticky + top:10px, elle reste collée en haut à droite pendant le
   scroll. margin-left:auto la pousse à droite ; margin-bottom:-32px annule sa
   hauteur dans le flux pour que le <h3> (padding-right:30px) reste calé dessous.
   Fond pilule + ombre pour rester lisible au-dessus du contenu qui défile —
   même pattern que .admin-recap-detail-modal .uk-modal-close-default. */
.pl-modal-x{position:sticky;top:10px;z-index:var(--ba-z-notification);
  margin:0 -12px -32px auto;width:32px;height:32px;display:flex;
  align-items:center;justify-content:center;padding:0;border:1px solid var(--ba-border);
  border-radius:50%;background:rgba(255,255,255,.92);color:var(--ba-text-muted);
  cursor:pointer;box-shadow:0 6px 16px rgba(15,23,42,.1);backdrop-filter:blur(6px)}
.pl-modal-x:hover,.pl-modal-x:focus-visible{background:var(--ba-surface-subtle);color:var(--ba-text-strong)}
.pl-modal-x svg{display:block}
.pl-field{display:block;font-size:var(--ba-font-xs);font-weight:700;color:var(--ba-text-muted);margin-bottom:var(--ba-space-3)}
/* font-size:var(--ba-font-xl) (et pas 14px) sur les champs : en dessous de 16px, Safari iOS
   zoome automatiquement sur le champ au focus — ce qui donnait l'effet « zoom »
   à l'ouverture du pop-up (le champ Début est focus auto). Même parade que les
   modales admin (admin-page.css). */
/* min-width:0 : input[type=time]/[number] ont une largeur intrinsèque minimale
   élevée (widget natif heure + flèches du spinner). Sans ça, dans une grille
   .pl-field-2/.pl-field-3, la piste refuse de rétrécir sous cette largeur et le
   champ déborde à droite de l'encadré (Début/Fin par défaut). Même parade que
   .pl-tpl-row input. Couplé aux pistes minmax(0,1fr) ci-dessous. */
.pl-field input,.pl-field select{display:block;width:100%;min-width:0;margin-top:5px;padding:10px 12px;
  border:1px solid var(--ba-border);border-radius:var(--ba-radius-control);font-size:var(--ba-font-xl);
  background:var(--ba-surface);color:var(--ba-text-strong);font-weight:600}
/* -webkit-appearance:none : sur iOS Safari, le widget natif heure/spinner garde
   une largeur intrinsèque que min-width:0 ne contraint PAS (ça marche en
   émulation Chrome, mais sur un vrai iPhone l'encadré Début/Fin déborde à droite
   de la grille .pl-field-2). Le neutraliser fait respecter width:100% +
   box-sizing ; le picker natif reste accessible au tap. SURTOUT pas sur <select>
   (supprimerait la flèche native). */
.pl-field input[type=time],.pl-field input[type=date],.pl-field input[type=number]{
  -webkit-appearance:none;appearance:none}
/* input[type=date] VIDE : sur WebKit/Safari (avec appearance:none), un champ
   date sans valeur n'a aucun nœud texte interne — sa hauteur s'effondre et
   l'encadré « Au (inclus) » paraît plus petit que « Du » tant qu'il est vide
   (modale absence). On réserve la ligne : hauteur mini calquée sur un champ
   rempli (1.4em de texte + 2×10px padding + 2×1px bordure, box-sizing border-box)
   + pseudo-élément WebKit pour caler la valeur à gauche sur iOS. */
.pl-field input[type=date]{min-height:calc(1.4em + 22px)}
.pl-field input[type=date]::-webkit-date-and-time-value{text-align:left;min-height:1.4em}
.pl-field-2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;margin-bottom:var(--ba-space-3)}
.pl-field-2 .pl-field{margin-bottom:0}
/* Libellé de section (même registre que .pl-field, hors <label>). */
.pl-field-label{display:block;font-size:var(--ba-font-xs);font-weight:700;color:var(--ba-text-muted);margin-bottom:8px}
/* Palette pastel d'identité du salarié : pastilles cliquables (radiogroup). */
.pl-swatches{display:flex;flex-wrap:wrap;gap:8px}
.pl-swatch{width:30px;height:30px;border-radius:50%;border:2px solid transparent;
  box-shadow:0 0 0 1px rgba(15,23,42,.12) inset;cursor:pointer;padding:0;
  transition:transform .12s ease,box-shadow .12s ease;outline:none}
.pl-swatch:hover{transform:scale(1.08)}
.pl-swatch:focus-visible{box-shadow:0 0 0 3px var(--ba-primary)}
/* « Aucune » : damier discret (même motif que .pl-flt-swatch--none). */
.pl-swatch--none{background:repeating-linear-gradient(45deg,#e5e9ef,#e5e9ef 4px,#fff 4px,#fff 8px)}
/* Sélection : anneau primaire autour de la pastille. */
.pl-swatch.is-selected{border-color:var(--ba-primary);
  box-shadow:0 0 0 2px #fff inset,0 0 0 1px var(--ba-primary)}
.pl-net{background:var(--ba-bg-info);border-radius:var(--ba-radius-panel);padding:10px 14px;
  font-size:var(--ba-font-sm);display:flex;justify-content:space-between;margin:0 0 14px;font-weight:700}
.pl-net b{color:var(--ba-primary)}
.pl-modal-actions{display:flex;justify-content:center;gap:var(--ba-space-2);margin-top:4px}
.pl-btn-ghost{display:inline-flex;align-items:center;border-radius:var(--ba-radius-control);
  font-weight:700;font-size:var(--ba-font-base);padding:11px 18px;cursor:pointer;border:1px solid transparent;
  background:transparent;color:var(--ba-text-muted)}
.pl-btn-danger{display:inline-flex;align-items:center;border-radius:var(--ba-radius-control);
  font-weight:700;font-size:var(--ba-font-sm);padding:9px 16px;cursor:pointer;border:1px solid var(--ba-danger-bg);
  background:var(--ba-danger-bg);color:var(--ba-danger-text)}

/* ---- Barre d'outils (pré-réglages + dupliquer) ---- */
.pl-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pl-icon-btn{display:inline-flex;align-items:center;gap:var(--ba-space-1);background:var(--ba-surface);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-pill);padding:7px 12px;font-size:var(--ba-font-sm);font-weight:700;color:var(--ba-primary);
  cursor:pointer;text-decoration:none}
.pl-icon-btn:hover{background:var(--ba-surface-subtle)}
.pl-icon-btn svg{display:block}
/* Bouton « Dupliquer S-1 » : action distincte des deux contrôles de réglage
   (Pré-réglages / Filtrer) — chip teinté info pour le démarquer. */
.pl-icon-btn--dup{background:var(--ba-bg-info);border-color:#cfe0ef}
.pl-icon-btn--dup:hover{background:#e2eef8}
/* Groupe d'actions « semaine » (Dupliquer S-1 + Transmettre + Auto) : un seul
   enfant flex de .pl-toolbar pour préserver le justify-content:space-between. */
.pl-actions-group{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* Transmission email : ✈ « Transmettre » (chip teinté info comme Dupliquer) et
   ⏰ « Auto » dont l'état actif est signalé en vert (tokens success). */
.pl-icon-btn--mail{background:var(--ba-bg-info);border-color:#cfe0ef}
.pl-icon-btn--mail:hover{background:#e2eef8}
.pl-icon-btn--auto.is-on{background:var(--ba-success-bg);color:var(--ba-success-text);border-color:var(--ba-success-text)}
.pl-icon-btn--auto.is-on:hover{background:var(--ba-success-bg)}
.pl-btn-soft{display:inline-flex;align-items:center;gap:var(--ba-space-1);background:var(--ba-bg-info);border:1px solid #cfe0ef;
  border-radius:var(--ba-radius-control);padding:8px 14px;font-size:var(--ba-font-sm);font-weight:700;color:var(--ba-primary);
  cursor:pointer;margin-top:8px}
.pl-btn-soft:hover{background:#e2eef8}

/* ---- Filtre d'affichage (popover entonnoir) ---- */
.pl-filter-wrap{position:relative;display:inline-flex}
.pl-icon-btn.is-active{border-color:var(--ba-primary);background:var(--ba-bg-info)}
.pl-filter-dot{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--ba-primary);margin-left:2px}
.pl-filter-dot[hidden]{display:none}
.pl-filter-pop{position:absolute;top:calc(100% + 8px);left:0;z-index:var(--ba-z-popover);
  width:288px;max-width:calc(100vw - 32px);background:var(--ba-surface);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-card);box-shadow:0 18px 44px rgba(15,23,42,.18);padding:16px}
.pl-filter-pop[hidden]{display:none}
.pl-filter-pop, .pl-filter-pop *{box-sizing:border-box}
.pl-filter-pop .pl-field{margin-bottom:12px}
/* Sections du filtre en cases à cocher (Salariés / Jours / Postes). Chaque
   section : un titre + des pré-sélecteurs de groupe, puis la liste cochable. */
.pl-flt-sect{border-top:1px solid var(--ba-border-light);padding-top:12px;margin-top:12px}
.pl-flt-sect:first-of-type{border-top:0;padding-top:0;margin-top:0}
.pl-flt-head{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.pl-flt-title{font-size:var(--ba-font-xs);font-weight:700;color:var(--ba-text-muted)}
.pl-flt-presets{display:flex;flex-wrap:wrap;gap:4px}
.pl-flt-pre{border:1px solid var(--ba-border);background:var(--ba-surface);color:var(--ba-primary);
  font-size:var(--ba-font-2xs);font-weight:700;padding:3px 8px;border-radius:var(--ba-radius-pill);cursor:pointer}
.pl-flt-pre:hover{background:var(--ba-bg-info)}
.pl-flt-find{display:block;width:100%;margin-bottom:8px;padding:8px 10px;font-size:var(--ba-font-sm);
  border:1px solid var(--ba-border);border-radius:var(--ba-radius-control)}
.pl-flt-list{max-height:184px;overflow:auto;border:1px solid var(--ba-border-light);
  border-radius:var(--ba-radius-control);padding:4px}
.pl-flt-item{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:var(--ba-radius-control);
  font-size:var(--ba-font-sm);font-weight:600;color:var(--ba-text-strong);cursor:pointer}
.pl-flt-item:hover{background:var(--ba-surface-subtle)}
.pl-flt-item[hidden]{display:none}
.pl-flt-item input{flex:0 0 auto;margin:0}
.pl-flt-nm{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pl-flt-tag{flex:0 0 auto;font-size:var(--ba-font-2xs);font-weight:700;color:var(--ba-text-muted)}
.pl-flt-hint{font-size:var(--ba-font-xs);color:var(--ba-text-muted);margin:6px 2px 0}
.pl-flt-swatch{flex:0 0 auto;width:13px;height:13px;border-radius:4px;border:1px solid rgba(15,23,42,.12)}
.pl-flt-swatch--none{background:repeating-linear-gradient(45deg,#e5e9ef,#e5e9ef 3px,#fff 3px,#fff 6px)}
.pl-flt-days{display:flex;flex-wrap:wrap;gap:var(--ba-space-1)}
.pl-flt-day{display:inline-flex;align-items:center;gap:var(--ba-space-1);padding:6px 10px;font-size:var(--ba-font-xs);font-weight:700;
  color:var(--ba-text-strong);border:1px solid var(--ba-border);border-radius:var(--ba-radius-pill);cursor:pointer}
.pl-flt-day input{margin:0}
.pl-flt-day--off{color:var(--ba-text-muted);border-style:dashed}
.pl-filter-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--ba-space-2);margin-top:var(--ba-space-3)}
.pl-filter-foot .pl-btn-ghost{padding:7px 10px;font-size:var(--ba-font-sm)}
#pl-filter-count{font-size:var(--ba-font-xs)}
.pl-grid tr[hidden]{display:none}
/* Filtre jour (admin) : colonne masquée (th + td portant data-day). */
.pl-grid .pl-col-hidden{display:none}
/* Filtre poste (admin) : créneau masqué (poste décoché) dans une cellule. */
.pl-grid .pl-shift-hidden{display:none}
.pl-grid .pl-empty-filter td{text-align:center;color:var(--ba-text-muted);padding:22px 12px;font-size:var(--ba-font-sm)}

/* ---- Vue compacte (mobile) : initiales × 7 jours en pastilles ----
   Bascule par #pl-compact-toggle (classe .pl-compact sur la table). Objectif :
   tout le tableau tient dans la largeur de l'écran, sans scroll horizontal, quel
   que soit l'écran (table-layout:fixed -> colonnes jours égales). Chaque jour =
   une pastille (verte = jour passé travaillé, bleue = à venir, contour pointillé
   = rien de prévu). Clic sur une pastille -> modale d'info du jour. */
.pl-dot{display:none;width:18px;height:18px;border-radius:50%;box-sizing:border-box}
.pl-dot--empty{background:transparent;border:1.5px dashed var(--ba-border)}
.pl-dot--done{background:var(--ba-success-text);border:1px solid var(--ba-success-text)}
.pl-dot--planned{background:var(--ba-primary);border:1px solid var(--ba-primary)}
/* Jour d'absence seule : la couleur du TYPE est posée inline au rendu (même
   pattern que les postes) ; ce repli neutre ne sert qu'à un type sans couleur. */
.pl-dot--absence{background:#64748b;border:1px solid #64748b}
.pl-grid.pl-compact{table-layout:fixed}
.pl-grid.pl-compact td,.pl-grid.pl-compact th{vertical-align:middle}
.pl-grid.pl-compact .pl-colsum{display:none}
.pl-grid.pl-compact .pl-emp{width:42px;padding:8px 2px}
.pl-grid.pl-compact .pl-emp .pl-nm,
.pl-grid.pl-compact .pl-emp .pl-rl,
.pl-grid.pl-compact thead .pl-emp-h{display:none}
.pl-grid.pl-compact .pl-av{margin-right:0}
.pl-grid.pl-compact thead th{padding:7px 1px;font-size:var(--ba-font-3xs)}
.pl-grid.pl-compact thead th .pl-dnum{font-size:var(--ba-font-sm)}
.pl-grid.pl-compact .pl-cell{min-height:0;padding:7px 2px;display:flex;align-items:center;justify-content:center}
.pl-grid.pl-compact .pl-cell .pl-shift,
.pl-grid.pl-compact .pl-cell .pl-empty{display:none}
.pl-grid.pl-compact .pl-cell .pl-dot{display:block}

/* Lecture seule (vue salarié) : en compact, la cellule est cliquable pour
   ouvrir le détail du jour ; en grille étendue elle reste inerte. La cellule
   vide n'affiche pas le « + » d'ajout (rien à éditer). */
.pl-grid.pl-compact .pl-cell-read{cursor:pointer}
.pl-cell-read .pl-empty-read{min-height:18px}

/* Modale d'info du jour (clic sur une pastille). Réutilise l'habillage des
   créneaux de la grille pour chaque ligne (.pl-t / .pl-br). */
.pl-day-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}
.pl-day-shift{display:block;width:100%;text-align:left;cursor:pointer;font:inherit;
  background:var(--ba-bg-info);border:1px solid #cfe0ef;border-left:3px solid var(--ba-primary);
  border-radius:10px;padding:10px 12px;color:var(--ba-text-strong)}
.pl-day-shift:hover{filter:brightness(.98)}
.pl-day-shift .pl-t{font-weight:800;font-size:var(--ba-font-base);color:var(--ba-primary-dark)}
.pl-day-shift .pl-br{color:var(--ba-text-muted);font-size:var(--ba-font-xs);margin-top:2px}
.pl-day-shift.pl-done{background:var(--ba-success-bg);border-color:#bfe3cc;border-left-color:var(--ba-success-text)}
.pl-day-shift.pl-done .pl-t{color:var(--ba-success-text)}
/* Variante lecture seule : non cliquable (pas d'édition au clic). */
.pl-day-shift--read{cursor:default}
.pl-day-shift--read:hover{filter:none}
.pl-day-note{display:block;font-style:italic;color:var(--ba-text-muted);font-size:var(--ba-font-xs);margin-top:4px}
.pl-day-empty{color:var(--ba-text-muted);font-size:var(--ba-font-sm);text-align:center;padding:16px 0;margin:0}

/* ---- Interrupteur Semaine / Mois (segmenté à curseur glissant) ----
   Le curseur (.pl-viewswitch-thumb) est une pastille pleine positionnée sous
   l'option active ; au clic, le JS bascule .is-month et la transition CSS le fait
   GLISSER vers l'autre moitié avant la navigation. Au chargement, pas d'animation
   (la transition ne joue qu'au changement de classe). */
.pl-viewswitch{position:relative;display:inline-flex;align-items:stretch;background:var(--ba-surface);
  border:1px solid var(--ba-border);border-radius:var(--ba-radius-pill);padding:2px}
.pl-viewswitch-thumb{position:absolute;top:2px;bottom:2px;left:2px;width:calc(50% - 2px);
  background:var(--ba-primary);border-radius:var(--ba-radius-pill);z-index:0;
  transition:transform .22s cubic-bezier(.4,0,.2,1)}
.pl-viewswitch.is-month .pl-viewswitch-thumb{transform:translateX(100%)}
.pl-viewswitch-opt{position:relative;z-index:1;flex:1 1 0;min-width:68px;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:var(--ba-font-sm);font-weight:700;color:var(--ba-text-muted);text-decoration:none;
  padding:6px 13px;line-height:1;transition:color .18s ease}
.pl-viewswitch-opt.is-active{color:var(--ba-bg-white)}

/* ---- Calendrier mensuel (vue Mois admin) ----
   Grille 7 colonnes (Lun→Dim). Chaque jour du mois est un <button> cliquable
   (gestion des salariés), les jours hors-mois sont grisés et inertes. */
.pl-month{background:var(--ba-surface);border:1px solid var(--ba-border);border-radius:var(--ba-radius-card);
  overflow:hidden;box-shadow:var(--ba-shadow-card)}
.pl-month-head{display:grid;grid-template-columns:repeat(7,1fr);background:var(--ba-surface-subtle)}
.pl-month-head span{padding:8px 6px;text-align:center;font-size:var(--ba-font-xs);font-weight:700;
  color:var(--ba-text-muted);border-right:1px solid var(--ba-border-light)}
.pl-month-head span:last-child{border-right:0}
.pl-month-grid{display:grid;grid-template-columns:repeat(7,1fr)}
.pl-mday{display:flex;flex-direction:column;gap:5px;min-height:96px;padding:var(--ba-space-1);
  text-align:left;font:inherit;color:inherit;background:var(--ba-surface);cursor:pointer;
  border:0;border-right:1px solid var(--ba-border-light);border-bottom:1px solid var(--ba-border-light)}
.pl-mday:nth-child(7n){border-right:0}
button.pl-mday:hover{background:var(--ba-surface-subtle)}
button.pl-mday:focus-visible{outline:2px solid var(--ba-primary);outline-offset:-2px}
.pl-mday--out{background:var(--ba-bg-subtle);cursor:default}
.pl-mday-num{align-self:flex-end;font-size:var(--ba-font-sm);font-weight:800;color:var(--ba-text-strong)}
.pl-mday--out .pl-mday-num{color:var(--ba-text-muted);font-weight:600}
.pl-mday--today .pl-mday-num{display:inline-flex;align-items:center;justify-content:center;
  min-width:23px;height:23px;padding:0 5px;background:var(--ba-primary);color:var(--ba-bg-white);border-radius:var(--ba-radius-pill)}
.pl-mday-people{display:flex;flex-wrap:wrap;gap:3px;align-content:flex-start}
.pl-mday-av{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;
  border-radius:50%;background:var(--ba-bg-info);color:var(--ba-primary);font-size:var(--ba-font-3xs);font-weight:800}
.pl-mday-av.pl-admin{background:var(--ba-warning-bg);color:var(--ba-warning-text)}
.pl-mday-more{display:inline-flex;align-items:center;font-size:var(--ba-font-2xs);font-weight:800;
  color:var(--ba-text-muted);padding:0 3px}
/* Filtre Salariés en vue Mois : avatar d'un salarié décoché masqué. */
.pl-mday-av.pl-av-hidden{display:none}
/* Bouton « Condensé » désactivé (vue Mois : rien à compacter). */
.pl-icon-btn:disabled,.pl-icon-btn.is-disabled{opacity:.45;cursor:not-allowed}
.pl-icon-btn:disabled:hover,.pl-icon-btn.is-disabled:hover{background:var(--ba-surface)}
@media (max-width: 640px){
  .pl-mday{min-height:62px;gap:3px;padding:4px 3px}
  .pl-mday-num{font-size:var(--ba-font-xs)}
  .pl-mday-av{width:18px;height:18px;font-size:9px}
  .pl-month-head span{padding:6px 2px;font-size:var(--ba-font-2xs)}
}

/* Mobile : les 3 boutons d'outils (Pré-réglages / Filtrer / Dupliquer) centrés
   sur leur propre ligne, sélecteur de semaine centré dessous. Le popover de
   filtre est recentré sous son bouton (qui n'est plus collé à gauche). */
@media (max-width: 640px){
  .pl-toolbar{justify-content:center}
  .pl-tools{width:100%;justify-content:center}
  .pl-weekpick{margin-left:auto;margin-right:auto}
  .pl-filter-pop{left:50%;right:auto;transform:translateX(-50%)}
  /* Mobile : les 3 boutons (Pré-réglages · Filtrer · Condensé) tiennent sur une
     ligne via .pl-tools width:100% ; Dupliquer S-1 (enfant direct de .pl-toolbar)
     passe seul sur la ligne suivante, centré ; le sélecteur de semaine en dessous. */
  #pl-dup-form{width:100%;display:flex;justify-content:center}
  /* Les boutons restants du groupe (Semaines types · Transmettre · Auto) wrappent
     sous Dupliquer S-1 : on les centre au lieu du flex-start par défaut. */
  .pl-actions-group{justify-content:center}
}

/* ---- Modale Réglages (large) ---- */
.pl-modal-lg{max-width:560px}
/* Onglets de la modale Réglages : segmented control, un seul volet visible.
   Les volets masqués (.pl-tabpane[hidden]) gardent leurs champs dans le <form>. */
.pl-tabs{display:flex;gap:4px;background:var(--ba-surface-subtle);border:1px solid var(--ba-border-light);
  border-radius:var(--ba-radius-pill);padding:4px;margin:0 0 16px}
.pl-tab{flex:1 1 0;min-width:0;border:0;background:transparent;border-radius:var(--ba-radius-pill);
  padding:8px 10px;font-size:12.5px;font-weight:700;color:var(--ba-text-muted);cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pl-tab:hover{color:var(--ba-text-strong)}
.pl-tab.is-active{background:var(--ba-surface);color:var(--ba-primary);box-shadow:0 1px 3px rgba(15,23,42,.12)}
.pl-tabpane[hidden]{display:none}

/* Ajout inline (poste / modèle) dans l'éditeur de créneau : un lien révèle une
   mini-ligne de saisie, persistée en AJAX sans ouvrir les Réglages. */
.pl-inline-add{margin:-6px 0 14px}
.pl-inline-link{border:0;background:transparent;padding:0;font-size:12.5px;font-weight:700;
  color:var(--ba-primary);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.pl-inline-link:hover{opacity:.8}
.pl-inline-link[hidden]{display:none}
.pl-inline-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pl-inline-row[hidden]{display:none}
.pl-inline-input{flex:1 1 140px;min-width:0;padding:8px;border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-control);font-size:var(--ba-font-sm);background:var(--ba-surface);color:var(--ba-text-strong);font-weight:600}
.pl-inline-color{flex:0 0 40px;width:40px;height:36px;padding:2px;cursor:pointer;
  border:1px solid var(--ba-border);border-radius:var(--ba-radius-control);background:var(--ba-surface)}
.pl-inline-row .pl-btn-soft{margin-top:0}
.pl-inline-x{flex:0 0 auto;width:28px;height:28px;border:0;border-radius:50%;
  background:var(--ba-danger-bg);color:var(--ba-danger-text);font-size:var(--ba-font-xl);line-height:1;cursor:pointer}
.pl-inline-msg{display:block;margin-top:var(--ba-space-1);font-size:11.5px;font-weight:700}
.pl-inline-msg[hidden]{display:none}
.pl-inline-msg.is-err{color:var(--ba-danger-text)}
.pl-inline-msg.is-ok{color:var(--ba-success-text)}

/* Multi-site : lignes de sites (Réglages > Modèles, postes & sites) */
.pl-site-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:7px 0;border-bottom:1px dashed var(--ba-border-light)}
.pl-site-row:last-child{border-bottom:0}
.pl-site-row__dot{width:10px;height:10px;border-radius:50%;flex:0 0 auto;background:var(--ba-border)}
.pl-site-row__name{font-weight:700;color:var(--ba-text-strong)}
.pl-site-row__form{width:100%}
.pl-site-badge{font-size:var(--ba-font-3xs);font-weight:800;text-transform:uppercase;letter-spacing:.04em;
  color:var(--ba-primary);border:1px solid currentColor;border-radius:var(--ba-radius-pill);padding:0 7px}
.pl-site-state{font-size:var(--ba-font-2xs);font-weight:700;color:var(--ba-text-muted)}
.pl-site-state--ok{color:var(--ba-success-text)}
.pl-site-state--warn{color:var(--ba-warning-text)}
.pl-site-row__edit{margin-left:auto}
.pl-sect{border-top:1px solid var(--ba-border-light);padding-top:var(--ba-space-3);margin-top:var(--ba-space-3)}
.pl-sect:first-of-type{border-top:0;padding-top:0;margin-top:0}
.pl-sect-h{font-size:var(--ba-font-sm);font-weight:800;color:var(--ba-text-strong);margin-bottom:12px}
.pl-field-3{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,1fr);gap:12px;margin-bottom:var(--ba-space-3)}
.pl-field-3 .pl-field{margin-bottom:0}

/* Jours travaillés */
.pl-days{display:flex;flex-wrap:wrap;gap:var(--ba-space-1);margin-bottom:var(--ba-space-1)}
.pl-day{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-pill);padding:5px 11px;font-size:var(--ba-font-xs);font-weight:700;
  color:var(--ba-text-muted);cursor:pointer;background:var(--ba-surface)}
.pl-day input{margin:0}
.pl-day:has(input:checked){background:var(--ba-bg-info);border-color:#cfe0ef;color:var(--ba-primary)}

/* Modèles de créneau */
.pl-tpl-head,.pl-tpl-row{display:grid;grid-template-columns:1fr 86px 86px 74px 28px;gap:8px;align-items:center}
.pl-tpl-head{font-size:var(--ba-font-2xs);color:var(--ba-text-muted);font-weight:700;margin-bottom:var(--ba-space-1);padding:0 2px}
.pl-tpl-row{margin-bottom:8px}
/* min-width:0 : autorise les inputs à rétrécir sous leur largeur intrinsèque
   pour que la ligne tienne dans la modale sur petit écran (pas de scroll H). */
.pl-tpl-row input{width:100%;min-width:0;padding:8px;border:1px solid var(--ba-border);border-radius:var(--ba-radius-control);
  font-size:var(--ba-font-sm);background:var(--ba-surface);color:var(--ba-text-strong);font-weight:600}
.pl-tpl-del{width:28px;height:28px;border:0;border-radius:50%;background:var(--ba-danger-bg);
  color:var(--ba-danger-text);font-size:var(--ba-font-xl);line-height:1;cursor:pointer}
.pl-tpl-del:hover{filter:brightness(.95)}

/* Postes affectables (libellé + couleur) */
.pl-pos-head,.pl-pos-row{display:grid;grid-template-columns:1fr 52px 28px;gap:8px;align-items:center}
.pl-pos-head{font-size:var(--ba-font-2xs);color:var(--ba-text-muted);font-weight:700;margin-bottom:var(--ba-space-1);padding:0 2px}
.pl-pos-row{margin-bottom:8px}
.pl-pos-row input[type=text]{width:100%;min-width:0;padding:8px;border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-control);font-size:var(--ba-font-sm);background:var(--ba-surface);color:var(--ba-text-strong);font-weight:600}
/* input[type=color] : swatch carré aligné sur la hauteur des autres champs. */
.pl-pos-row input[type=color]{width:100%;min-width:0;height:36px;padding:2px;cursor:pointer;
  border:1px solid var(--ba-border);border-radius:var(--ba-radius-control);background:var(--ba-surface)}
.pl-pos-del{width:28px;height:28px;border:0;border-radius:50%;background:var(--ba-danger-bg);
  color:var(--ba-danger-text);font-size:var(--ba-font-xl);line-height:1;cursor:pointer}
.pl-pos-del:hover{filter:brightness(.95)}

/* ---- Publication progressive du planning ---- */
.pl-check{display:flex;align-items:flex-start;gap:9px;font-size:var(--ba-font-sm);font-weight:600;
  color:var(--ba-text-strong);line-height:1.4;cursor:pointer}
.pl-check input{margin:2px 0 0;flex:0 0 auto}
/* Champ « semaines à l'avance » grisé/verrouillé quand la publication est OFF.
   Classe .is-off posée par planning-page.js ; le sélecteur :has assure un repli
   purement CSS si JS est absent (même pattern que .pl-day:has(input:checked)). */
.pl-reveal-field.is-off,
.pl-sect:has(#pl-reveal-toggle:not(:checked)) .pl-reveal-field{opacity:.5}
.pl-reveal-field.is-off input,
.pl-sect:has(#pl-reveal-toggle:not(:checked)) .pl-reveal-field input{cursor:not-allowed}
/* Visibilité par salarié (« Qui est visible par les collègues ») : liste de cases
   en 2 colonnes responsives, chaque ligne reprenant .pl-check. */
.pl-peer-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));
  gap:8px 16px;margin-top:4px}
.pl-peer-row{margin:0;align-items:center}
.pl-peer-tag{display:inline-block;margin-left:var(--ba-space-1);font-size:var(--ba-font-3xs);font-weight:700;
  text-transform:uppercase;letter-spacing:.04em;color:var(--ba-text-muted);
  background:var(--ba-surface-subtle);border:1px solid var(--ba-border-light);
  border-radius:var(--ba-radius-pill);padding:1px 7px;vertical-align:middle}
/* Bandeau admin : statut de publication de la semaine affichée */
.pl-pubbar{display:flex;align-items:center;gap:8px;margin:0 0 12px;padding:9px 14px;
  border-radius:var(--ba-radius-control);font-size:var(--ba-font-sm);font-weight:700}
.pl-pubbar-i{flex:0 0 auto;display:block}
.pl-pubbar-on{background:var(--ba-success-bg);color:var(--ba-success-text);border:1px solid var(--ba-success-text)}
.pl-pubbar-off{background:var(--ba-warning-bg);color:var(--ba-warning-text);border:1px solid var(--ba-warning-text)}
/* Carte salarié : semaine pas encore publiée — état « verrouillé » discret. */
/* =====================================================================
   Vue LECTURE salarié — habillage calqué sur history.php (UIkit + cartes
   history-*). N'affecte PAS la grille admin (qui garde la navbar planning).
   Réutilise les tokens --ba-* et les classes pl-* internes (stats, pills,
   items) à l'intérieur des cartes history-panel-card.
   ===================================================================== */

/* Navbar lecture salarié : structure 1:1 avec les autres pages (cf.
   .history-navbar-brand). Pictogramme agenda positionné en absolu à gauche +
   wordmark « la badgeuse » centré dans la barre. Le pictogramme porte l'identité
   « le planning » ; le wordmark reste celui partagé par toute l'app. */
@media (max-width:640px){
          /* Modèles de créneau : colonnes resserrées pour tenir dans la modale étroite
     sans scroll horizontal (cf. overflow-x:hidden sur .pl-modal). */
  .pl-tpl-head,.pl-tpl-row{grid-template-columns:1fr 76px 76px 62px 26px;gap:var(--ba-space-1)}
  .pl-pos-head,.pl-pos-row{grid-template-columns:1fr 46px 26px;gap:var(--ba-space-1)}
}

/* Contenu de période (sous le bloc « Période »). */
/* Synthèse 2 colonnes (vue Jour : Réalisé / Prévu). */
/* Ligne de créneau : colonne droite (durée + pastille) + note optionnelle. */
/* Vue Mois : un bloc par semaine ISO, séparé par un filet. */
/* Semaine non publiée (publication progressive) — version intégrée au flux. */
.planning-read-masked{text-align:center;padding:22px 16px;border:1px dashed var(--ba-border);
  border-radius:var(--ba-radius-panel);background:var(--ba-surface-subtle);color:var(--ba-text-muted)}
.planning-read-masked__ico{color:var(--ba-text-muted);margin-bottom:8px}
.planning-read-masked__ico svg{display:block;margin:0 auto}
.planning-read-masked__title{font-size:var(--ba-font-lg);font-weight:800;color:var(--ba-text-strong);margin-bottom:var(--ba-space-1)}

/* Repli sans JS du mini-agenda. */
/* Tactile : pas de grossissement au tap (le :hover reste collé). Le bouton retour
   garde sa base translateY(-50%) (centrage), on retire seulement le scale. */
@media (hover: none), (pointer: coarse){
  .pl-navbar .pl-back:hover,
  .pl-navbar .pl-back:focus-visible{transform:translateY(-50%)}
  .pl-navbar .pl-history:hover,
  .pl-navbar .pl-history:focus-visible,
  .pl-navbar .pl-admin:hover,
  .pl-navbar .pl-admin:focus-visible,
  .pl-navbar .pl-planning:hover,
  .pl-navbar .pl-planning:focus-visible,
  .pl-navbar .pl-tasks:hover,
  .pl-navbar .pl-tasks:focus-visible{transform:none}
}

/* === Récurrence des créneaux (modale) ====================================== */
.pl-rec-custom{border:1px solid var(--ba-border);border-radius:var(--ba-radius-panel);
  padding:12px;margin:0 0 14px;background:var(--ba-bg-subtle)}
.pl-rec-sub{margin-bottom:12px}
.pl-rec-inline{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--ba-font-sm);
  font-weight:600;color:var(--ba-text-strong);margin-bottom:var(--ba-space-3)}
.pl-rec-num{width:74px;padding:8px 10px;border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-control);font:inherit}
.pl-field input.pl-rec-num{display:inline-block;width:74px;margin-top:0}
.pl-rec-dows{display:flex;flex-wrap:wrap;gap:var(--ba-space-1);margin-bottom:12px}
.pl-rec-dow{display:inline-flex;align-items:center;gap:5px;font-size:var(--ba-font-xs);font-weight:700;
  color:var(--ba-text-strong);background:var(--ba-bg-white);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-pill);padding:5px 10px;cursor:pointer;user-select:none}
.pl-rec-dow input{margin:0}
.pl-rec-months{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--ba-space-1)}
.pl-rec-month{display:inline-flex;align-items:center;gap:5px;font-size:var(--ba-font-xs);
  font-weight:600;color:var(--ba-text-strong)}
.pl-rec-radio{display:flex;align-items:center;flex-wrap:wrap;gap:var(--ba-space-1);font-size:var(--ba-font-sm);
  font-weight:600;color:var(--ba-text-strong);margin-bottom:8px}
.pl-rec-radio input[type=number],.pl-rec-radio input[type=date],.pl-rec-radio select{
  padding:8px 10px;border:1px solid var(--ba-border);border-radius:var(--ba-radius-control);font:inherit}
.pl-rec-end{border-top:1px dashed var(--ba-border);padding-top:var(--ba-space-2);margin-top:4px}
.pl-rec-end-title{font-size:var(--ba-font-xs);font-weight:700;color:var(--ba-text-muted);margin-bottom:8px}
/* Choix de portée d'une série (cet événement / et les suivants / tous) */
.pl-scope-choices{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}
.pl-scope-opt{width:100%;text-align:left}

/* === Semaines types (modèles paires / impaires) ============================ */
.pl-wt-sect{padding:12px 0;border-top:1px solid var(--ba-border)}
.pl-wt-sect:first-of-type{border-top:0;padding-top:0}
.pl-wt-h{font-size:var(--ba-font-xs);font-weight:800;color:var(--ba-text-muted);text-transform:uppercase;
  letter-spacing:.03em;margin-bottom:var(--ba-space-2)}
.pl-wt-mode{display:flex;flex-wrap:wrap;gap:var(--ba-space-3);margin:0 0 12px}
.pl-wt-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--ba-space-1)}
.pl-wt-item{display:flex;align-items:center;justify-content:space-between;gap:var(--ba-space-2);
  background:var(--ba-bg-subtle);border:1px solid var(--ba-border);
  border-radius:var(--ba-radius-control);padding:8px 12px}
.pl-wt-name{font-size:var(--ba-font-sm);font-weight:600;color:var(--ba-text-strong)}
.pl-wt-del{border:0;background:transparent;color:var(--ba-danger-text);font-size:var(--ba-font-3xl);
  line-height:1;cursor:pointer;padding:0 4px;border-radius:var(--ba-radius-control)}
.pl-wt-del:hover{background:var(--ba-danger-bg)}

/* États désactivés des boutons pl-* (P8) — même recette que .pl-icon-btn ;
   le hover est neutralisé sur le fond de base. */
.pl-btn:disabled,.pl-btn-soft:disabled{opacity:.45;cursor:not-allowed}
.pl-btn:disabled:hover{background:var(--ba-primary)}
.pl-btn-soft:disabled:hover{background:var(--ba-bg-info)}

/* Accessibilité : réduction des animations (P8). Le glissement du switch
   semaine/mois devient instantané ; la navigation reste sur un setTimeout
   de 200 ms (planning-page.js), indépendante de la transition. */
@media (prefers-reduced-motion: reduce){
  .pl-navbar .pl-back,.pl-navbar .pl-history,.pl-navbar .pl-admin,
  .pl-navbar .pl-planning,.pl-navbar .pl-task,.pl-cell-edit,.pl-emp-edit,
  .pl-swatch,.pl-viewswitch-thumb,.pl-viewswitch-opt{transition:none}
}
