/* ============================================================================
   Gestiria — Design System
   Esprit : centre de loisirs (chaleureux, joyeux, accessible) + look pro SaaS.
   Conventions : custom properties pour toute la palette, classes existantes
   préservées, transitions douces, accessibilité RGAA-A.
   ========================================================================= */

/* -------- 1. Variables -------- */
:root {
  /* Palette chaleureuse — corail, orange, teal */
  --c-primary: #FF6B6B;
  --c-primary-hover: #FF5252;
  --c-primary-soft: #FFE4E1;
  --c-primary-text: #B91C1C;

  --c-accent: #FF8C5A;
  --c-accent-hover: #FF7A3F;

  --c-secondary: #14B8A6;
  --c-secondary-hover: #0D9488;
  --c-secondary-soft: #CCFBF1;

  --c-warn: #F59E0B;
  --c-warn-hover: #D97706;
  --c-warn-soft: #FEF3C7;
  --c-warn-text: #92400E;

  --c-danger: #EF4444;
  --c-danger-hover: #DC2626;
  --c-danger-soft: #FEE2E2;
  --c-danger-text: #991B1B;

  --c-success: #10B981;
  --c-success-soft: #D1FAE5;
  --c-success-text: #065F46;

  --c-info: #3B82F6;
  --c-info-soft: #DBEAFE;
  --c-info-text: #1E40AF;

  /* Familles de boutons — 4 couleurs distinctes pour la navigation et les actions */
  --c-week: #7C3AED;          /* violet — sélecteur semaine */
  --c-week-hover: #6D28D9;
  --c-week-soft: #EDE9FE;
  --c-week-border: #C4B5FD;

  --c-day: #0EA5E9;           /* bleu ciel — sélecteur jour */
  --c-day-hover: #0284C7;
  --c-day-soft: #E0F2FE;
  --c-day-border: #7DD3FC;

  --c-view: #14B8A6;          /* teal/vert — bascule vue horaire/activité */
  --c-view-hover: #0D9488;
  --c-view-soft: #CCFBF1;

  --c-action: #FF6B6B;        /* corail — boutons d'action (créneau/activité/sortie) */
  --c-action-hover: #FF5252;

  /* Violet pour la barre 'jour' du planning (distinct de la barre 'semaine'
     qui utilise secondary teal) */
  --c-violet: #8B5CF6;
  --c-violet-soft: #EDE9FE;
  --c-violet-text: #5B21B6;

  /* Neutres */
  --c-bg: #FFF8F2;
  --c-surface: #FFFFFF;
  --c-surface-2: #FAFAF9;
  --c-border: #E7E5E4;
  --c-border-strong: #D6D3D1;
  --c-text: #1F2937;
  --c-text-soft: #4B5563;
  --c-text-muted: #6B7280;
  /* Phase 5.4 (RGAA AA) : --c-text-faint passe de #9CA3AF (2.84:1, fail)
     a #6B7280 (4.69:1, AA OK). Reste visuellement plus discret que
     --c-text-muted grace au contraste avec les autres couleurs UI. */
  --c-text-faint: #6B7280;

  /* Gradient header */
  --grad-header: linear-gradient(135deg, #FF8C5A 0%, #FF6B6B 60%, #F472B6 100%);

  /* Couleurs de groupe — palette "centre de loisirs" douce */
  --g-1: #FF6B9D;  /* PS - rose framboise */
  --g-2: #FF8C5A;  /* MS - orange chaleureux */
  --g-3: #A78BFA;  /* GS/ELEM - violet */
  --g-4: #60A5FA;  /* Direction - bleu */
  --g-5: #34D399;  /* extra - vert menthe */
  --g-6: #FBBF24;  /* extra - jaune */

  /* Espaces */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* Rayons */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 18px;
  --r-pill: 999px;

  /* Ombres — souples, modernes */
  --sh-sm: 0 1px 2px rgba(15, 23, 42, .06);
  --sh-md: 0 4px 12px rgba(15, 23, 42, .08);
  --sh-lg: 0 8px 24px rgba(15, 23, 42, .10);
  --sh-card: 0 1px 3px rgba(15, 23, 42, .06), 0 4px 16px rgba(15, 23, 42, .04);
  --sh-header: 0 2px 12px rgba(255, 107, 107, .25);

  /* Transitions */
  --t-fast: 120ms ease;
  --t-base: 180ms ease;

  /* Typo — stack 100% system, zéro requête externe (RGPD-friendly + pas de FOUT) */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

/* -------- 2. Reset + base -------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--c-text);
  /* Fond chaleureux global (vs blanc plat) : creme/peche avec halos
     orange-rose qui evoquent l'esprit ACM/centre de loisirs. background-attachment: fixed pour que le degrade ne defile pas avec le contenu. */
  background: #FFF1DD;
  background-image:
    radial-gradient(circle at 92% 8%, rgba(255, 140, 90, 0.22), transparent 45%),
    radial-gradient(circle at 8% 95%, rgba(255, 183, 77, 0.18), transparent 45%),
    radial-gradient(circle at 50% 50%, rgba(255, 209, 154, 0.10), transparent 60%),
    linear-gradient(135deg, #FFF1DD 0%, #FFE9CC 100%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--sp-3);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--c-text);
}
h1 { font-size: 1.5rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 var(--sp-3); }

a { color: var(--c-secondary-hover); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--c-primary); }
a:focus-visible { outline: 2px solid var(--c-secondary); outline-offset: 2px; border-radius: 3px; }

::selection { background: var(--c-primary-soft); color: var(--c-primary-text); }

/* Sprint 8 P2-18 : --c-text-muted (#6B7280) sur fond peach = 3.97:1 (fail
   AA). --c-text-soft (#4B5563) = 6.55:1 (AA OK). Plus lisible pour basse
   vision et daltoniens. */
.help, p.help { color: var(--c-text-soft); font-size: .92em; }

/* -------- 3. Header app -------- */
.app-header {
  background: var(--grad-header);
  color: #fff;
  padding: 7px 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
  position: sticky;
  top: 0;
  z-index: 50;
  box-shadow: var(--sh-header);
}
.app-title {
  margin: 0;
  font-size: 1.15em;
  font-weight: 700;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Sprint brand 2026-05-16 : la pastille decorative ::before est remplacee
   par le logo Gestiria (img/logo.png) injecte dans le markup. La regle
   ::before precedente (radial-gradient en 3 points) est supprimee. */
.app-title a {
  color: #fff;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.app-title a:hover { color: #fff; }
.app-logo { height: 32px; width: auto; flex-shrink: 0; vertical-align: middle; }

/* Sprint brand 2026-05-16 : logo "splash" pour les pages first-impression
   (login, account-request, install) — affichage centre au-dessus du H1. */
.splash-logo { display: block; margin: 0 auto 24px; height: 80px; width: auto; }

/* Sprint a11y 2026-05-16 (P1) : .visually-hidden — masque visuellement un
   contenu tout en le gardant accessible aux lecteurs d'ecran (label de
   champ, descriptif additionnel). Pattern standard W3C / WHATWG.
   Utilise par qr-view.html sur le <label for="day-pick">. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Sprint a11y 2026-05-16 (P2) : skip link "Aller au contenu principal".
   Critere RGAA 12.7. Invisible par defaut, visible sur :focus-visible
   (premier tab depuis l'URL bar). Cible l'id="main" du <main>. */
.skip-link {
  position: absolute;
  top: -100px;
  left: 8px;
  z-index: 1000;
  background: var(--c-primary, #FF6B6B);
  color: #fff;
  padding: 10px 16px;
  border-radius: 6px;
  font-weight: 600;
  text-decoration: none;
  transition: top var(--t-fast, 120ms);
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 8px;
  outline: 3px solid var(--c-secondary, #14B8A6);
  outline-offset: 2px;
}

.app-nav { display: flex; gap: 4px; flex-wrap: wrap; }
.app-nav a {
  color: #fff;
  text-decoration: none;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  font-size: .88em;
  font-weight: 500;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .22);
  transition: all var(--t-fast);
  white-space: nowrap;
}
.app-nav a:hover {
  background: rgba(255, 255, 255, .26);
  color: #fff;
  transform: translateY(-1px);
}
.app-nav a.active {
  background: #fff;
  color: var(--c-primary);
  border-color: #fff;
  font-weight: 700;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .12);
}

.app-user { display: flex; align-items: center; gap: 10px; font-size: .88em; }
.app-user .who {
  opacity: .95;
  background: rgba(255, 255, 255, .18);
  padding: 5px 12px;
  border-radius: var(--r-pill);
  font-weight: 500;
}
.app-user button {
  background: rgba(255, 255, 255, .18);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .3);
  padding: 6px 14px;
  border-radius: var(--r-pill);
  cursor: pointer;
  font-size: .88em;
  font-family: inherit;
  font-weight: 500;
  transition: all var(--t-fast);
}
.app-user button:hover {
  background: rgba(255, 255, 255, .3);
  transform: translateY(-1px);
}

/* -------- 4. Toolbars / banners -------- */
.toolbar {
  background: var(--c-surface);
  border-bottom: 1px solid var(--c-border);
  padding: 7px 22px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}
.toolbar label { font-size: .9em; color: var(--c-text-soft); font-weight: 500; }
.toolbar .grow { flex: 1; }
.toolbar input[type=date],
.toolbar select {
  padding: 7px 12px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: .92em;
  background: #fff;
  color: var(--c-text);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.toolbar input[type=date]:focus,
.toolbar select:focus {
  outline: none;
  border-color: var(--c-secondary);
  box-shadow: 0 0 0 3px rgba(20, 184, 166, .15);
}

.grace-banner {
  background: linear-gradient(90deg, var(--c-warn-soft), #FFEDD5);
  color: var(--c-warn-text);
  padding: 12px 22px;
  font-weight: 600;
  text-align: center;
  border-bottom: 1px solid var(--c-warn);
}
.test-banner {
  background: repeating-linear-gradient(45deg, #FEF3C7 0 12px, #FDE68A 12px 24px);
  color: #78350F;
  padding: 9px 22px;
  text-align: center;
  font-weight: 700;
  font-size: .92em;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* -------- 5. Pills selectors — 4 familles visuellement distinctes -------- */
/* SEMAINES = violet · JOURS = bleu ciel · VUES = teal · ACTIONS = corail.
   Chaque famille porte sa couleur AU REPOS (bordure + texte teinté + fond pâle)
   pour qu'on identifie le rôle d'un bouton sans avoir à le cliquer. */
.week-selector, .day-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

/* SEMAINES — VIOLET */
.week-selector button {
  padding: 7px 14px;
  border: 1.5px solid var(--c-week-border);
  background: var(--c-week-soft);
  color: var(--c-week-hover);
  border-radius: var(--r-pill);
  cursor: pointer;
  font-size: .88em;
  font-family: inherit;
  font-weight: 600;
  transition: all var(--t-fast);
}
.week-selector button:hover:not(.active) {
  background: #fff;
  border-color: var(--c-week);
  color: var(--c-week);
  transform: translateY(-1px);
}
.week-selector button.active {
  background: var(--c-week);
  color: #fff;
  border-color: var(--c-week);
  font-weight: 700;
  box-shadow: 0 3px 8px rgba(124, 58, 237, .35);
}

/* JOURS — BLEU CIEL */
.day-selector button {
  padding: 7px 14px;
  border: 1.5px solid var(--c-day-border);
  background: var(--c-day-soft);
  color: var(--c-day-hover);
  border-radius: var(--r-pill);
  cursor: pointer;
  font-size: .88em;
  font-family: inherit;
  font-weight: 600;
  transition: all var(--t-fast);
}
.day-selector button:hover:not(.active) {
  background: #fff;
  border-color: var(--c-day);
  color: var(--c-day);
  transform: translateY(-1px);
}
.day-selector button.active {
  background: var(--c-day);
  color: #fff;
  border-color: var(--c-day);
  font-weight: 700;
  box-shadow: 0 3px 8px rgba(14, 165, 233, .35);
}

/* -------- 6. View switch (Vue horaire / Vue activité) — TEAL -------- */
.view-switch {
  display: inline-flex;
  gap: 4px;
  background: var(--c-view-soft);
  border: 1.5px solid var(--c-view);
  border-radius: var(--r-lg);
  padding: 4px;
}
.view-switch button {
  font-size: 1.05em;
  padding: 5px 22px;
  border: none;
  background: transparent;
  color: var(--c-view-hover);
  border-radius: var(--r-md);
  cursor: pointer;
  font-weight: 700;
  font-family: inherit;
  transition: all var(--t-fast);
}
.view-switch button:hover:not(.active) {
  color: var(--c-view);
  background: rgba(255, 255, 255, .7);
}
.view-switch button.active {
  background: var(--c-view);
  color: #fff;
  box-shadow: 0 3px 8px rgba(20, 184, 166, .35);
}

/* -------- 7. Boutons -------- */
.btn, button.primary {
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--c-primary), var(--c-accent));
  color: #fff;
  cursor: pointer;
  font-family: inherit;
  font-size: .92em;
  font-weight: 600;
  transition: all var(--t-fast);
  box-shadow: var(--sh-sm);
  white-space: nowrap;
}
.btn:hover, button.primary:hover {
  transform: translateY(-1px);
  box-shadow: var(--sh-md);
  filter: brightness(1.05);
}
.btn:active { transform: translateY(0); }
.btn:focus-visible, button:focus-visible {
  outline: 2px solid var(--c-secondary);
  outline-offset: 2px;
}
/* Sprint 8 P3-1 : focus renforce sur les selectors (week/day/view) pour
   les rendre clairement distinguables au clavier, meme quand un bouton
   actif a deja un fond colore qui pourrait masquer un outline 2px standard. */
.week-selector button:focus-visible,
.day-selector button:focus-visible,
.view-switch button:focus-visible,
.app-nav a:focus-visible {
  outline: 3px solid var(--c-secondary);
  outline-offset: 3px;
  z-index: 1;
  position: relative;
}
.btn:disabled, button:disabled {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn.secondary, button.secondary {
  background: #fff;
  color: var(--c-text);
  border: 1px solid var(--c-border-strong);
}
.btn.secondary:hover, button.secondary:hover {
  background: var(--c-surface-2);
  border-color: var(--c-secondary);
  color: var(--c-secondary-hover);
}

.btn.warn, button.warn {
  background: linear-gradient(135deg, var(--c-warn), #FB923C);
  color: #fff;
}
/* .danger : meme niveau de polish que .btn (gradient, shadow, hover lift),
   pour que les boutons "Supprimer" / "Revoquer" / "Tout revoquer" aient
   la meme patte graphique que "Fermer la suggestion". On force aussi
   padding/border-radius/transition au cas ou la classe est posee sans
   .btn (ex: <button class="danger">) — sinon le bouton heritait juste
   du fond rouge plat, sans rondeur ni ombre. */
.btn.danger, button.danger {
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, #EF4444, #DC2626);
  color: #fff;
  cursor: pointer;
  font-family: inherit;
  font-size: .92em;
  font-weight: 600;
  transition: all var(--t-fast);
  box-shadow: 0 1px 2px rgba(220, 38, 38, .25), 0 4px 12px rgba(220, 38, 38, .15);
  white-space: nowrap;
}
.btn.danger:hover, button.danger:hover {
  transform: translateY(-1px);
  filter: brightness(1.06);
  box-shadow: 0 2px 4px rgba(220, 38, 38, .30), 0 6px 16px rgba(220, 38, 38, .20);
}
.btn.danger:active, button.danger:active { transform: translateY(0); filter: none; }
.btn.danger:disabled, button.danger:disabled {
  opacity: .55; cursor: not-allowed; transform: none; filter: none;
}

.btn.success { background: var(--c-success); color: #fff; }

/* Boutons natifs hors .btn (dans formulaires admin/onboarding).
   :where() ramene la specificite a 0,0,1 pour que les selecteurs contextuels
   (week-selector, day-selector, view-switch, group-arrows...) gagnent. */
button:where(:not(.btn):not(.secondary):not(.danger):not(.warn):not(.primary)) {
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--c-primary), var(--c-accent));
  color: #fff;
  cursor: pointer;
  font-family: inherit;
  font-size: .92em;
  font-weight: 600;
  transition: all var(--t-fast);
  box-shadow: var(--sh-sm);
}
button:where(:not(.btn):not(.secondary):not(.danger):not(.warn):not(.primary)):hover {
  transform: translateY(-1px);
  box-shadow: var(--sh-md);
  filter: brightness(1.05);
}

/* -------- 8. Forms (inputs, selects, textareas, labels) -------- */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"],
input[type="tel"],
input[type="time"],
select,
textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: .95em;
  color: var(--c-text);
  background: #fff;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--c-secondary);
  box-shadow: 0 0 0 3px rgba(20, 184, 166, .15);
}
input:disabled, select:disabled, textarea:disabled {
  background: var(--c-surface-2);
  color: var(--c-text-muted);
}
textarea { resize: vertical; min-height: 80px; }

label {
  display: block;
  font-weight: 600;
  margin-top: var(--sp-3);
  color: var(--c-text-soft);
  font-size: .92em;
}

/* -------- 9. Layout (sidebar + main) -------- */
.layout {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 0;
  min-height: calc(100vh - 110px);
}
aside, .layout > nav {
  background: var(--c-surface);
  border-right: 1px solid var(--c-border);
  padding: 18px 16px;
}
aside h3 {
  margin: 0 0 var(--sp-3);
  font-size: .82em;
  color: var(--c-text-muted);
  text-transform: uppercase;
  letter-spacing: .08em;
  font-weight: 700;
}
main {
  padding: 22px 26px;
  overflow: auto;
}

/* -------- 10. Cards -------- */
.card {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--sh-card);
  margin-bottom: var(--sp-4);
}

/* -------- 11. Alerts -------- */
.alert {
  padding: 11px 15px;
  border-radius: var(--r-md);
  margin: var(--sp-3) 0;
  font-size: .94em;
  border: 1px solid;
  border-left-width: 4px;
}
.alert-info {
  background: var(--c-info-soft);
  color: var(--c-info-text);
  border-color: #93C5FD;
  border-left-color: var(--c-info);
}
.alert-error {
  background: var(--c-danger-soft);
  color: var(--c-danger-text);
  border-color: #FCA5A5;
  border-left-color: var(--c-danger);
}
.alert-warning {
  background: var(--c-warn-soft);
  color: var(--c-warn-text);
  border-color: #FCD34D;
  border-left-color: var(--c-warn);
}
.alert-success {
  background: var(--c-success-soft);
  color: var(--c-success-text);
  border-color: #6EE7B7;
  border-left-color: var(--c-success);
}

/* -------- 12. Alerts card (planning) -------- */
.alerts-card {
  background: linear-gradient(90deg, #FFFBEB, #FEF3C7);
  border: 1px solid #FCD34D;
  border-left: 4px solid var(--c-warn);
  border-radius: var(--r-md);
  padding: 4px 12px;
  margin: 0 0 4px;
}
.alerts-card h3 {
  margin: 0 0 3px;
  font-size: .95em;
  color: var(--c-warn-text);
  cursor: pointer;
  user-select: none;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}
.alerts-card.collapsed .alerts-list { display: none; }
.alerts-list { display: flex; flex-wrap: wrap; gap: 6px; }

.alert-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 11px;
  border-radius: var(--r-pill);
  font-size: .82em;
  font-weight: 600;
  border: 1px solid;
  background: #fff;
}
.alert-pill.under {
  background: #FFE4D6;
  color: #C2410C;
  border-color: #FB923C;
}
.alert-pill.over {
  background: var(--c-danger-soft);
  color: var(--c-danger-text);
  border-color: #FCA5A5;
}
.alert-pill .arrow { font-weight: 700; }

/* -------- 13. Badges & Pills -------- */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: .78em;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.b-active { background: var(--c-success-soft); color: var(--c-success-text); }
.b-pending { background: var(--c-info-soft); color: var(--c-info-text); }
.b-grace { background: var(--c-warn-soft); color: var(--c-warn-text); }
.b-closed { background: #E5E7EB; color: #4B5563; }

.pill {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 4px;
  flex-shrink: 0;
  vertical-align: middle;
}
.group-pill {
  width: 14px;
  height: 14px;
  border-radius: 4px;
  flex-shrink: 0;
  display: inline-block;
}

/* -------- 14. Tables -------- */
table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--sp-3) 0;
  background: var(--c-surface);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--sh-sm);
  font-size: .92em;
}
th {
  text-align: left;
  padding: 11px 14px;
  background: var(--c-surface-2);
  color: var(--c-text-soft);
  font-weight: 600;
  font-size: .82em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--c-border);
}
td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--c-border);
  color: var(--c-text);
}
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--c-surface-2); }

