/* ════════════════════════════════════════════════════════════════
   Base CSS — design tokens, sidebar, topbar, app-loader.
   Partagé entre base.html (layout=narrow) et base_large.html (layout=wide).
   Différences gérées via body[data-layout="narrow"] / "wide".
   ════════════════════════════════════════════════════════════════ */

/* ══ Mouvement ═════════════════════════════════════════════════════
   Règle du noyau : une animation doit PORTER UNE INFORMATION — ce qui a
   changé, où un objet est parti, d'où vient la page, que c'est enregistré.
   Si on peut l'enlever sans que l'utilisateur perde quoi que ce soit, elle
   n'a rien à faire dans un outil qu'on ouvre cinquante fois par jour.

   - Durées et courbes : jetons --dur-1…4, --ease-out, --ease-in (:root).
   - Côté JS : cuma.signaler / cuma.transition / cuma.retirer / cuma.vu
     (static/js/shell.js). Ils respectent tous prefers-reduced-motion.
   - Garde « animations réduites » globale ci-dessous : aucune page n'a à
     la réécrire. Verrouillé par accounts.tests.MouvementTests.           */

/* ── Transitions entre pages (View Transitions inter-documents) ──────
   Chrome/Edge et Safari récents ; ailleurs la navigation reste normale.
   Le cadre (barre latérale, barre du haut / onglets mobiles) est capturé
   à part : il ne bouge pas, seul le contenu change. L'arrivée est réglée
   dans le script du loader des gabarits de base (pageswap/pagereveal). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition { background: var(--bg); }
.sidebar { view-transition-name: cuma-cadre-lateral; }
.topbar  { view-transition-name: cuma-cadre-haut; }
::view-transition-group(cuma-cadre-lateral),
::view-transition-group(cuma-cadre-haut) { animation-duration: var(--dur-2); }
/* Fondu enchaîné, pas fondu croisé : deux écrans de données superposés
   sont illisibles. L'ancien s'efface vite, le nouveau arrive juste après ;
   entre les deux, seul le fond (commun à toutes les pages) reste visible.
   mix-blend-mode normal : les deux courbes diffèrent, le mélange additif
   par défaut (plus-lighter) éclaircirait le fond à mi-course. */
::view-transition-old(root) {
  animation: cuma-page-sort var(--dur-1) var(--ease-in) both;
  mix-blend-mode: normal;
}
::view-transition-new(root) {
  animation: cuma-page-entre var(--dur-3) var(--ease-out) calc(var(--dur-1) / 2) both;
  mix-blend-mode: normal;
}
@keyframes cuma-page-sort  { to   { opacity: 0; } }
@keyframes cuma-page-entre { from { opacity: 0; transform: translateY(6px); } }
/* Retour (bouton Retour de la barre, ou historique du navigateur) :
   le contenu revient par la gauche, comme sur iOS. */
html:active-view-transition-type(retour)::view-transition-old(root) { animation-name: cuma-page-sort-retour; }
html:active-view-transition-type(retour)::view-transition-new(root) { animation-name: cuma-page-entre-retour; }
@keyframes cuma-page-sort-retour  { to   { opacity: 0; transform: translateX(16px); } }
@keyframes cuma-page-entre-retour { from { opacity: 0; transform: translateX(-16px); } }

/* ── Mise à jour sur place (cuma.transition, static/js/shell.js) ─────
   Un filtre, un onglet, une liste rafraîchie : la page ne change pas. Seuls
   les éléments NOMMÉS (view-transition-name, posé par la page le temps de
   la transition) bougent : ceux qui restent glissent à leur nouvelle place,
   ceux qui partent s'effacent, les nouveaux apparaissent. Le reste bascule
   d'un coup — et se signale s'il a changé (cuma.signaler). */
html.vt-maj .sidebar,
html.vt-maj .topbar { view-transition-name: none; }
html.vt-maj::view-transition-old(root),
html.vt-maj::view-transition-new(root) { animation: none; }
html.vt-maj::view-transition-group(*) {
  animation-duration: var(--dur-3);
  animation-timing-function: var(--ease-out);
}
/* Ce qui part s'efface dès le départ (ease-out) : il ne doit pas masquer ce
   qui arrive à sa place, qui n'apparaît qu'après (--dur-1). */
html.vt-maj::view-transition-old(*):only-child { animation: cuma-maj-sort var(--dur-2) var(--ease-out) both; }
html.vt-maj::view-transition-new(*):only-child { animation: cuma-maj-entre var(--dur-3) var(--ease-out) var(--dur-1) both; }
@keyframes cuma-maj-sort  { to   { opacity: 0; transform: scale(.98); } }
@keyframes cuma-maj-entre { from { opacity: 0; transform: translateY(6px); } }

/* ── Changement de thème : révélation circulaire (base.html / base_large.html).
   Portée par la classe html.vt-theme, posée le temps de la transition :
   sans elle, ces règles tueraient aussi les transitions entre pages. */
html.vt-theme .sidebar,
html.vt-theme .topbar { view-transition-name: none; }
html.vt-theme::view-transition-old(root),
html.vt-theme::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.vt-theme::view-transition-old(root) { z-index: 1; }
html.vt-theme::view-transition-new(root) { z-index: 2; }

/* ── Pendant une transition entre pages : pas de second fondu.
   Le fondu anti-FOUC et le loader feraient une deuxième entrée par-dessus
   la transition. Classe posée au départ (pageswap) et à l'arrivée
   (pagereveal) par le script du loader des gabarits de base. */
html.vt-en-cours { opacity: 1 !important; transition: none !important; }
html.vt-en-cours .app-loader,
html.vt-en-cours .app-loader-inner { transition: none !important; animation: none !important; }

/* ── Garde « animations réduites » ───────────────────────────────────
   Réglage système (iOS « Réduire les animations », Windows « Effets
   d'animation »…) : tout mouvement devient instantané, sur toutes les
   pages qui chargent ce fichier. .01ms plutôt que 0 : animationend et
   transitionend partent quand même, et le code qui les attend (repli des
   sections de la barre latérale…) continue de fonctionner. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* ── Écart affiché après un changement de valeur (jauges de cuve…) ── */
.cuma-ecart {
  display: inline-flex; align-items: center; gap: 4px;
  align-self: flex-start; max-width: 100%;   /* dans une colonne flex : la taille du texte */
  padding: 3px 9px; border-radius: var(--rp);
  font-family: var(--f); font-size: .7rem; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  color: var(--ac-txt); background: var(--ac-dim); border: .5px solid var(--ac-brd);
  animation: cuma-ecart-in var(--dur-3) var(--ease-out) both;
}
.cuma-ecart--baisse { color: var(--l2); background: var(--sur2); border-color: var(--sep); }
.cuma-ecart-depuis { font-weight: 500; opacity: .75; }
@keyframes cuma-ecart-in { from { opacity: 0; transform: translateY(4px) scale(.96); } }

/* ── Pastille de cuma.retirer : elle file vers la destination de l'objet ── */
.cuma-fantome {
  position: fixed; z-index: 100000; margin: 0; pointer-events: none;
  display: inline-flex; align-items: center;
  padding: 4px 11px; border-radius: var(--rp);
  font-family: var(--f); font-size: .78rem; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  color: var(--l1); background: var(--sur); border: .5px solid var(--sep);
  box-shadow: var(--sh-hover);
  will-change: transform, opacity;
}