/* -------- 15. Modals -------- */
.modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
  animation: fadein var(--t-base);
}
.modal-bg.open { display: flex; }
.modal {
  background: var(--c-surface);
  border-radius: var(--r-xl);
  padding: 22px 26px;
  width: 92%;
  max-width: 540px;
  max-height: 88vh;
  overflow: auto;
  box-shadow: var(--sh-lg);
  animation: slideup var(--t-base);
}
.modal h2 {
  margin: 0 0 12px;
  color: var(--c-primary);
  font-size: 1.2em;
  font-weight: 700;
}
.modal label { display: block; font-weight: 600; margin-top: 12px; color: var(--c-text-soft); }
.modal .row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 18px;
  justify-content: flex-end;
}

@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideup { from { transform: translateY(12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
/* Animation pour les pastilles "nouvelle reponse" cote directeur :
   pulse soft pour attirer l'oeil sans agresser. */
@keyframes badgepulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(229, 57, 53, 0.55); }
  50%      { box-shadow: 0 0 0 5px rgba(229, 57, 53, 0); }
}

/* -------- 15b. Modale de confirmation custom (remplace confirm() natif) ----
   Reprend la patte graphique du site : carte blanche arrondie, halo
   orange/rouge selon "danger", boutons coherents avec .btn / .btn.danger.
   Empile au-dessus de .modal-bg pour pouvoir confirmer une action depuis
   un modal deja ouvert (ex: suppression dans la modal sortie). */
.confirm-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
  animation: fadein var(--t-base);
}
.confirm-dialog {
  background: var(--c-surface);
  border-radius: var(--r-xl);
  padding: 24px 24px 18px;
  width: 100%;
  max-width: 440px;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  animation: slideup var(--t-base);
}
.confirm-icon {
  display: inline-flex;
  width: 56px;
  height: 56px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 140, 90, 0.18);
  color: var(--c-accent-hover);
  font-size: 28px;
  font-weight: 700;
  margin-bottom: 12px;
  line-height: 1;
}
.confirm-dialog.is-danger .confirm-icon {
  background: var(--c-danger-soft);
  color: var(--c-danger);
}
.confirm-title {
  margin: 0 0 6px;
  font-size: 1.05em;
  font-weight: 700;
  color: var(--c-text);
}
.confirm-message {
  margin: 0 0 20px;
  color: var(--c-text-muted);
  font-size: .95em;
  line-height: 1.5;
  white-space: pre-wrap;
}
.confirm-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}
.confirm-actions .btn {
  min-width: 110px;
  justify-content: center;
}