/* ── Messages : ils arrivent, et une réussite se voit d'un coup d'œil ──
   Après un enregistrement, le salarié atterrit sur l'accueil : la coche qui
   se trace dit « c'est enregistré » avant même la lecture du texte. */
.page-content > .base-messages > .alert,
.page-content > .alert { animation: cuma-message-in var(--dur-3) var(--ease-out) both; }
@keyframes cuma-message-in { from { opacity: 0; transform: translateY(-6px); } }
.page-content > .base-messages > .alert-success,
.page-content > .alert-success { position: relative; padding-left: 44px; }
.page-content > .base-messages > .alert-success::before,
.page-content > .alert-success::before {
  content: ''; position: absolute; left: 13px; top: 50%;
  width: 20px; height: 20px; margin-top: -10px; border-radius: 50%;
  background: rgba(110,138,36,.16);
  animation: cuma-coche-rond var(--dur-3) var(--spring) var(--dur-1) both;
}
.page-content > .base-messages > .alert-success::after,
.page-content > .alert-success::after {
  content: ''; position: absolute; left: 17px; top: 50%;
  width: 12px; height: 12px; margin-top: -6px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12.5 9.5 18 20 6'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12.5 9.5 18 20 6'/%3E%3C/svg%3E") center / contain no-repeat;
  animation: cuma-coche var(--dur-4) var(--ease-out) calc(var(--dur-1) * 2) both;
}
@keyframes cuma-coche-rond { from { opacity: 0; transform: scale(.4); } }
@keyframes cuma-coche      { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* ══ App loader ════════════════════════════════════════════════════ */
.app-loader {
  position: fixed; inset: 0; z-index: 99999;
  background: rgba(242,242,247,.30);
  display: flex; align-items: center; justify-content: center;
  opacity: 1; visibility: visible;
  transition: opacity .12s ease, visibility 0s linear;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-loader {
    background: rgba(242,242,247,.18);
    backdrop-filter: blur(8px) saturate(1.2);
    -webkit-backdrop-filter: blur(8px) saturate(1.2);
  }
}
body.loader-hidden .app-loader {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .32s cubic-bezier(.4,0,.2,1), visibility 0s linear .32s;
}
.app-loader-inner {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  animation: al-fade-in .25s ease both;
  transition: opacity .28s cubic-bezier(.4,0,.2,1), transform .32s cubic-bezier(.4,0,.2,1);
}
body.loader-hidden .app-loader-inner { opacity: 0; transform: scale(.92); }
@keyframes al-fade-in { from { opacity: 0; transform: scale(.95); } to { opacity: 1; transform: none; } }
.app-loader-ring { position: relative; width: 64px; height: 64px; }
.app-loader-ring::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(110,138,36,0) 0%, rgba(110,138,36,.85) 75%, #6E8A24 100%);
  -webkit-mask: radial-gradient(closest-side, transparent calc(50% - 2px), #000 calc(50% - 1.5px));
  mask: radial-gradient(closest-side, transparent calc(50% - 2px), #000 calc(50% - 1.5px));
  animation: al-spin .85s linear infinite;
}
@keyframes al-spin { to { transform: rotate(360deg); } }
/* Chargeur masqué : l'anneau s'arrête. Caché (visibility), il tournait encore et forçait une
   mise à jour des calques à chaque image, sur toutes les pages, tant qu'elles restaient ouvertes */
body.loader-hidden .app-loader-ring::before { animation: none; }
.app-loader-logo {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 36px; height: 36px;
  border-radius: 9px;
  background: rgba(255,255,255,.85);
  border: 0.5px solid rgba(0,0,0,.06);
  padding: 5px;
  object-fit: contain;
  box-shadow: 0 2px 8px rgba(0,0,0,.06);
}
.app-loader-text {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", sans-serif;
  font-size: .7rem; font-weight: 600;
  color: rgba(60,60,67,.55);
  letter-spacing: .14em;
  text-transform: uppercase;
}
html[data-theme="dark"] .app-loader { background: rgba(28,28,30,.30); }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html[data-theme="dark"] .app-loader { background: rgba(28,28,30,.18); }
}
html[data-theme="dark"] .app-loader-logo { background: rgba(44,44,46,.9); border-color: rgba(255,255,255,.08); }
html[data-theme="dark"] .app-loader-text { color: rgba(235,235,245,.55); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .app-loader { background: rgba(28,28,30,.30); }
  html:not([data-theme="light"]) .app-loader-logo { background: rgba(44,44,46,.9); border-color: rgba(255,255,255,.08); }
  html:not([data-theme="light"]) .app-loader-text { color: rgba(235,235,245,.55); }
}
@media (prefers-reduced-motion: reduce) {
  .app-loader-ring::before, .app-loader-inner { animation: none !important; }
}

/* ══ Anti-FOUC ═════════════════════════════════════════════════════ */
html { opacity: 0; }
html.loaded { opacity: 1; transition: opacity .18s ease; }

/* ══ Design tokens ═════════════════════════════════════════════════ */
:root {
  --l1:      #1C1C1E;
  /* Texte : contraste WCAG AA (≥ 4,5:1) sur --sur, --sur2 ET --bg, vérifié par
     ContrasteJetonsTests (accounts/test_clarte.py). Relevés le 13/10/2026 :
     --l2 .60 → .82 (3,4 → 6,3:1 sur blanc), --l3 .52 → .74 (2,8 → 5,0:1).
     --l4 (1,4:1) n'est PAS une couleur de texte : séparateurs, traits, puces. */
  --l2:      rgba(60,60,67,.82);
  --l3:      rgba(60,60,67,.74);
  --l4:      rgba(60,60,67,.18);
  --sep:     rgba(0,0,0,.06);
  --bg:      #F2F2F7;
  --sur:     #FFFFFF;
  --sur2:    #F9F9FB;
  /* Accent : #6E8A24 donnait 3,9:1 (texte vert, et texte blanc sur bouton vert).
     #5A7220 : 5,4:1 dans les deux sens, 4,9:1 sur --bg (13/10/2026). */
  --ac:      #5A7220;
  --ac-hover:#4B5F1B;   /* accent foncé (hover/active) — était codé en dur 51× dans 42 fichiers */
  /* Deux accents depuis le 13/10/2026 : --ac est l'accent de FOND (boutons
     pleins, pastilles, barres : texte blanc posé dessus), --ac-txt l'accent de
     TEXTE (liens, chiffres, icônes, contours de focus posés sur une surface).
     En clair ils sont égaux ; en sombre, un seul vert ne pouvait pas servir
     les deux (#6E8A24 : 3,5-4,3:1 en texte, 3,9:1 sous du blanc). */
  --ac-txt:  #5A7220;
  --ac-dim:  rgba(110,138,36,.09);
  --ac-brd:  rgba(110,138,36,.18);
  --sh-ac:   0 2px 10px rgba(110,138,36,.30);  /* ombre teintée accent */
  --red:     #C0392B;
  --red-dim: rgba(192,57,43,.08);
  --red-brd: rgba(192,57,43,.20);
  /* Palette sémantique (était éparpillée en hex divergents) */
  --warn:     #8F5D0E;   /* était #B07314 (4,0:1) : 5,9:1 sur blanc */
  --warn-dim: rgba(200,140,30,.10);
  --warn-brd: rgba(200,140,30,.22);
  --info:     #366BA8;
  --info-dim: rgba(54,107,168,.10);
  --info-brd: rgba(54,107,168,.22);
  --f:       -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
  --r:       16px;
  --r2:      8px;
  --rp:      100px;
  --sh-card: 0 4px 6px -1px rgba(0,0,0,.02), 0 10px 15px -3px rgba(0,0,0,.03);
  --sh-hover:0 0 0 .5px rgba(0,0,0,.08), 0 8px 24px rgba(0,0,0,.08);
  --sidebar-w: 220px;
  --sidebar-c: 62px;
  --topbar-h:  52px;
  --spring:  cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease:    cubic-bezier(0.25, 0.46, 0.45, 0.94);
  /* Mouvement (voir la section « Mouvement » plus haut). Les durées suivent
     les familles déjà présentes dans les gabarits : .12-.15s, .2s, .3s, .6s. */
  --ease-out: cubic-bezier(.22, 1, .36, 1);   /* entrée : arrive vite, se pose */
  --ease-in:  cubic-bezier(.4, 0, 1, 1);      /* sortie : part sans traîner */
  --dur-1:   .12s;  /* micro : survol, appui, couleur */
  --dur-2:   .2s;   /* élément : pastille, onglet, ligne, menu */
  --dur-3:   .3s;   /* surface : panneau, modale, page */
  --dur-4:   .6s;   /* donnée : valeur qui change, jauge */
}

@media (prefers-color-scheme: dark) {
  :root {
    --l1: #FFFFFF;
    --l2: rgba(235,235,245,.60);
    --l3: rgba(235,235,245,.55);
    --l4: rgba(235,235,245,.18);
    --sep: rgba(255,255,255,.07);
    --bg: #000000;
    --sur: #1C1C1E;
    --sur2: #2C2C2E;
    --sh-card: 0 0 0 0.5px rgba(110,138,36,.15), 0 4px 24px rgba(0,0,0,.35);
    --sh-hover:0 0 0 .5px rgba(110,138,36,.20), 0 8px 24px rgba(0,0,0,.40);
    --ac: #5E7A22;       /* fond : blanc dessus 4,9:1 (était #6E8A24, 3,9:1) */
    --ac-hover:#4B5F1B;  /* fond survolé : blanc dessus 7,0:1 (était #84A436, 2,9:1) */
    --ac-txt: #94B43F;   /* texte : 5,9:1 sur --sur2, 7,2:1 sur --sur, 8,9:1 sur --bg */
    --warn: #E6B057;
    --info: #6FA8D8;
  }
}
html[data-theme="dark"] {
  --l1: #FFFFFF;
  --l2: rgba(235,235,245,.60);
  --l3: rgba(235,235,245,.55);
  --l4: rgba(235,235,245,.18);
  --sep: rgba(255,255,255,.07);
  --bg: #000000;
  --sur: #1C1C1E;
  --sur2: #2C2C2E;
  --sh-card: 0 0 0 0.5px rgba(110,138,36,.15), 0 4px 24px rgba(0,0,0,.35);
  --sh-hover:0 0 0 .5px rgba(110,138,36,.20), 0 8px 24px rgba(0,0,0,.40);
  --ac: #5E7A22;
  --ac-hover:#4B5F1B;
  --ac-txt: #94B43F;
  --warn: #E6B057;
  --info: #6FA8D8;
}
html[data-theme="light"] {
  --l1: #1C1C1E;
  --l2: rgba(60,60,67,.82);  /* aligné sur :root (WCAG AA) */
  --l3: rgba(60,60,67,.74);
  --l4: rgba(60,60,67,.18);
  --ac: #5A7220;
  --ac-hover: #4B5F1B;
  --ac-txt: #5A7220;
  --warn: #8F5D0E;
  --sep: rgba(0,0,0,.06);
  --bg: #F2F2F7;
  --sur: #FFFFFF;
  --sur2: #F9F9FB;
  --sh-card:0 4px 6px -1px rgba(0,0,0,.02), 0 10px 15px -3px rgba(0,0,0,.03);
  --sh-hover:0 0 0 .5px rgba(0,0,0,.08), 0 8px 24px rgba(0,0,0,.08);
}

/* ══ Reset ═════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; font-family: var(--f); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body { background: var(--bg); display: flex; min-height: 100dvh; }
a { text-decoration: none; }

/* ══ Sidebar overlay (mobile) ══════════════════════════════════════ */
.sidebar-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,.28);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 999998;
  animation: overlay-in .2s ease both;
}
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
body.sb-open .sidebar-overlay { display: block; }