/* Modal de refus avec textarea (account-requests). */
.confirm-field-label {
  display: block;
  margin: 1em 0 0.4em;
  font-weight: 600;
  text-align: left;
}
.confirm-field-textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 0.95em;
  padding: 0.5em;
  border: 1px solid var(--c-border, #ccc);
  border-radius: 4px;
  resize: vertical;
}
.confirm-field-hint {
  font-size: 0.85em;
  color: var(--c-text-muted);
  margin: 0.3em 0 0;
  text-align: left;
}

/* -------- 16. Group list (sidebar) -------- */
.group-list { list-style: none; padding: 0; margin: 0; }
.group-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: var(--r-md);
  margin-bottom: 4px;
  cursor: grab;
  user-select: none;
  background: var(--c-surface-2);
  border: 1px solid transparent;
  transition: all var(--t-fast);
}
.group-item:hover {
  background: #fff;
  border-color: var(--c-secondary);
  box-shadow: var(--sh-sm);
}
.group-item.dragging { opacity: .45; cursor: grabbing; }
.group-name { flex: 1; font-weight: 600; font-size: .92em; }
.group-arrows { display: flex; flex-direction: column; gap: 1px; }
.group-arrows button {
  background: #fff;
  border: 1px solid var(--c-border);
  width: 22px;
  height: 18px;
  font-size: .7em;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  color: var(--c-text-muted);
  border-radius: 3px;
}
.group-arrows button:hover { background: var(--c-secondary-soft); color: var(--c-secondary-hover); }
.group-arrows button:focus-visible { outline: 2px solid var(--c-secondary); }

/* -------- 17. Timeline (planning vue horaire) -------- */
.timeline {
  display: grid;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  overflow: hidden;
  font-size: .88em;
  box-shadow: var(--sh-card);
}
.tl-header {
  display: grid;
  grid-template-columns: 180px 1fr;
  background: var(--c-surface-2);
  border-bottom: 1px solid var(--c-border);
  font-weight: 600;
  color: var(--c-text-soft);
  /* Boost lisibilite (2026-05) : passe de .82em a .95em pour le bandeau
     "EQUIPE" + heures du header. */
  font-size: .95em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.tl-header .label { padding: 10px 14px; }
.tl-hours { display: grid; position: relative; }
.tl-hour-tick {
  /* Couleur volontairement plus marquee (#94a3b8) que --c-border : sur fond
     blanc le pointille gris-clair etait quasi invisible, ce qui empechait de
     situer rapidement les heures sur la grille. */
  border-left: 1px dashed #94a3b8;
  padding: 8px 0 4px 6px;
  /* Boost lisibilite (2026-05) : .78em -> 1em. Les heures (7H, 8H...) doivent
     etre lisibles d'un coup d'oeil. */
  font-size: 1em;
  color: var(--c-text-muted);
  font-weight: 600;
}
.tl-row {
  display: grid;
  grid-template-columns: 180px 1fr;
  /* Séparateur 2px gris-bleu plus contrasté pour distinguer clairement
     chaque animateur (notamment quand des sorties s'affichent sous leur barre
     horaire). */
  border-bottom: 2px solid #B0BEC5;
  min-height: 76px;
  transition: background var(--t-fast);
}
.tl-row:last-child { border-bottom: none; }
.tl-row:hover { background: rgba(255, 248, 242, .5); }
.tl-row .label {
  padding: 10px 14px;
  font-weight: 600;
  background: var(--c-surface-2);
  border-right: 1px solid var(--c-border);
  display: flex;
  align-items: center;
  gap: 8px;
  /* Boost lisibilite (2026-05) : .92em -> 1.1em. Nom de l'animateur,
     visible quand on regarde la timeline. */
  font-size: 1.1em;
}
/* Le compteur "12h / 47.5h (sem.)" sous le nom est dans un <small> qui
   reduit a ~.83em par defaut. On force a .92em pour que ca reste lisible
   meme sous le boost de .tl-row .label. */
.tl-row .label small {
  font-size: .92em;
}
.tl-track {
  position: relative;
  /* Les lignes verticales horaires DOIVENT s'aligner sur les .tl-hour-tick
     du header (CSS Grid 1fr/heure). On utilise donc un repeat % et non un
     pas en pixels (l'ancienne valeur fixe 40px etait incoherente avec le
     header en pourcentage et creait un drift visible).
     Pattern : 1px gris-bleute (#94a3b8) a chaque frontiere horaire + fond
     blanc. Couleur renforcee par rapport aux gris-clairs precedents pour
     etre clairement visible meme par-dessus les barres horaires (alpha
     reduit pour rester discret quand un block recouvre la zone). */
  background-color: #FFFFFF;
  background-image: linear-gradient(to right,
    rgba(148, 163, 184, 0.55) 0,
    rgba(148, 163, 184, 0.55) 1px,
    transparent 1px);
  background-size: calc(100% / 14) 100%;
  background-repeat: repeat-x;
}
/* Track horaire : double-clic sur zone vide pour creer un creneau. */
.tl-track { cursor: cell; }
.tl-track.empty { cursor: default; opacity: .55; }
.tl-track:has(.block:hover),
.tl-track:has(.outing-strip:hover) { cursor: default; }

.block {
  position: absolute;
  top: 8px;
  height: 44px;
  border-radius: var(--r-md);
  color: #fff;
  /* 14px lateral = place pour les handles ; le label est centre par flex. */
  padding: 4px 14px;
  /* Boost lisibilite (2026-05) : .8em -> 1em. Le label horaire dans la barre
     ("08:15 - 17:15") doit etre lisible d'un coup d'oeil. */
  font-size: 1em;
  font-weight: 600;
  cursor: grab;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  white-space: nowrap;
  box-shadow: var(--sh-sm);
  transition: box-shadow var(--t-fast);
  letter-spacing: 0.01em;
  user-select: none;
}
.block:hover {
  box-shadow: var(--sh-md);
  z-index: 2;
}
.block.dragging { cursor: grabbing; opacity: .85; box-shadow: var(--sh-lg); z-index: 5; }
/* Label horaire centre rigoureusement au milieu du bloc */
.block .block-label {
  text-align: center;
  width: 100%;
  pointer-events: none; /* clic traverse vers le bloc parent */
  text-overflow: ellipsis;
  overflow: hidden;
}
/* Croix de suppression : visible au survol du bloc, en haut a droite.
   Sprint 8 P1-19 : passe de <span> a <button> → reset des styles
   user-agent du button (padding, border, font-family) sinon le × est
   pousse vers le bas par le padding implicite. inline-flex centre
   parfaitement le caractere quel que soit le rendu UA. */
.block .block-del {
  position: absolute;
  top: 2px;
  right: 12px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .25);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  font-family: inherit;
  box-sizing: border-box;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--t-fast), background var(--t-fast);
  font-weight: 700;
}
.block:hover .block-del { opacity: 1; }
.block .block-del:hover { background: rgba(239, 68, 68, .9); }

/* Handles de redimensionnement — bords gauche et droit */
.block .handle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 8px;
  cursor: ew-resize;
  background: rgba(255, 255, 255, .15);
  transition: background var(--t-fast);
}
.block .handle:hover { background: rgba(255, 255, 255, .35); }
.block .handle.left  { left: 0;  border-radius: var(--r-md) 0 0 var(--r-md); }
.block .handle.right { right: 0; border-radius: 0 var(--r-md) var(--r-md) 0; }

/* Barre sortie : se positionne SOUS la barre horaire de l'animateur (et non
   dessus). top calé à 56px (8 + 44 + 4 d'écart) pour ne pas chevaucher .block.
   Cliquable pour ouvrir le modal d'edition. */
.outing-strip {
  position: absolute;
  /* La hauteur passe de 18px a 22px pour accommoder le boost de font-size. */
  top: 56px;
  height: 22px;
  background: linear-gradient(135deg, #7C3AED, #6D28D9);
  color: #fff;
  /* Boost lisibilite (2026-05) : .72em -> .9em. La pilule "Zoo" (nom de la
     sortie) etait quasi illisible sur la timeline. */
  font-size: .9em;
  padding: 2px 10px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(124, 58, 237, .35);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: filter var(--t-fast), box-shadow var(--t-fast);
}
.outing-strip:hover { filter: brightness(1.1); box-shadow: 0 2px 6px rgba(124, 58, 237, .45); }
.outing-strip::before {
  content: "🚌";
  font-size: 1em;
}
/* Couverture insuffisante : fond degrade rouge-orange + bordure pointillee */
.outing-strip.cover-issue {
  background: linear-gradient(135deg, #DC2626, #F59E0B);
  box-shadow: 0 1px 3px rgba(220, 38, 38, .5);
  outline: 2px dashed rgba(255, 255, 255, .7);
  outline-offset: -3px;
}
.outing-strip .cover-warn {
  font-size: .9em;
  margin-left: auto;
}
.group-row {
  background: linear-gradient(to right, rgba(0, 0, 0, .04), transparent 40%);
  padding: 8px 14px;
  font-weight: 700;
  color: var(--c-text);
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--c-border);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  /* Boost lisibilite (2026-05) : retire le doublon font-size .82em qui
     ecrasait le .92em. On monte directement a 1.05em pour les bandeaux
     "PETITE SECTION", "MOYENNE SECTION", etc. */
  font-size: 1.05em;
}
/* Le "X animateur(s)" qui suit le nom du groupe etait force petit via
   inline style. On override pour le rendre proportionnel au boost. */
.group-row .anim-count {
  font-size: .85em;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: #546E7A;
  margin-left: 8px;
}
.group-row .pill { width: 12px; height: 12px; }
/* Separation verticale entre groupes en vue horaire : un trait gris
   epais (6px) clairement visible separe physiquement chaque groupe du
   precedent. On utilise un pseudo-element ::before plutot que margin+
   border-top pour eviter le hover-flickering et garantir la pleine
   largeur (label + timeline). */
.timeline .tl-row + .group-row {
  position: relative;
  margin-top: 14px;
}
.timeline .tl-row + .group-row::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -10px;
  height: 6px;
  background: #94a3b8;
  border-radius: 2px;
}
.vue-groupe .tl-row { min-height: 84px; }

/* -------- 18. Vue activité (cartes par groupe) -------- */
.vue-activite-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 16px;
  margin-top: 10px;
}
.group-card {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  padding: 16px;
  border-top: 4px solid;
  box-shadow: var(--sh-card);
  transition: transform var(--t-fast), box-shadow var(--t-fast);
}
.group-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-lg);
}
.group-card h3 {
  margin: 0 0 6px;
  font-size: 1.1em;
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
}
.group-card .anim-count {
  color: var(--c-text-muted);
  font-size: .82em;
  font-weight: 500;
}
.slot-block { margin-top: 12px; }
.slot-label {
  font-size: .72em;
  color: var(--c-text-muted);
  text-transform: uppercase;
  letter-spacing: .08em;
  font-weight: 700;
  margin-bottom: 6px;
}
.slot-items { display: flex; flex-wrap: wrap; gap: 6px; }
.slot-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 12px;
  border-radius: var(--r-pill);
  background: linear-gradient(135deg, #FFEDD5, #FED7AA);
  color: #9A3412;
  font-size: .85em;
  font-weight: 600;
  border: 1px solid #FDBA74;
  transition: box-shadow var(--t-fast);
}
.slot-tag:hover { box-shadow: var(--sh-sm); }
/* Bouton supprimer harmonisé : petit cercle subtil au repos, rouge au hover.
   Hérite des règles de tous les boutons "remove" / "close" du design system. */
.slot-tag .x,
.btn-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: rgba(154, 52, 18, .12);
  color: #9A3412;
  cursor: pointer;
  font-weight: 700;
  font-size: .9em;
  line-height: 1;
  border: none;
  font-family: inherit;
  transition: all var(--t-fast);
  flex-shrink: 0;
}
.slot-tag .x:hover,
.btn-remove:hover {
  background: var(--c-danger);
  color: #fff;
  transform: scale(1.1);
}
.slot-tag .x:focus-visible,
.btn-remove:focus-visible {
  outline: 2px solid var(--c-danger);
  outline-offset: 2px;
}
.slot-add {
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--c-text-muted);
  font-size: .85em;
  font-weight: 500;
  border: 1px dashed var(--c-border-strong);
  cursor: pointer;
  font-family: inherit;
  transition: all var(--t-fast);
}
.slot-add:hover {
  background: var(--c-surface-2);
  color: var(--c-text);
  border-color: var(--c-secondary);
}