/* ══ Sidebar ═══════════════════════════════════════════════════════ */
.sidebar {
  position: fixed;
  top: 0; left: 0;
  height: 100dvh;
  width: var(--sidebar-w);
  background: var(--sur);
  border-right: 0.5px solid var(--sep);
  display: flex;
  flex-direction: column;
  z-index: 999999;
  overflow: hidden;
  transition: width .22s var(--ease), transform .22s var(--ease);
}
.sidebar::after {
  content: '';
  position: absolute;
  top: 0; right: 0;
  width: 1px; height: 100%;
  background: linear-gradient(180deg, rgba(255,255,255,.12) 0%, rgba(255,255,255,.04) 50%, rgba(255,255,255,.0) 100%);
  pointer-events: none;
}

.sdb-logo {
  display: flex;
  align-items: center;
  padding: 0 14px;
  height: var(--topbar-h);
  flex-shrink: 0;
  border-bottom: 0.5px solid var(--sep);
  gap: 10px;
  overflow: hidden;
}
.sdb-logo-img {
  width: 28px; height: 28px;
  border-radius: 7px;
  border: 0.5px solid var(--sep);
  object-fit: contain;
  background: var(--ac-dim);
  padding: 3px;
  flex-shrink: 0;
}
.sdb-wordmark {
  font-size: .875rem;
  font-weight: 500;
  color: var(--l1);
  letter-spacing: -.01em;
  white-space: nowrap;
  transition: opacity .18s var(--ease), width .22s var(--ease);
}

.sdb-nav { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 10px 8px; scrollbar-width: none; }
.sdb-nav::-webkit-scrollbar { display: none; }

.sdb-section {
  font-size: 0.6875rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .14em;
  color: var(--l3);
  padding: 16px 8px 6px;
  white-space: nowrap;
  transition: opacity .15s var(--ease);
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  border: none; background: none;
  font-family: var(--f);
  cursor: pointer; user-select: none;
  text-align: left;
}
.sdb-section:hover { color: var(--l3); }
.sdb-chev {
  width: 13px; height: 13px; flex-shrink: 0;
  stroke: var(--l4); fill: none;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .22s var(--ease), opacity .15s var(--ease);
  margin-right: 2px;
}
.sdb-section:not(.sec-open) .sdb-chev { transform: rotate(-90deg); }
.sdb-sec-items { overflow: hidden; transition: height .22s var(--ease); }
body.sb-collapsed:not(.sb-peek) .sdb-sec-items { height: auto !important; }
body.sb-collapsed .sdb-chev { opacity: 0; width: 0; }

.sn-link {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-radius: 9px;
  color: var(--l2);
  font-family: var(--f);
  font-size: .8125rem; font-weight: 400; line-height: 1.3;
  cursor: pointer;
  transition: background .12s, color .12s, transform .18s var(--spring);
  white-space: normal; overflow: hidden;
  position: relative;
}
.sn-label { transition: opacity .15s var(--ease); flex: 1; min-width: 0; word-break: break-word; overflow-wrap: anywhere; }
/* Pastille de messages internes non lus, dans le lien « Mes messages ».
   Repliée avec la barre : en mode collapsed, seul un point reste visible. */
.sn-badge {
  flex: none; min-width: 18px; height: 18px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ac); color: #fff;
  border-radius: 9px;
  font-size: 0.6875rem; font-weight: 700; font-variant-numeric: tabular-nums;
  line-height: 1;
}
/* Fonction en bêta (Vue 3D) : pastille discrète, pas un compteur */
.sn-badge--beta { background: color-mix(in srgb, var(--ac) 14%, transparent); color: var(--ac-txt); font-weight: 700; letter-spacing: .02em; }
body.sb-collapsed:not(.sb-peek) .sn-badge {
  min-width: 7px; width: 7px; height: 7px; padding: 0;
  font-size: 0; border-radius: 50%;
  position: absolute; top: 9px; right: 9px;
}
body.sb-collapsed:not(.sb-peek) .sn-link { position: relative; }
.sn-link:hover { background: rgba(0,0,0,.04); color: var(--l1); text-decoration: none; }
html[data-theme="dark"] .sn-link:hover { background: rgba(255,255,255,.06); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .sn-link:hover { background: rgba(255,255,255,.06); }
}
.sn-link.sn-active { background: var(--ac-dim); color: var(--ac-txt); font-weight: 500; }
.sn-link.sn-active::before {
  content: '';
  position: absolute;
  left: 0; top: 20%; height: 60%;
  width: 2.5px;
  border-radius: var(--rp);
  background: var(--ac);
}
.sn-link.sn-active svg { stroke: var(--ac-txt); }
.sn-child { padding-left: 20px; font-size: .79rem; }

.sdb-version {
  font-size: .6875rem;
  color: var(--l3);
  text-align: center;
  padding: 6px 0 4px;
  transition: opacity .15s var(--ease);
}
body.sb-collapsed .sdb-version { opacity: 0; }

.sn-icon {
  width: 16px; height: 16px;
  flex-shrink: 0;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round; stroke-linejoin: round;
  fill: none;
  transition: stroke .12s;
}

.sdb-footer { flex-shrink: 0; padding: 10px 8px; border-top: 0.5px solid var(--sep); }

/* Bascule de thème (déplacée de la topbar vers la sidebar) */
.sdb-theme {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  margin-bottom: 6px;
  background: transparent;
  border: none;
  border-radius: 10px;
  color: var(--l2);
  cursor: pointer;
  font-family: var(--f);
  font-size: .8125rem;
  font-weight: 500;
  text-align: left;
  transition: background .14s, color .14s;
}
.sdb-theme:hover { background: rgba(0,0,0,.05); color: var(--l1); }
html[data-theme="dark"] .sdb-theme:hover { background: rgba(255,255,255,.06); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .sdb-theme:hover { background: rgba(255,255,255,.06); }
}
.sdb-theme-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;   /* aligné sur .sn-icon (16px) : le soleil/lune s'aligne avec les autres icônes de nav */
  flex-shrink: 0;
  color: var(--l2);
}
.sdb-theme-ico svg { width: 16px; height: 16px; }
.sdb-theme-label { white-space: nowrap; overflow: hidden; }
/* Sidebar repliée (desktop) : icône seule, libellé masqué ; ré-affiché au peek */
body.sb-collapsed .sdb-theme { justify-content: center; padding: 8px; gap: 0; }
body.sb-collapsed .sdb-theme-label { opacity: 0; width: 0; }
body.sb-collapsed.sb-peek .sdb-theme { justify-content: flex-start; padding: 8px 10px; gap: 10px; }
body.sb-collapsed.sb-peek .sdb-theme-label { opacity: 1; width: auto; }
.sdb-user {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-radius: 10px;
  overflow: hidden;
  transition: background .12s;
}
.sdb-user:hover { background: rgba(0,0,0,.04); }
.sdb-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--ac);
  color: #fff;
  font-family: var(--f);
  font-size: .75rem; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.sdb-user-info { flex: 1; min-width: 0; overflow: hidden; transition: opacity .15s var(--ease), width .22s var(--ease); }