.anim-list {
  margin-top: 14px;
  border-top: 1px solid var(--c-border);
  padding-top: 10px;
}
.anim-list-label {
  font-size: .72em;
  color: var(--c-text-muted);
  text-transform: uppercase;
  letter-spacing: .08em;
  font-weight: 700;
  margin-bottom: 8px;
}
.anim-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  border-left: 3px solid;
  padding-left: 12px;
  margin-left: -10px;
  font-size: .92em;
}
.anim-row .anim-name { flex: 1; font-weight: 600; }
.anim-row .anim-time { color: var(--c-text-muted); font-family: var(--font-mono); font-size: .85em; }
.group-card-outings { margin-top: 12px; }

.day-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 12px 0 8px;
  padding: 0 4px;
}
.day-header h2 { margin: 0; font-size: 1.15em; color: var(--c-text); }
.day-header .day-meta { color: var(--c-text-muted); font-size: .9em; }

/* -------- 19. Empty state -------- */
.empty {
  padding: 60px 24px;
  text-align: center;
  color: var(--c-text-muted);
  font-size: .95em;
}

/* -------- 20. Onboarding TOC nav -------- */
nav.toc { display: flex; flex-direction: column; gap: 4px; }
nav.toc a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: var(--r-md);
  color: var(--c-text-soft);
  text-decoration: none;
  font-weight: 500;
  font-size: .92em;
  transition: all var(--t-fast);
  border: 1px solid transparent;
}
nav.toc a:hover {
  background: var(--c-surface-2);
  color: var(--c-text);
}
nav.toc a.active {
  background: linear-gradient(135deg, var(--c-primary-soft), #FFE4E1);
  color: var(--c-primary-text);
  border-color: var(--c-primary);
  font-weight: 600;
}
nav.toc a.done {
  color: var(--c-success-text);
  background: var(--c-success-soft);
}
nav.toc a.done::before {
  content: "✓ ";
  font-weight: 700;
}

section {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  padding: 22px 26px;
  margin-bottom: 18px;
  box-shadow: var(--sh-card);
}
section h2 {
  margin: 0 0 6px;
  color: var(--c-primary);
  font-size: 1.25em;
}

.row { display: flex; gap: 12px; flex-wrap: wrap; }
.row > div { flex: 1; min-width: 200px; }

.footer-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--c-border);
}

/* -------- 21. Login / change-password screens -------- */
body.auth-page main {
  max-width: 420px;
  margin: 8vh auto;
  padding: 36px 32px;
  background: var(--c-surface);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  border: 1px solid var(--c-border);
}
body.auth-page h1 {
  text-align: center;
  margin: 0 0 8px;
  background: linear-gradient(135deg, var(--c-primary), var(--c-accent));
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-size: 1.6em;
}
body.auth-page .help {
  text-align: center;
  margin-bottom: 24px;
}
body.auth-page button[type=submit] {
  width: 100%;
  margin-top: var(--sp-4);
  padding: 12px;
  font-size: 1em;
}
body.auth-page .footer {
  text-align: center;
  margin-top: 22px;
  font-size: .9em;
  color: var(--c-text-muted);
}
body.auth-page .footer a { color: var(--c-secondary-hover); }

/* Password rules checklist (change-password) */
ul.pwd-rules {
  list-style: none;
  padding: 12px 14px;
  margin: 10px 0;
  background: var(--c-surface-2);
  border-radius: var(--r-md);
  border: 1px solid var(--c-border);
  font-size: .88em;
}
ul.pwd-rules li {
  padding: 3px 0;
  color: var(--c-text-muted);
  display: flex;
  align-items: center;
  gap: 8px;
}
ul.pwd-rules li::before {
  content: "○";
  color: var(--c-text-faint);
  font-weight: 700;
}
ul.pwd-rules li.ok { color: var(--c-success-text); }
ul.pwd-rules li.ok::before { content: "✓"; color: var(--c-success); }

/* -------- 22. QR view (mobile-first) -------- */
.qr-confid, .confid {
  background: linear-gradient(90deg, #FEF3C7, #FDE68A);
  color: #78350F;
  padding: 14px 18px;
  font-weight: 700;
  font-size: 1em;
  text-align: center;
  border-bottom: 2px solid var(--c-warn);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.confid .icon { font-size: 1.3em; }

body.qr-page header {
  background: var(--grad-header);
  color: #fff;
  padding: 18px 20px;
  text-align: center;
  box-shadow: var(--sh-header);
}
body.qr-page header h1 { color: #fff; margin: 0 0 4px; font-size: 1.3em; }
body.qr-page header .meta { opacity: .9; font-size: .9em; }

.day-bar {
  background: #fff;
  padding: 12px;
  display: flex;
  gap: 8px;
  align-items: center;
  border-bottom: 1px solid var(--c-border);
  position: sticky;
  top: 0;
  z-index: 20;
}
.day-bar input[type=date] {
  flex: 1;
  padding: 8px 10px;
  font-size: .95em;
}
.day-bar button {
  padding: 8px 14px;
  background: var(--c-secondary);
  color: #fff;
  border: none;
  border-radius: var(--r-md);
}

/* PIN card */
.pin-card {
  background: var(--c-surface);
  margin: 5vh auto;
  max-width: 360px;
  padding: 32px 28px;
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  text-align: center;
}
.pin-card h2 {
  margin: 0 0 6px;
  background: linear-gradient(135deg, var(--c-primary), var(--c-accent));
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-size: 1.4em;
}
.pin-card .help { margin-bottom: 18px; }
.pin-input {
  width: 100%;
  padding: 14px;
  font-size: 1.5em;
  text-align: center;
  letter-spacing: 0.4em;
  font-family: var(--font-mono);
  border: 2px solid var(--c-border-strong);
  border-radius: var(--r-md);
}
.pin-input:focus {
  border-color: var(--c-secondary);
  box-shadow: 0 0 0 4px rgba(20, 184, 166, .15);
  outline: none;
}
.pin-card button {
  width: 100%;
  margin-top: 14px;
  padding: 12px;
  font-size: 1em;
}

/* Slots & staff QR */
.slots { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.slot {
  background: var(--c-surface-2);
  border-radius: var(--r-md);
  padding: 10px 12px;
  border-left: 3px solid var(--c-primary);
}
.slot-content { display: flex; flex-wrap: wrap; gap: 6px; }
.slot-content .item {
  background: #fff;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: .88em;
  font-weight: 600;
  border: 1px solid var(--c-border);
}

.outings { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.outing {
  background: linear-gradient(135deg, #EDE9FE, #DDD6FE);
  border: 1px solid #A78BFA;
  padding: 10px 14px;
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  color: #5B21B6;
}
.outing-time {
  font-family: var(--font-mono);
  font-size: .9em;
  color: #6D28D9;
}

.staff-block { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--c-border); }
.staff-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  font-size: .94em;
}
.staff-pill { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.staff-name { flex: 1; font-weight: 600; }
.staff-times { color: var(--c-text-muted); font-family: var(--font-mono); font-size: .88em; }

/* -------- 23. Countdown / pin display admin -------- */
.countdown {
  background: linear-gradient(135deg, var(--c-warn-soft), #FED7AA);
  border: 1px solid var(--c-warn);
  border-radius: var(--r-md);
  padding: 12px 16px;
  font-weight: 700;
  color: var(--c-warn-text);
  display: inline-block;
  font-family: var(--font-mono);
}
.pin-display {
  font-family: var(--font-mono);
  font-size: 2em;
  font-weight: 700;
  letter-spacing: 0.3em;
  background: linear-gradient(135deg, var(--c-primary), var(--c-accent));
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  padding: 12px;
  text-align: center;
  border: 2px dashed var(--c-primary);
  border-radius: var(--r-md);
  margin: 10px 0;
}

pre {
  background: #1E293B;
  color: #E2E8F0;
  padding: 14px;
  border-radius: var(--r-md);
  font-size: .85em;
  overflow-x: auto;
  font-family: var(--font-mono);
}

/* -------- 24. Utilities -------- */
.text-muted { color: var(--c-text-muted); }
.text-soft { color: var(--c-text-soft); }
.text-center { text-align: center; }

/* -------- 24bis. Utilitaires (suite Sprint C chantier-q2-2026) --------
   Tailwind-like, alignes sur les --sp-N existants.
   Sizing : xs=4 sm=8 md=12 lg=16 xl=20 2xl=24 3xl=32
   Valeurs orphelines (6/10/18px) : utiliser une classe contextuelle plus
   bas dans la section 24ter (composants) plutot qu'un utilitaire pollue.
*/
.mt-xs  { margin-top: var(--sp-1); }
.mt-sm  { margin-top: var(--sp-2); }
.mt-md  { margin-top: var(--sp-3); }
.mt-lg  { margin-top: var(--sp-4); }
.mt-xl  { margin-top: var(--sp-5); }
.mt-2xl { margin-top: var(--sp-6); }
.mb-sm  { margin-bottom: var(--sp-2); }
.mb-md  { margin-bottom: var(--sp-3); }
.mb-lg  { margin-bottom: var(--sp-4); }

.nowrap        { white-space: nowrap; }
.is-hidden     { display: none !important; }
.text-help     { font-size: .88em; color: var(--c-text-soft); }
.text-help-sm  { font-size: .92em; }
.text-help-xs  { font-size: .85em; }
.text-help-xxs { font-size: .82em; color: var(--c-text-muted); }
.empty-msg     { color: var(--c-text-soft); font-style: italic; }
.text-success  { color: var(--c-success-text); }
.text-warn     { color: var(--c-warn-text); }
.text-danger   { color: var(--c-danger-text); }
.text-italic   { font-style: italic; }
.label-radio-block { display: block; }
.label-radio-block + .label-radio-block { margin-top: var(--sp-2); }

/* -------- 24ter. Composants dedies (Sprint C chantier-q2-2026) --------
   Classes composant pour bloc HTML genere via innerHTML avec mise en page
   complexe. Chaque classe reproduit a l'identique le style inline
   d'origine — verifie pixel-perfect au refacto. */

/* h3 "Equipe" sidebar planning + h3 sections admin */
.h3-section-spaced { margin-top: 18px; }

/* Badges header admin (sg-badge / ar-badge) — etat initial cache */
.badge-counter-hidden {
  margin-left: 6px;
  background: var(--c-danger);
  color: #fff;
}

/* SLA / lien aide en pied de sidebar admin */
.sidebar-footer-link {
  display: inline-block;
  margin-top: 18px;
  font-size: .88em;
  color: var(--c-text-muted);
  border-top: 1px solid var(--c-border);
  padding-top: 10px;
}

/* Bloc periode preparation (admin alerte) */
.period-pending-help {
  color: var(--c-text-soft);
  font-size: .92em;
}

/* QR : cadre image + code URL */
.qr-frame {
  margin-top: 12px;
  text-align: center;
  background: #fff;
  border-radius: 12px;
  padding: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .12);
  display: inline-block;
  width: 100%;
  box-sizing: border-box;
}
.qr-caption {
  margin-top: 10px;
  font-size: .92em;
}
.url-display {
  background: #ECEFF1;
  padding: 6px 10px;
  display: inline-block;
  margin-top: 6px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  word-break: break-all;
}
.url-display-sm {
  background: #ECEFF1;
  padding: 4px 8px;
  display: inline-block;
  margin-top: 4px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  word-break: break-all;
}
.password-inline {
  background: #ECEFF1;
  padding: 3px 7px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
}

/* Form reset password admin */
.reset-pwd-form {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.reset-pwd-label {
  font-weight: normal;
  font-size: .9em;
}
.reset-pwd-row {
  display: flex;
  gap: 6px;
}
.checkbox-inline-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: normal;
}

/* Cellule td actions (table accounts admin) */
.td-actions   { text-align: center; }
.td-nowrap    { white-space: nowrap; }

/* Usage tableau admin */
.usage-row-realtime { background: var(--c-info-soft); }
.usage-cell-label-meta { font-weight: 400; color: var(--c-text-muted); font-size: .85em; }
.usage-cell-detail     { color: var(--c-text-muted); font-size: .82em; margin-left: 6px; }
.usage-reset-bar {
  margin-bottom: 10px;
  display: flex;
  justify-content: flex-end;
}
.th-w-50  { width: 48%; }
.th-w-140 { width: 140px; }

/* Suggestions admin */
.badge-new-flash {
  background: var(--c-danger);
  color: #fff;
  animation: badgepulse 1.6s ease-in-out infinite;
  margin-right: 6px;
}
.sg-card-clickable { cursor: pointer; }
.sg-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}
.sg-thread-collapsed {
  margin-top: 14px;
  border-top: 1px solid var(--c-border);
  padding-top: 12px;
}
.tg-test-bar {
  margin: 8px 0 14px;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.tg-test-out { font-size: .92em; }
.sg-messages-scroll {
  max-height: 340px;
  overflow: auto;
  padding: 6px;
  background: var(--c-surface-2);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sg-msg-system {
  align-self: center;
  max-width: 90%;
  background: #FFF8E1;
  border: 1px dashed #F59E0B;
  border-radius: 8px;
  padding: 6px 12px;
  font-size: .85em;
  color: #92400E;
  font-style: italic;
  text-align: center;
}
.sg-msg-system-time {
  font-size: .75em;
  color: #A16207;
  font-style: normal;
  margin-top: 2px;
}
.sg-msg {
  max-width: 85%;
  border-radius: 10px;
  padding: 8px 12px;
}
.sg-msg-mine     { align-self: flex-end; }
.sg-msg-other    { align-self: flex-start; }
.sg-msg-admin    { background: var(--c-info-soft); border: 1px solid var(--c-info); }
.sg-msg-director { background: #fff; border: 1px solid var(--c-border); }
.sg-msg-meta {
  font-size: .75em;
  color: var(--c-text-muted);
  font-weight: 600;
  margin-bottom: 4px;
}
.sg-msg-body {
  white-space: pre-wrap;
  font-size: .94em;
}
.sg-reply-form {
  margin-top: 10px;
  display: flex;
  gap: 8px;
  flex-direction: column;
}
.sg-reply-textarea { width: 100%; }
.sg-reply-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* Planning : select periode toolbar */
.period-pick-select {
  padding: 5px 8px;
  border: 1px solid var(--c-border-strong);
  border-radius: 6px;
  font: inherit;
  max-width: 280px;
}

/* Planning : div row util */
.row-flex-gap {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

/* Planning : sortie modal */
.modal-out-group-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  margin-bottom: 6px;
  background: #fff;
}
.modal-out-group-label {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  margin: 0;
  cursor: pointer;
  font-weight: 600;
}
.modal-out-children-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: .85em;
  color: var(--c-text-muted);
  margin: 0;
}
.modal-out-children-input {
  width: 70px;
  padding: 5px 8px;
}
.modal-anim-list-scroll {
  max-height: 240px;
  overflow: auto;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  padding: 8px;
  background: var(--c-surface-2);
}
.modal-row-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 10px;
}
.modal-anim-required-input { max-width: 100px; }
.modal-comment-textarea {
  resize: vertical;
  font-family: inherit;
  font-size: .95em;
}
.modal-anim-warnings { margin-top: 8px; }
.modal-anim-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  margin: 0;
  font-weight: 500;
  cursor: pointer;
  border-bottom: 1px solid var(--c-border);
}
.modal-anim-pill-small { width: 10px; height: 10px; }

/* Planning : extra hours block (heures complementaires) */
.extra-hours-block {
  margin-top: 14px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  padding: 8px 12px;
  background: var(--c-surface-2);
}
.extra-hours-summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--c-text);
}
.extra-hours-help {
  margin: 8px 0 6px;
}
.extra-hours-list {
  max-height: 220px;
  overflow: auto;
  margin: 6px 0;
}
.extra-hours-form {
  display: grid;
  grid-template-columns: 1fr 90px 130px;
  gap: 6px;
  align-items: end;
}
.extra-hours-add-btn {
  height: 38px;
  /* Ligne 2 : pousse a droite sous Date. */
  grid-column: 3;
  justify-self: end;
  width: 100%;
}
.extra-hours-included-label {
  /* Ligne 2 : occupe les 2 premieres colonnes (sous Motif + Heures). */
  grid-column: 1 / span 2;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: .9em;
  white-space: nowrap;
  padding-bottom: 8px;
}
.extra-hours-empty {
  color: var(--c-text-muted);
  text-align: center;
  font-size: .9em;
  margin: 6px 0;
}
.extra-hours-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--c-border);
  font-size: .92em;
}
.extra-hours-date {
  color: var(--c-text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 88px;
}
.extra-hours-amount {
  font-weight: 600;
  min-width: 50px;
}
.extra-hours-reason { flex: 1; }
.extra-hours-included-toggle {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: .85em;
  color: var(--c-text-muted);
  white-space: nowrap;
  cursor: pointer;
}
.extra-hours-del-btn {
  padding: 3px 8px;
  font-size: .85em;
}

/* Planning : alerte info modal print + outing errors */
.alert-tight {
  margin: 6px 0 12px;
}
.outing-errors {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.outing-error-line {
  font-size: .82em;
  color: var(--c-danger-text);
  font-weight: 600;
}

/* Planning : anim warnings (in outing modal) */
.anim-no-coverage {
  color: var(--c-danger);
  font-weight: 700;
  margin-left: 6px;
}
.anim-partial-coverage {
  color: var(--c-warn);
  font-weight: 700;
  margin-left: 6px;
}

/* Planning : staff list label (sidebar) */
.staff-role-label {
  font-size: .7em;
  color: var(--c-text-soft);
  text-transform: none;
  letter-spacing: 0;
}
.group-arrows-wrap {
  margin-right: 2px;
}

/* Planning : ligne anim "aucun" dans grid horaire */
.tl-empty-label {
  color: var(--c-text-soft);
  font-style: italic;
}

/* Planning : timeline label animateur (2 lignes) */
.tl-label-stacked {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
}
.tl-label-stacked-row {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
}
.tl-label-hours {
  font-weight: 600;
}

/* Modal print mode radio labels */
.print-mode-radio { display: block; }
.print-mode-radio + .print-mode-radio { margin-top: 6px; }

/* Lien qui herite de la couleur du parent (utilise dans banners) */
.link-inherit { color: inherit; }

/* Planning : staff arrows + role label (sidebar) */
/* (deja .staff-role-label et .group-arrows-wrap definis plus haut) */

/* Planning : help text grise periode dans modal */
.modal-period-help {
  color: #78909C;
  font-size: .92em;
}

/* -------- 24ter. Page auth requise (403 fallback) --------
   Sprint B chantier-q2-2026 : redirectToLogin() injecte ce markup dans
   document.body.innerHTML quand /api/me echoue (401). Affiche un card
   centre + bouton vers /login.html. En mode normal le card flash ~50ms
   avant que window.location.replace prenne le relais — il est surtout
   visible sur les webviews qui avalent le redirect silencieux. Duplique
   a l'identique dans admin.html, planning.html, onboarding.html. */
.auth-required-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--c-bg);
}
.auth-required-card {
  max-width: 420px;
  text-align: center;
  background: var(--c-surface);
  padding: 32px 28px;
  border-radius: var(--r-lg);
  box-shadow: var(--sh-lg);
}
.auth-required-card h1 {
  color: var(--c-action);
  margin: 0 0 12px;
  font-size: 1.4em;
}
.auth-required-card p {
  color: var(--c-text-soft);
  margin: 0 0 22px;
  line-height: 1.5;
}
.auth-required-card .auth-required-hint {
  color: var(--c-text-muted);
  font-size: .85em;
  margin: 18px 0 0;
}