.sdb-user-name { display: block; font-size: .8125rem; font-weight: 500; color: var(--l1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sdb-user-role { display: block; font-size: 0.6875rem; color: var(--l3); text-transform: capitalize; white-space: nowrap; }
.sdb-logout {
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 7px;
  color: var(--l3);
  transition: color .12s, background .12s;
  flex-shrink: 0;
}
.sdb-logout:hover { color: var(--red); background: var(--red-dim); }

/* ══ Avatar utilisateur (initiales) — composant global ════════════
   Pastille ronde aux initiales, couleur de marque. À utiliser PARTOUT
   où le nom d'une personne (utilisateur / salarié) est affiché, pour
   rester cohérent avec le tableau de bord admin et les filtres.

   Avatar seul :
     <span class="u-av u-av--sm">{{ personne|initials }}</span>
   Avatar + nom (alignés) :
     <span class="u-person">
       <span class="u-av u-av--sm">{{ p|initials }}</span>
       <span class="u-person-name">{{ p.first_name }} {{ p.last_name }}</span>
     </span>
   ({% load custom_filters %} requis pour le filtre |initials, qui
    accepte aussi bien un utilisateur qu'une chaîne « Prénom Nom ».)        */
.u-av {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; box-sizing: border-box;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--ac); color: #fff;
  font-family: var(--f);
  font-size: .70rem; font-weight: 700; line-height: 1;
  letter-spacing: 0; text-transform: uppercase; white-space: nowrap;
  user-select: none;
}
.u-av--xs { width: 22px; height: 22px; font-size: 0.6875rem; }
.u-av--sm { width: 26px; height: 26px; font-size: 0.6875rem; }
.u-av--md { width: 32px; height: 32px; font-size: .78rem; }
.u-av--lg { width: 40px; height: 40px; font-size: .95rem; }
/* Variante douce (fond pâle) — pour listes très denses / menus de filtre. */
.u-av--soft { background: var(--ac-dim); color: var(--ac-txt); border: .5px solid var(--ac-brd); }
/* Variante « vide » — quand aucune personne n'est rattachée (« — »).      */
.u-av--empty { background: var(--sur2); color: var(--l3); border: .5px solid var(--sep); font-weight: 600; }

.u-person { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.u-person-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* ══ Sidebar collapsed (desktop) ══════════════════════════════════ */
body.sb-collapsed .sidebar { width: var(--sidebar-c); }
body.sb-collapsed .sdb-wordmark { opacity: 0; width: 0; }
body.sb-collapsed .sdb-logo { justify-content: center; padding: 0; gap: 0; }
body.sb-collapsed .sdb-section {
  cursor: default;
  pointer-events: none;
  position: relative;
  padding: 16px 8px 6px;   /* hauteur réservée (idem peek) → pas de décalage des icônes au survol */
  justify-content: center; /* centre le tiret de remplacement */
}
/* Replié : on masque le nom du menu et on met un tiret discret à la place */
body.sb-collapsed .sdb-section > span { display: none; }
body.sb-collapsed .sdb-section::before {
  content: '—';
  color: var(--l3);
  /* Le tiret se centre via justify-content:center du .sdb-section, comme les
     icônes désormais centrées (cf. .sn-link gap:0). Pas de décalage. */
}
body.sb-collapsed .sn-label { opacity: 0; width: 0; overflow: hidden; white-space: nowrap; word-break: normal; overflow-wrap: normal; }
body.sb-collapsed .sdb-user-info { opacity: 0; width: 0; }
body.sb-collapsed .sdb-user { justify-content: center; padding: 8px; gap: 0; }
body.sb-collapsed .sdb-logout { display: none; }
body.sb-collapsed .sn-link { justify-content: center; padding: 8px; gap: 0; }
body.sb-collapsed .sn-link.sn-active::before { display: none; }
body.sb-collapsed .main-wrap { margin-left: var(--sidebar-c); }

/* ══ Sidebar peek (hover overlay quand replié) ════════════════════ */
body.sb-collapsed.sb-peek .sidebar {
  width: var(--sidebar-w);
  box-shadow: 0 12px 40px rgba(0,0,0,.10), 0 4px 14px rgba(0,0,0,.06);
}
body.sb-collapsed.sb-peek .sdb-wordmark   { opacity: 1; width: auto; }
body.sb-collapsed.sb-peek .sdb-logo       { justify-content: flex-start; padding: 0 14px; gap: 10px; }
body.sb-collapsed.sb-peek .sdb-section    { cursor: pointer; pointer-events: auto; opacity: 1; height: auto; padding: 16px 8px 6px; justify-content: space-between; }
body.sb-collapsed.sb-peek .sdb-section > span  { display: inline; }
body.sb-collapsed.sb-peek .sdb-section::before { content: none; }
body.sb-collapsed.sb-peek .sn-label       { opacity: 1; width: auto; }
body.sb-collapsed.sb-peek .sdb-user-info  { opacity: 1; width: auto; }
body.sb-collapsed.sb-peek .sdb-user        { justify-content: flex-start; padding: 8px 10px; gap: 10px; }
body.sb-collapsed.sb-peek .sdb-logout     { display: flex; }
body.sb-collapsed.sb-peek .sn-link        { padding: 8px 10px; justify-content: flex-start; gap: 10px; }
body.sb-collapsed.sb-peek .sn-link.sn-active::before { display: block; }
body.sb-collapsed.sb-peek .sdb-chev       { opacity: 1; width: 13px; }
body.sb-collapsed.sb-peek .sdb-version    { opacity: 1; }
body.sb-collapsed.sb-peek .sdb-sec-items  { height: auto; }

/* ══ Main wrap ═════════════════════════════════════════════════════ */
.main-wrap {
  flex: 1;
  margin-left: var(--sidebar-w);
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  transition: margin-left .22s var(--ease);
}

/* ══ Topbar ════════════════════════════════════════════════════════ */
.topbar {
  position: sticky;
  top: 0;
  z-index: 80;
  height: var(--topbar-h);
  background: var(--sur);
  border-bottom: 0.5px solid var(--sep);
  display: flex;
  align-items: center;
  padding: 0 20px 0 14px;
  gap: 12px;
  flex-shrink: 0;
}
.topbar::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: rgba(255,255,255,.5);
  pointer-events: none;
}

.topbar-toggle {
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none;
  border-radius: 8px;
  color: var(--l2);
  cursor: pointer;
  flex-shrink: 0;
  transition: background .12s, color .14s, transform .2s var(--spring);
}
.topbar-toggle:hover { background: rgba(0,0,0,.05); color: var(--l1); }
.topbar-toggle svg { width: 16px; height: 16px; flex-shrink: 0; }

.topbar-back {
  display: flex; width: 32px; height: 32px;
  align-items: center; justify-content: center;
  background: transparent; border: none;
  border-radius: 8px;
  color: var(--l2);
  cursor: pointer;
  flex-shrink: 0;
  transition: background .12s, color .14s, transform .18s var(--ease);
  position: relative;
}
.topbar-back:hover:not(.is-disabled) {
  background: rgba(0,0,0,.05);
  color: var(--ac-txt);
  transform: translateX(-2px);
}
.topbar-back:active:not(.is-disabled) { transform: translateX(-3px) scale(.95); }
.topbar-back svg { width: 16px; height: 16px; transition: transform .15s; }
.topbar-back.is-disabled { color: var(--l4); cursor: not-allowed; opacity: .5; }
.topbar-back.is-disabled:hover { background: transparent; transform: none; }

.topbar-logo {
  display: none; align-items: center; justify-content: center;
  padding: 0 2px;
  flex-shrink: 0;
  transition: opacity .15s, transform .2s var(--ease);
}
.topbar-logo:hover { opacity: .8; }
.topbar-logo:active { transform: scale(.95); }
.topbar-logo-img {
  width: 28px; height: 28px;
  border-radius: 7px;
  border: 0.5px solid var(--sep);
  object-fit: contain;
  background: var(--ac-dim);
  padding: 3px;
}

.topbar-back-count {
  position: absolute;
  top: -2px; right: -2px;
  min-width: 14px; height: 14px;
  padding: 0 4px;
  background: var(--ac); color: #fff;
  border-radius: 7px;
  font-size: 0.6875rem; font-weight: 700;
  display: none; align-items: center; justify-content: center;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  box-shadow: 0 0 0 1.5px var(--sur);
}
.topbar-back:hover:not(.is-disabled) .topbar-back-count { display: inline-flex; }

.topbar-title {
  flex: 1;
  font-size: .875rem; font-weight: 400;
  color: var(--l2);
  margin: 0;
  letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.topbar-right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

.topbar-btn {
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none;
  border-radius: 8px;
  color: var(--l3);
  cursor: pointer;
  transition: background .12s, color .14s;
}
.topbar-btn:hover { background: rgba(0,0,0,.05); color: var(--l1); }
.topbar-btn svg { width: 15px; height: 15px; }

/* Sun/moon toggle icons */
.icon-moon { display: none; }
html[data-theme="dark"] .icon-sun { display: none; }
html[data-theme="dark"] .icon-moon { display: block; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .icon-sun  { display: none; }
  html:not([data-theme="light"]) .icon-moon { display: block; }
}

.topbar-user { font-size: .8125rem; color: var(--l2); font-family: var(--f); padding: 0 4px; text-decoration: none; border-radius: 8px; transition: background .12s, color .12s; }
a.topbar-user:hover { color: var(--l1); background: rgba(0,0,0,.05); text-decoration: none; }

/* Libellés des onglets — visibles uniquement sur la barre mobile (cf. media query) */
.topbar-tab-label { display: none; }

/* ══ Page content ══════════════════════════════════════════════════ */
.page-content { flex: 1; min-width: 0; }
/* `clip` et non plus `hidden` (vague 2, 14/10/2026) : `hidden` faisait du contenu un conteneur de
   défilement qui ne défile jamais, et AUCUN `position: sticky` des pages ne collait (récapitulatif
   des bordereaux, barre « Valider » au téléphone, barre de sélection de l'analytique). `clip`
   coupe pareil sans créer de conteneur. `hidden` reste pour un navigateur qui ignore `clip`. */
body[data-layout="wide"] .page-content { overflow: hidden; overflow: clip; }
body[data-layout="narrow"] .page-content { padding: 32px 40px 60px; }

/* ══ Container (formulaires en mode narrow) ═══════════════════════ */
body[data-layout="narrow"] .container {
  max-width: 520px;
  margin: 0 auto !important;
  padding: 28px !important;
  background: var(--sur) !important;
  border-radius: var(--r) !important;
  box-shadow: var(--sh-card), inset 0 1px 0 rgba(255,255,255,.9) !important;
  border: 0.5px solid var(--sep) !important;
}

/* ══ Django messages ══════════════════════════════════════════════ */
.base-messages { padding: 16px 24px 0; }
.base-messages .alert, .alert {
  border-radius: var(--r2);
  font-family: var(--f);
  font-size: .875rem;
  padding: 12px 16px;
  margin: 0 0 16px;
  border-width: 1px;
  border-style: solid;
}
.alert-success { background: rgba(110,138,36,.08); border-color: rgba(110,138,36,.20); color: #3D4E14; }
.alert-error,
.alert-danger  { background: var(--red-dim); border-color: var(--red-brd); color: var(--red); }
.alert-info    { background: var(--sur2); border-color: var(--sep); color: var(--l2); }
.alert-warning { background: rgba(200,140,30,.08); border-color: rgba(200,140,30,.20); color: #7A500A; }

/* Thème sombre : les textes olive/ambre/rouge foncés sont illisibles sur fond noir
   → couleurs éclaircies (≥ 4.5:1). Doublé data-theme + prefers-color-scheme (cf. tokens). */
html[data-theme="dark"] .alert-success { color: #A9C46C; }
html[data-theme="dark"] .alert-warning { color: #E6B057; }
html[data-theme="dark"] .alert-error,
html[data-theme="dark"] .alert-danger  { color: #E8897E; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .alert-success { color: #A9C46C; }
  html:not([data-theme="light"]) .alert-warning { color: #E6B057; }
  html:not([data-theme="light"]) .alert-error,
  html:not([data-theme="light"]) .alert-danger  { color: #E8897E; }
}

/* ══ Form elements (narrow only) ══════════════════════════════════ */
body[data-layout="narrow"] label {
  font-family: var(--f);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .10em;
  color: var(--l3);
  margin-bottom: 6px;
  display: block;
}
body[data-layout="narrow"] input[type="text"],
body[data-layout="narrow"] input[type="email"],
body[data-layout="narrow"] input[type="password"],
body[data-layout="narrow"] input[type="number"],
body[data-layout="narrow"] input[type="date"],
body[data-layout="narrow"] select,
body[data-layout="narrow"] textarea {
  font-family: var(--f);
  font-size: .875rem;
  color: var(--l1);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--sep);
  border-radius: 0;
  padding: 7px 0 8px;
  width: 100%;
  outline: none;
  transition: border-color .15s;
  box-shadow: none !important;
}
body[data-layout="narrow"] input:focus,
body[data-layout="narrow"] select:focus,
body[data-layout="narrow"] textarea:focus {
  border-bottom-color: var(--ac);
  box-shadow: none !important;
}
body[data-layout="narrow"] input::placeholder,
body[data-layout="narrow"] textarea::placeholder { color: var(--l3); }

/* ══ Modale de confirmation partagée (cuma.confirm) ══════════════ */
/* ══ Bouton principal commun (harmonisation, 14/10/2026) ══════════════════════
   Toute règle `.xx-btn-primary` / `.xx-btn-apply` prend ces jetons au lieu de ses
   propres hauteur, rayon et taille (test : accounts/test_harmonisation.py,
   BoutonsTests). 40 px à la souris, 48 px au doigt, en pilule. */
:root { --btn-h: 40px; --btn-r: var(--rp); --btn-fs: .8125rem; --btn-px: 18px; }
@media (pointer: coarse) { :root { --btn-h: 48px; } }

/* Titre de page commun (harmonisation, 14/10/2026) : une taille pour le <h1> de toutes les pages de
   l'encadrement et des listes, au lieu de sept (1,4 à 1,9 rem). Test : TitresTests. */
:root { --titre-page: 1.75rem; }
@media (max-width: 640px) { :root { --titre-page: 1.5rem; } }

/* Couleur du TYPE de bordereau (décision de Lou, 14/10/2026) : la même partout — accueils, liste des bordereaux,
   Mes bordereaux, fiche. Prestation verte, entretien ambre, déplacement bleu. Test : TypeCouleursTests. */
:root {
  --type-prestation-bg: rgba(110,138,36,.11); --type-prestation-fg: var(--ac-txt);
  --type-entretien-bg: rgba(201,155,46,.14);  --type-entretien-fg: #8A5D0E;
  --type-deplacement-bg: rgba(80,140,180,.13); --type-deplacement-fg: #2F5F8E;
}
html[data-theme="dark"] { --type-entretien-fg: #E2B448; --type-deplacement-fg: #7AB0D8; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) { --type-entretien-fg: #E2B448; --type-deplacement-fg: #7AB0D8; }
}

/* Pagination commune des listes paginées (partials/_pages.html, harmonisation 14/10/2026). */
.cuma-pages { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 16px 0 4px; }
.cuma-pages-btn {
  display: inline-flex; align-items: center; justify-content: center; min-height: var(--btn-h);
  padding: 0 16px; border-radius: var(--btn-r); border: 0.5px solid var(--sep); background: var(--sur);
  color: var(--l1); font-size: var(--btn-fs); font-weight: 600; text-decoration: none; white-space: nowrap;
}
a.cuma-pages-btn:hover { border-color: var(--ac-brd); color: var(--ac-txt, var(--l1)); text-decoration: none; }
.cuma-pages-btn[aria-disabled="true"] { opacity: .4; }
.cuma-pages-info { font-size: .8125rem; color: var(--l2); text-align: center; flex: 1 1 auto; }
@media (max-width: 520px) { .cuma-pages-info { order: -1; flex-basis: 100%; } }

.cuma-confirm-overlay {
  position: fixed; inset: 0; z-index: 1100;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(0,0,0,.45);
  opacity: 0; transition: opacity .16s var(--ease);
}
.cuma-confirm-overlay.show { opacity: 1; }
.cuma-confirm {
  width: 100%; max-width: 420px;
  background: var(--sur);
  border: 0.5px solid var(--sep);
  border-radius: var(--r);
  box-shadow: var(--sh-hover);
  padding: 22px 22px 18px;
  transform: scale(.96); transition: transform .16s var(--spring);
  font-family: var(--f);
}
.cuma-confirm-overlay.show .cuma-confirm { transform: scale(1); }
.cuma-confirm-title { font-size: 1.1rem; font-weight: 600; color: var(--l1); margin: 0 0 8px; letter-spacing: -.02em; }
.cuma-confirm-msg { font-size: .875rem; color: var(--l2); margin: 0 0 20px; line-height: 1.5; white-space: pre-line; }
.cuma-confirm-motif { display: grid; gap: 6px; margin: -8px 0 20px; font-size: .8125rem; color: var(--l2); }
.cuma-confirm-motif textarea { width: 100%; font: inherit; font-size: .875rem; color: var(--l1); background: var(--sur2); border: 1px solid var(--sep); border-radius: 8px; padding: 8px 10px; resize: vertical; }
.cuma-confirm-motif textarea:focus { outline: 2px solid var(--ac-brd); outline-offset: 1px; }
/* `recopier` (shell.js) : le nombre à retaper avant un geste de masse. */
.cuma-confirm-recopie { display: grid; gap: 6px; margin: -8px 0 20px; font-size: .8125rem; color: var(--l2); }
.cuma-confirm-recopie input { width: 100%; font: inherit; font-size: 1rem; font-variant-numeric: tabular-nums; color: var(--l1); background: var(--sur2); border: 1px solid var(--sep); border-radius: 8px; padding: 9px 10px; }
.cuma-confirm-recopie input:focus { outline: 2px solid var(--red-brd, var(--ac-brd)); outline-offset: 1px; }
.cuma-confirm-ok:disabled, .cuma-confirm-ok:disabled:hover { opacity: .45; cursor: not-allowed; }
.cuma-confirm-actions { display: flex; justify-content: flex-end; gap: 10px; }
.cuma-confirm-cancel, .cuma-confirm-ok {
  font-family: var(--f); font-size: .85rem; font-weight: 600;
  padding: 9px 18px; border-radius: var(--rp); cursor: pointer;
  border: 0.5px solid transparent; transition: background .15s, color .15s, border-color .15s;
}
.cuma-confirm-cancel { background: var(--sur2); color: var(--l2); border-color: var(--sep); }
.cuma-confirm-cancel:hover { background: var(--sur); color: var(--l1); border-color: var(--ac-brd); }
.cuma-confirm-ok { background: var(--ac); color: #fff; }
.cuma-confirm-ok:hover { background: var(--ac-hover); }
.cuma-confirm-ok.is-danger { background: var(--red); }
.cuma-confirm-ok.is-danger:hover { background: #a93226; }
/* `prudent` (shell.js) : le choix sûr en avant, le geste risqué en secondaire. */
.cuma-confirm-cancel.is-principal { background: var(--ac); color: #fff; border-color: transparent; }
.cuma-confirm-cancel.is-principal:hover { background: var(--ac-hover); color: #fff; }
.cuma-confirm-ok.is-secondaire { background: var(--sur2); color: var(--l1); border-color: var(--sep); }
.cuma-confirm-ok.is-secondaire:hover { background: var(--sur); border-color: var(--ac-brd); }
body.cuma-confirm-open { overflow: hidden; }

/* ══ iPhone : la page défile dans .main-wrap, pas dans le document ═══
   Safari iOS 26 (navigateur et app installée) décroche une barre fixée en bas
   pendant le défilement du document : la barre d'onglets (Menu, Retour,
   Recherche…) remontait jusqu'au milieu de l'écran, surtout avec « Réduire les
   animations » (signalé par Lou le 21/10/2026 ; forums développeurs Apple,
   WebKit 297779). Parade documentée : le document ne défile plus, un enfant du
   corps devient le conteneur de défilement. iOS seulement
   (-webkit-touch-callout n'existe que là), largeur téléphone seulement ;
   ordinateurs et Android gardent le défilement du document. Le code qui lit le
   défilement écoute en capture (tooltip.js, accueil) ou remonte aussi
   .main-wrap (saisie_fiable.js). */
@supports (-webkit-touch-callout: none) {
  @media (max-width: 768px) {
    html, body { height: 100%; overflow: hidden; }
    body { min-height: 0; }
    /* « body .main-wrap » et non « .main-wrap » : la règle téléphone plus bas dans ce fichier
       (« .main-wrap { padding-bottom: calc(68px + …) } ») l'emportait par l'ordre, et les boutons
       Brouillon/Valider flottaient 68 px au-dessus de la barre d'onglets (21/10/2026). */
    body .main-wrap {
      height: 100%;
      min-height: 0;
      overflow-y: auto;
      overscroll-behavior-y: contain;
      -webkit-overflow-scrolling: touch;
      /* La marge du bas d'un conteneur de défilement décale ses éléments collants (les
         boutons Brouillon/Valider remontaient de 68 px) : la place sous la barre d'onglets
         devient un espace vide en fin de contenu. */
      padding-bottom: 0;
    }
    body .main-wrap::after { content: ''; display: block; flex: none; height: calc(68px + env(safe-area-inset-bottom, 0px)); }
    body.cuma-confirm-open .main-wrap, body.modal-open .main-wrap { overflow: hidden; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .cuma-confirm-overlay, .cuma-confirm { transition: none; }
}

/* ══ Focus visible (accessibilité clavier) ═══════════════════════ */
*:focus { outline: none; }
*:focus-visible {
  outline: 2px solid var(--ac-txt);
  outline-offset: 2px;
  border-radius: 6px;
}
/* Override pour les liens inline : pas trop chargé */
a:focus-visible { outline-offset: 3px; }

/* ══ Skip-link (navigation clavier) ═══════════════════════════════ */
.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  background: var(--ac);
  color: #fff;
  padding: 8px 14px;
  border-radius: 0 0 8px 8px;
  font-size: .85rem;
  font-weight: 600;
  z-index: 100000;
  transition: top .15s var(--ease);
  text-decoration: none;
}
.skip-link:focus { top: 0; color: #fff; text-decoration: none; }

/* ══ Submit loading state (spinner sur boutons) ═══════════════════ */
.js-btn-content {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: inherit;
  transition: opacity .15s;
}
.js-btn-spinner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity .15s;
}
.js-btn-spinner svg {
  width: 18px; height: 18px;
  animation: btn-spin .7s linear infinite;
  color: currentColor;
}
.is-loading {
  position: relative !important;
  pointer-events: none !important;
  cursor: wait !important;
}
.is-loading .js-btn-content { opacity: 0; }
.is-loading .js-btn-spinner { opacity: 1; }
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* ══ Mobile ════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  .sidebar {
    transform: translateX(-100%);
    width: 240px !important;
    box-shadow: none;
  }
  body.sb-collapsed .sidebar { transform: translateX(-100%); width: 240px !important; }
  body.sb-open .sidebar { transform: translateX(0) !important; box-shadow: 0 0 40px rgba(0,0,0,.15); }
  /* En drawer ouvert, on force le contenu pleinement visible
     même si sb-collapsed est encore sur le body (état desktop résiduel) */
  body.sb-open .sdb-wordmark   { opacity: 1 !important; width: auto !important; }
  body.sb-open .sdb-section    { opacity: 1 !important; height: auto !important; padding: 16px 8px 6px !important; justify-content: space-between !important; }
  body.sb-open .sdb-section > span  { display: inline !important; }
  body.sb-open .sdb-section::before { content: none !important; }
  body.sb-open .sn-label       { display: inline !important; opacity: 1 !important; width: auto !important; white-space: normal !important; word-break: break-word !important; overflow-wrap: anywhere !important; }
  body.sb-open .sdb-user-info  { opacity: 1 !important; width: auto !important; }
  body.sb-open .sdb-logo       { justify-content: flex-start !important; padding: 0 14px !important; gap: 10px !important; }
  body.sb-open .sdb-user       { justify-content: flex-start !important; padding: 8px 10px !important; gap: 10px !important; }
  body.sb-open .sdb-logout     { display: flex !important; }
  body.sb-open .sn-link        { justify-content: flex-start !important; padding: 8px 10px !important; gap: 10px !important; }
  body.sb-open .sdb-version    { opacity: 1 !important; }
  body.sb-open .sdb-chev       { opacity: 1 !important; width: 13px !important; }
  .main-wrap {
    margin-left: 0 !important;
    padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px));
  }
  body[data-layout="narrow"] .page-content { padding: 20px 16px 72px; }
  body[data-layout="narrow"] .container { margin: 0 !important; max-width: 100%; }
  /* ══ Topbar mobile = barre d'onglets fixée en bas (style app iOS/Material) ══ */
  .topbar {
    position: fixed;
    top: auto; bottom: 0; left: 0; right: 0;
    height: calc(56px + env(safe-area-inset-bottom, 0px));
    padding: 4px 6px;
    padding-bottom: calc(4px + env(safe-area-inset-bottom, 0px));
    gap: 2px;
    display: flex;
    align-items: stretch;
    justify-content: space-around;
    background: rgba(255,255,255,.82);
    backdrop-filter: blur(22px) saturate(1.8);
    -webkit-backdrop-filter: blur(22px) saturate(1.8);
    border-bottom: none;
    border-top: 0.5px solid var(--sep);
    box-shadow: 0 -6px 24px rgba(0,0,0,.06);
  }
  html[data-theme="dark"] .topbar {
    background: rgba(28,28,30,.74);
    border-top-color: rgba(255,255,255,.08);
    box-shadow: 0 -6px 24px rgba(0,0,0,.4);
  }
  @media (prefers-color-scheme: dark) {
    html:not([data-theme="light"]) .topbar {
      background: rgba(28,28,30,.74);
      border-top-color: rgba(255,255,255,.08);
      box-shadow: 0 -6px 24px rgba(0,0,0,.4);
    }
  }
  .topbar::after { display: none; }

  /* Ce qui n'a pas sa place dans une barre d'onglets */
  .topbar-logo,
  .topbar-title,
  .topbar:has(.bcrumb) .topbar-title,
  .bcrumb { display: none !important; }

  /* Le conteneur droit s'efface : ses enfants deviennent des onglets de 1er niveau */
  .topbar-right { display: contents; }

  /* Chaque onglet : pile verticale icône + libellé, répartis également.
     Préfixe `.topbar` → spécificité (0,2,0) pour battre cmd-palette.css
     (chargé après base.css) qui cible `.cmd-trigger` à (0,1,0). */
  .topbar .topbar-toggle,
  .topbar .topbar-back,
  .topbar .cmd-trigger,
  .topbar .nbell-btn,
  .topbar .topbar-user {
    flex: 1 1 0;
    min-width: 0;
    max-width: 96px;
    width: auto;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 5px 2px;
    background: transparent;
    border: none;
    border-radius: 13px;
    color: var(--l2);
    -webkit-tap-highlight-color: transparent;
    transition: transform .16s var(--spring), background .14s, color .14s;
  }
  .topbar .nbell { flex: 1 1 0; min-width: 0; max-width: 96px; display: flex; }
  .topbar .nbell-btn { width: 100%; position: relative; }

  /* Icônes homogènes */
  .topbar .topbar-toggle svg,
  .topbar .topbar-back svg,
  .topbar .cmd-trigger-ico,
  .topbar .nbell-btn > svg { width: 23px; height: 23px; flex-shrink: 0; }

  /* Libellés d'onglets */
  .topbar .topbar-tab-label {
    display: block;
    max-width: 100%;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1;
    color: inherit;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* cmd-trigger : neutralise le masquage de span hérité de cmd-palette.css */
  .topbar .cmd-trigger > .topbar-tab-label { display: block; }
  .topbar .cmd-trigger > span:not(.topbar-tab-label),
  .topbar .cmd-trigger-kbd { display: none; }

  /* Onglet Profil : avatar + libellé (le prénom est masqué) */
  .topbar-user .u-person-name { display: none; }
  .topbar-user .u-av { width: 23px; height: 23px; font-size: 0.6875rem; }

  /* États : appui (sidebar ouverte → Menu en accent) */
  .topbar-toggle:active,
  .topbar-back:active:not(.is-disabled),
  .cmd-trigger:active,
  .nbell-btn:active,
  .topbar-user:active { transform: scale(.9); background: rgba(0,0,0,.05); }
  html[data-theme="dark"] .topbar-toggle:active,
  html[data-theme="dark"] .cmd-trigger:active,
  html[data-theme="dark"] .topbar-user:active { background: rgba(255,255,255,.07); }
  body.sb-open .topbar-toggle,
  body.sb-open .topbar-toggle .topbar-tab-label { color: var(--ac-txt); }

  /* Pastille de notif : repositionnée sur le coin haut-droit de l'icône.
     `.topbar` → (0,2,0) pour battre le <style> inline du partial (0,1,0). */
  .topbar .nbell-count { top: 6px; right: calc(50% - 17px); }

  /* Densité = réglage desktop ; masquée sur mobile */
  .topbar-btn[data-action="cycle-density"] { display: none; }
}
@media (max-width: 480px) {
  body[data-layout="narrow"] .page-content { padding: 16px 12px 72px; }
}

/* ══ Cibles tactiles au doigt (≥ 44 px) ═══════════════════════════════
   Au téléphone (pointeur grossier), les commandes des écrans de gestion
   mesuraient 18 à 29 px de haut (audit D-25, A12). `min-height` et
   `min-width` l'emportent sur la `height`/`width` fixée par la page, sans
   rien changer à l'ordinateur. Un lien en ligne devient `inline-flex` pour
   que la hauteur s'applique. Ajouter ici toute nouvelle commande au doigt. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
@media (pointer: coarse) {
  /* `html body` : l'emporte sur une règle de la page de même classe (la page
     est chargée après base.css et redéfinit parfois min-height à 36 px). */
  /* Accueil administrateur */
  html body :is(.dash-panel-toggle, .dash-panel-tool, .adb-range-nav, .adb-alr-trash, .adb-hide-btn,
  /* Journées, congés, adhérents, carburant, cuves, activités */
  .lj-del-btn, .gc-del-btn, .la-act, .la-del-btn, .lc-del-btn, .hc-edit-btn, .hc-del-btn,
  .ga-act, .ga-del-btn, .ac-combo-toggle,
  /* Connexion */
  .theme-btn, .pw-toggle) {
    min-width: 44px; min-height: 44px;
  }
  html body :is(.adb-link-more, .adb-cuve-btn, .adb-range-label, .adb-mini-btn,
  .lj-btn-outline, .lj-btn-loadmore, .gc-tab, .gc-btn-outline, .gc-btn-respond,
  .lc-back, .lc-btn-outline, .lc-btn-apply, .lc-btn-loadmore, .lc-input,
  .hc-back, .hc-btn-outline, .hc-tab, .hc-btn-glass, .hc-btn-ghost, .ga-tab, .mc-sort,
  .an-btn-sec, .an-btn-lien, .an-seg-btn, .an-kpi-alerte, .an-puce-lien,
  .login-input, .login-btn) {
    min-height: 44px;
  }
  html body :is(.adb-link-more, .adb-cuve-btn, .adb-mini-btn, .gc-btn-respond, .lc-back, .hc-back, .an-puce-lien) {
    display: inline-flex; align-items: center;
  }
  html body :is(.adb-table-link, .lj-num-link, .pf-link) {
    display: inline-flex; align-items: center; min-height: 44px;
  }
  html body .an-coche { width: 24px; height: 24px; }
  /* Retouches du 14/10/2026 (renotation, groupe 1) : « Marquer comme lu » (29 px), la
     déconnexion du menu (28 × 28), les retours « Mes congés » (32 et 37 px), Filtrer et
     Export de « Mes journées » (40 px). */
  html body :is(.mm-btn-lu, .dcs-back, .dc-back, .mj-btn-glass, .mj-btn-ghost, .mj-btn-pri) {
    min-height: 44px;
  }
  html body :is(.dcs-back, .dc-back) { display: inline-flex; align-items: center; }
  html body .sdb-logout { min-width: 44px; min-height: 44px; }
}