/* -------- 24bis. Sidebar collapsible (planning) --------
   Sprint chantier-q2-2026 : languette pour ouvrir/fermer le sidebar
   groupes/equipe sur planning.html. Scope strict via .layout--collapsible
   pour ne pas affecter admin.html / onboarding.html qui partagent .layout
   et le selecteur global `aside, .layout > nav`. */
.layout--collapsible {
  position: relative;
  --sidebar-w: 260px;
  grid-template-columns: var(--sidebar-w) 1fr;
  transition: grid-template-columns var(--t-base);
}
.layout--collapsible.is-sidebar-collapsed { --sidebar-w: 0px; }
.layout--collapsible aside#planning-sidebar {
  overflow: hidden;
  transition: padding var(--t-base), border-right-width var(--t-base);
}
.layout--collapsible aside#planning-sidebar.collapsed {
  padding-left: 0;
  padding-right: 0;
  border-right-width: 0;
}
.sidebar-toggle {
  position: absolute;
  top: 50%;
  left: var(--sidebar-w);
  transform: translate(-50%, -50%);
  width: 22px;
  height: 56px;
  padding: 0;
  border: 1px solid var(--c-border-strong);
  background: var(--c-surface);
  color: var(--c-text-soft);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-size: 1.2em;
  line-height: 1;
  transition: left var(--t-base), background var(--t-fast);
  z-index: 5;
}
/* transform redefini pour neutraliser le selecteur global L.553
   `button:where(:not(.btn)...):hover { transform: translateY(-1px); }`
   qui sinon ecrasait le translate(-50%, -50%) du centrage absolu et
   faisait sauter la languette de ~28px vers le bas. */
.sidebar-toggle:hover {
  background: var(--c-surface-2);
  transform: translate(-50%, -50%);
}
@media (prefers-reduced-motion: reduce) {
  .layout--collapsible,
  .layout--collapsible aside#planning-sidebar,
  .sidebar-toggle { transition: none; }
}

/* -------- 24quater. Module Actus (Sprint Actus.2 chantier-q2-2026) --------
   Bouton "Actus" dans .app-user du header + modal news + liste markdown
   rendered (marked + DOMPurify cote front). Le bouton herite naturellement
   du style .app-user button (transparent + border semi-blanche). On ajoute
   juste le badge integre et les styles modal/liste.
*/
.header-news-btn {
  display: inline-flex;
  align-items: center;
  gap: 0;
}
.news-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 7px;
  min-width: 18px;
  border-radius: 10px;
  background: var(--c-danger);
  color: #fff;
  font-size: .82em;
  font-weight: 600;
  text-align: center;
  line-height: 1.2;
}
.news-badge[hidden] { display: none; }

/* <dialog> natif HTML5 : on override le styling par defaut pour matcher
   le look des autres modals du site (.modal/.modal-bg pattern existant). */
.news-modal {
  width: 92%;
  max-width: 760px;
  max-height: 88vh;
  margin: auto;
  padding: 0;
  border: none;
  border-radius: var(--r-xl);
  background: var(--c-surface);
  box-shadow: var(--sh-lg);
  overflow: hidden;
}
.news-modal::backdrop {
  background: rgba(15, 23, 42, .55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.news-modal .modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  border-bottom: 1px solid var(--c-border);
}
.news-modal .modal-header h2 {
  margin: 0;
  color: var(--c-primary);
  font-size: 1.2em;
  font-weight: 700;
}
.news-modal .modal-close {
  background: transparent;
  border: none;
  font-size: 1.6em;
  line-height: 1;
  color: var(--c-text-muted);
  cursor: pointer;
  padding: 4px 10px;
  border-radius: var(--r-md);
  font-family: inherit;
  transition: all var(--t-fast);
}
.news-modal .modal-close:hover {
  background: var(--c-surface-2);
  color: var(--c-text);
}
.news-modal .modal-body {
  padding: 20px 24px;
  overflow: auto;
  max-height: calc(88vh - 64px);
}
.news-list {
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.news-item {
  padding-bottom: 18px;
  border-bottom: 1px solid var(--c-border);
}
.news-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.news-item h3 {
  margin: 0 0 4px;
  color: var(--c-action);
}
.news-item time {
  display: block;
  color: var(--c-text-muted);
  font-size: .85em;
  margin-bottom: 10px;
}
.news-item .news-body { line-height: 1.55; }
.news-item .news-body p { margin: 0 0 10px; }
.news-item .news-body p:last-child { margin-bottom: 0; }
.news-item .news-body h2 { margin: 14px 0 6px; font-size: 1.1em; }
.news-item .news-body ul,
.news-item .news-body ol { margin: 6px 0 10px 18px; }
.news-item .news-body a { color: var(--c-primary); }
.news-item .news-body code {
  background: var(--c-surface-2);
  padding: 1px 5px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: .92em;
}

/* Sprint Actus.3 : mode editor (boutons admin + form markdown). */
.news-list-admin-new {
  margin-bottom: 16px;
}
.news-item-admin-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.news-item-admin-actions button {
  font-size: .85em;
  padding: 4px 10px;
}
.news-editor {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.news-editor-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.news-editor-field span {
  font-weight: 600;
  font-size: .92em;
  color: var(--c-text-soft);
}
.news-editor-field input {
  padding: 8px 10px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: 1em;
}
.news-editor-toolbar {
  display: flex;
  gap: 6px;
  padding: 6px 0;
  border-top: 1px solid var(--c-border);
  border-bottom: 1px solid var(--c-border);
  flex-wrap: wrap;
}
.news-editor-toolbar button {
  padding: 6px 14px;
  min-width: 44px;
  background: #fff;
  color: var(--c-text);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: .95em;
  font-family: inherit;
  font-weight: 700;
  transition: all var(--t-fast);
}
.news-editor-toolbar button:hover {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  color: var(--c-primary-text);
}
/* Bold + italic gardent leur formattage typo dans le label pour evoquer l'effet */
.news-editor-toolbar button[data-md="bold"]   { font-weight: 900; }
.news-editor-toolbar button[data-md="italic"] { font-style: italic; font-weight: 700; }

/* Palette couleur dans la toolbar (5 swatches DS + bouton effacer).
   Choix : palette FIXE plutot que color picker natif. Le picker natif
   declenche un event 'input' en continu pendant le drag -> wrap a chaque
   pixel = nesting catastrophique. La palette fixe = 1 click = 1 wrap
   propre + zero ambiguite UX. */
.news-editor-palette {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 2px 4px;
  border-left: 1px solid var(--c-border-strong);
}
.news-editor-swatch {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 2px solid #fff;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--c-border-strong);
  transition: transform var(--t-fast), box-shadow var(--t-fast);
}
.news-editor-swatch:hover {
  transform: scale(1.15);
  box-shadow: 0 0 0 2px var(--c-text);
}
.news-editor-swatch:focus-visible {
  outline: 2px solid var(--c-secondary);
  outline-offset: 2px;
}
.news-editor-swatch-clear {
  background: #fff;
  color: var(--c-text);
  font-size: 1.1em;
  font-weight: 900;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.news-editor-swatch-clear:hover {
  background: var(--c-surface-2);
}
.news-editor textarea {
  width: 100%;
  min-height: 220px;
  font-family: var(--font-mono);
  font-size: .92em;
  padding: 10px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  resize: vertical;
  box-sizing: border-box;
}
.news-editor-preview {
  min-height: 220px;
  padding: 12px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface-2);
  line-height: 1.55;
}
.news-editor-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 8px;
  gap: 8px;
  flex-wrap: wrap;
}
.news-editor-actions-right {
  display: flex;
  gap: 8px;
}
.news-editor-error {
  color: var(--c-danger-text);
  background: var(--c-danger-soft);
  padding: 8px 12px;
  border-radius: var(--r-md);
  border-left: 3px solid var(--c-danger);
}
.news-editor-error[hidden] { display: none; }

/* -------- 24quinquies. Toast notifications (Sprint BUG.3a) --------
   Helper window.showToast() defini dans js/toast.js. Position fixe top-right,
   stack vertical des toasts. Auto-disparait apres 4s (par defaut). */
.toast-container {
  position: fixed;
  top: 80px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 200;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  min-width: 220px;
  max-width: 380px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  box-shadow: var(--sh-lg);
  font-size: .94em;
  font-weight: 500;
  border-left: 4px solid transparent;
  animation: toast-in .25s ease;
}
.toast-success {
  background: var(--c-success-soft);
  color: var(--c-success-text);
  border-left-color: var(--c-success);
}
.toast-error {
  background: var(--c-danger-soft);
  color: var(--c-danger-text);
  border-left-color: var(--c-danger);
}
.toast-info {
  background: var(--c-info-soft);
  color: var(--c-info-text);
  border-left-color: var(--c-info);
}
.toast-warn {
  background: var(--c-warn-soft);
  color: var(--c-warn-text);
  border-left-color: var(--c-warn);
}
.toast-fadeout {
  animation: toast-out .2s ease forwards;
}
@keyframes toast-in {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes toast-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(20px); }
}
@media (prefers-reduced-motion: reduce) {
  .toast, .toast-fadeout { animation: none; }
}
@media (max-width: 600px) {
  .toast-container {
    top: auto;
    bottom: 12px;
    right: 12px;
    left: 12px;
  }
  .toast { min-width: 0; max-width: none; }
}

/* -------- 25. Responsive -------- */
@media (max-width: 768px) {
  .layout { grid-template-columns: 1fr; }
  aside, .layout > nav {
    border-right: none;
    border-bottom: 1px solid var(--c-border);
  }
  /* Mobile : sidebar empile au-dessus de main, languette sans objet. */
  .layout--collapsible {
    grid-template-columns: 1fr;
    --sidebar-w: 100%;
  }
  .layout--collapsible aside#planning-sidebar,
  .layout--collapsible aside#planning-sidebar.collapsed {
    padding: 18px 16px;
    border-right-width: 0;
    overflow: visible;
  }
  .sidebar-toggle { display: none; }
  .tl-row { grid-template-columns: 120px 1fr; }
  .tl-header { grid-template-columns: 120px 1fr; }
  .app-header { padding: 10px 14px; }
  .app-nav { width: 100%; justify-content: flex-start; }
  main { padding: 14px; }
  .toolbar { padding: 10px 14px; }
}

@media (max-width: 480px) {
  body.qr-page main { padding: 12px; }
  .pin-card { margin: 2vh auto; padding: 24px 20px; }
  h1 { font-size: 1.25rem; }
  h2 { font-size: 1.1rem; }
}

/* Sprint 8 P3-5 : touch targets QR mobile >=44px (recommandation WCAG 2.5.5
   Target Size + Apple HIG / Material). Avant : prev-day/next-day a 8px 14px
   = ~32px de hauteur, en dessous de la cible mobile minimale. */
@media (max-width: 600px) {
  .day-bar button {
    min-width: 44px;
    min-height: 44px;
    padding: 10px 16px;
    font-size: 1.1em;
  }
  .day-bar input[type=date] {
    min-height: 44px;
    padding: 10px 12px;
  }
}

/* -------- 26. Print -------- */
@media print {
  .app-header, .toolbar, .alerts-card, button, .modal-bg { display: none !important; }
  body { background: #fff; }
  .timeline, .group-card { box-shadow: none; }
}

/* -------- 27. Utilitaires (Item 8 ROADMAP-suite, refacto progressif) ----------
   But : remplacer les `style="..."` recurrents par des classes pour pouvoir
   un jour retirer `style-src-attr 'unsafe-inline'` du CSP. Etat actuel :
   refacto partiel — les styles dynamiques (interpolation JS pour couleurs/
   positions) restent inline car ils dependent de valeurs runtime. La suite
   du refacto necessite un helper JS qui applique les styles via DOM api
   apres innerHTML, et un test complet en navigateur.
   ---------------------------------------------------------------------------- */
.u-m-0           { margin: 0; }
.u-mt-10         { margin-top: 10px; }
.u-mt-12         { margin-top: 12px; }
.u-mt-14         { margin-top: 14px; }
.u-mr-auto       { margin-right: auto; }
.u-w-auto        { width: auto; }
.u-flex-1        { flex: 1; }
.u-flex-center   { display: flex; align-items: center; }
.u-text-sm       { font-size: .85em; }
.u-helper-text   { font-weight: 400; color: var(--c-text-muted); font-size: .88em; }
.u-empty-msg     { color: var(--c-text-muted); text-align: center; margin: 12px 0; }
.u-row-info      { width: 100%; margin-top: 8px; font-size: .85em; }

/* Sprint UX-1 : modale "Saisie rapide multi-jours" */
.bulk-days-fieldset {
  border: 1px solid var(--c-border);
  border-radius: 8px;
  padding: 8px 12px;
  margin-top: 12px;
}
.bulk-days-legend {
  padding: 0 6px;
  font-weight: 600;
}
.bulk-days-actions {
  gap: 6px;
  margin-bottom: 8px;
}
.bulk-days-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 4px;
  max-height: 280px;
  overflow-y: auto;
  padding: 4px;
}
.day-checkbox {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border: 1px solid var(--c-border);
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.92em;
}
.day-checkbox:has(input:checked) {
  background: var(--c-primary-tint, #E1F5FE);
  border-color: var(--c-primary, #0277BD);
}
.day-checkbox .day-name {
  font-weight: 600;
  min-width: 30px;
}
.day-checkbox .day-num {
  color: var(--c-text-muted);
  font-size: 0.88em;
}

/* -------- 28. Planning viewport : top persistant + scrolls independants --------
   Sprint UX sticky top (chantier-q2-2026).
   body.planning-viewport = scope strict planning.html uniquement.
   CRITIQUE : min-height: 0 requis sur TOUS les enfants flex qui doivent
   scroller, sinon overflow:auto ne se declenche jamais (piege flex classique).
   ---------------------------------------------------------------------------- */
body.planning-viewport {
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
body.planning-viewport > header { flex: 0 0 auto; }
.planning-page {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.planning-top {
  flex: 0 0 auto;
  z-index: 5;
  background: var(--bg-page, #fff);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
}
.planning-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: row;
  position: relative;
}
.planning-side {
  flex: 0 0 var(--planning-side-w, 280px);
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  border-right: 1px solid var(--border, #e5e7eb);
}
.planning-grid {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

/* Positionnement de la languette dans le nouveau layout flex */
body.planning-viewport .sidebar-toggle {
  left: var(--planning-side-w, 280px);
}
body.planning-viewport.sidebar-collapsed .sidebar-toggle {
  left: 0;
}

/* Collapse sidebar via body */
body.planning-viewport.sidebar-collapsed .planning-side { display: none; }

/* Compactage automatique du bloc alertes au scroll */
.planning-alerts {
  overflow: hidden;
  transition: padding .22s ease;
}
.planning-alerts-summary { display: none; }
body.planning-viewport.is-scrolled .planning-alerts-detail { display: none; }
body.planning-viewport.is-scrolled .planning-alerts-summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--warning-bg, #FEF3C7);
  color: var(--warning-fg, #92400E);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
body.planning-viewport.is-scrolled .planning-alerts { padding-top: 6px; padding-bottom: 6px; }

/* Print : ne pas verrouiller la hauteur (impression tronquee sinon) */
@media print {
  body.planning-viewport { height: auto; overflow: visible; display: block; }
  .planning-page, .planning-body, .planning-side, .planning-grid {
    overflow: visible;
    min-height: 0;
  }
  .planning-alerts-summary { display: none !important; }
  .planning-alerts-detail { display: block !important; }
}

/* Mobile : desactiver le viewport lock sur petit ecran */
@media (max-width: 768px) {
  body.planning-viewport {
    height: auto;
    overflow: visible;
    display: block;
  }
  .planning-page, .planning-body { display: block; }
  .planning-side, .planning-grid { overflow: visible; min-height: 0; }
}
