/* =============================================================================
   El Ourwa — Styles des écrans de DIRECTION
   =============================================================================
   Système de design « Organic » : fond crème, accent terre cuite, secondaire
   olive, titres Caprasimo, corps Figtree, contrôles en pilule.

   POURQUOI CETTE COUCHE DE JETONS
   Toute la feuille (1 600 lignes) consomme ces variables. Les retuner ici
   rhabille donc l'application entière sans toucher aux 47 pages : le HTML
   existant est conservé, seule l'apparence change. Les anciens noms de jetons
   (--primary, --secondary...) sont donc GARDÉS, mais pointent désormais sur les
   valeurs Organic — d'où les alias plus bas.

   LES ÉCRANS PARENTS NE SONT PAS CONCERNÉS : ils chargent assets/css/parent.css
   et n'incluent jamais ce fichier.
   ============================================================================= */

/* --- Reset & Base --- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* ── M8 : la palette approuvée (docs/maquette-m8/) ───────────────────── */
  --o-bg:        #F6F1E6;   /* crème, le sol de l'interface */
  --o-surface:   #FBF8F2;   /* sable, les surfaces posées dessus */
  --o-ink:       #14212B;   /* encre chaude, presque noire */
  --o-accent:    #0E2A36;   /* terre cuite */
  --o-accent-2:  #7A5A24;   /* olive, le second accent */
  --o-divider:   rgba(20,33,43,.14);

  /* Rampes tonales — une seule échelle de clarté partagée, donc un même
     échelon de deux rôles a la même valeur visuelle. */
  --o-n-100:#FBF8F2; --o-n-200:#F3EEE4; --o-n-300:#E9E4D8; --o-n-400:#D5CEC1;
  --o-n-500:#A9A395; --o-n-600:#7C7668; --o-n-700:#5B6B75; --o-n-800:#3B4B55;
  --o-n-900:#14212B;

  --o-a-100:#FAF3E7; --o-a-200:#F3E7D3; --o-a-300:#E8D3AE; --o-a-400:#D9BD8C;
  --o-a-500:#C29B5E; --o-a-600:#A98245; --o-a-700:#7A5A24; --o-a-800:#5E4419;
  --o-a-900:#3F2D10;

  --o-g-100:#f2f5e9; --o-g-200:#e5ebd5; --o-g-300:#cdd7b4; --o-g-400:#adb98e;
  --o-g-500:#8b986c; --o-g-600:#6f7d52; --o-g-700:#57623f; --o-g-800:#3f472e;
  --o-g-900:#2a2f1e;

  /* ── M8 : la typographie approuvée ───────────────────────────────────────
     Titres en serif, texte en sans-serif système. Aucune police tierce n'est
     téléchargée : la maquette s'en tient aux polices du poste, et une requête
     de moins vers un hôte étranger est une dépendance de moins dans la CSP. */
  --font-heading: 'Marcellus', 'Amiri', Georgia, serif;
  --font-body:    'Inter', 'IBM Plex Sans Arabic', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* ── Alias historiques — tout le reste de la feuille passe par eux ───── */
  --primary:        var(--o-accent);
  --primary-light:  #C29B5E;
  --primary-dark:   #17394A;
  --secondary:      var(--o-accent-2);
  --secondary-light:var(--o-g-400);
  --bg:             var(--o-bg);
  --bg-card:        #ffffff;      /* la carte, un cran plus clair que le sol */
  --text:           var(--o-ink);
  --text-light:     var(--o-n-700);
  /* n-600 (#857768) sur le crème ne donne que 3,9:1 : sous le seuil de 4,5:1
     exigé pour un texte de 12 px, et ce ton sert justement aux petites
     étiquettes en capitales. On descend d'un échelon. */
  --text-muted:     var(--o-n-700);
  --success:        #2E6A35;
  --error:          #B42318;
  --warning:        #94560A;
  --border:         var(--o-n-300);

  /* Ombres teintées d'encre chaude, jamais grises : une ombre neutre sur un
     fond crème donne un gris sale. Volontairement discrètes. */
  --shadow:    0 1px 2px rgba(42,38,34,.06);
  --shadow-md: 0 1px 2px rgba(42,38,34,.06), 0 6px 20px rgba(42,38,34,.05);
  --shadow-lg: 0 2px 6px rgba(42,38,34,.08), 0 12px 32px rgba(42,38,34,.07);
  --shadow-xl: 0 16px 40px rgba(42,38,34,.14);

  /* Les rayons de la maquette : 9 px pour les contrôles, 14 px pour les
     surfaces. Trois crans, pas un de plus. */
  --radius:      9px;
  --radius-lg:   14px;
  --radius-pill: 999px;
  --sidebar-width: 264px;
  --transition: all .18s cubic-bezier(.2,.6,.3,1);
}

html { font-size: 16px; scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-body); background: var(--bg); color: var(--text);
  line-height: 1.55; min-height: 100vh;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}

h1,h2,h3,h4 {
  font-family: var(--font-heading); font-weight: 400;
  line-height: 1.14; letter-spacing: -.015em;
}
h5,h6 { font-family: var(--font-body); font-weight: 700; line-height: 1.3; }

a { color: var(--primary); text-decoration: none; transition: var(--transition); }
a:hover { color: var(--primary-dark); }

/* Un seul anneau de focus pour toute l'application, visible sur crème. */
:focus-visible { outline: 2px solid var(--o-accent); outline-offset: 2px; border-radius: 4px; }
::selection { background: rgba(198,113,57,.24); }

/* --- Login Page styles : voir section "LOGIN PAGE — Restylé v2" en bas --- */

.form-group { margin-bottom: 1.5rem; position: relative; }
.form-group label {
  display: block; font-size: .85rem; font-weight: 600;
  color: var(--text); margin-bottom: .4rem;
}
.form-group input {
  width: 100%; padding: .75rem 1rem;
  border: 2px solid var(--border); border-radius: var(--radius);
  font-size: 1rem; font-family: inherit; color: var(--text);
  background: var(--bg); transition: var(--transition); outline: none;
}
.form-group input:focus {
  border-color: var(--primary); box-shadow: 0 0 0 3px rgba(198,113,57,.15);
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .75rem 1.5rem; border: none; border-radius: var(--radius);
  font-size: 1rem; font-weight: 600; font-family: inherit;
  cursor: pointer; transition: var(--transition); outline: none;
}
.btn-primary {
  /* M8 : aplat de terre cuite, pas de dégradé. Un bouton est une action, pas
     une matière — et le dégradé ajoutait une teinte brune imprévisible sur les
     écrans à faible gamut. */
  background: var(--o-accent);
  color: #fff; width: 100%;
}
.btn-primary:hover { background: var(--o-a-700); box-shadow: var(--shadow-md); filter: none; }
.btn-primary:active { transform: none; }

.btn-secondary {
  background: var(--bg-card); color: var(--text); border: 1px solid var(--border);
}
.btn-secondary:hover { border-color: var(--primary); color: var(--primary); }

.btn-success { background: var(--success); color: #fff; }
.btn-success:hover { filter: brightness(1.1); }

.btn-danger { background: var(--error); color: #fff; }
.btn-danger:hover { filter: brightness(1.1); }

.btn-sm { padding: .5rem 1rem; font-size: .875rem; }

.alert {
  padding: .75rem 1rem; border-radius: var(--radius); margin-bottom: 1.5rem;
  font-size: .9rem; font-weight: 500; animation: fadeIn .3s ease-out;
}
.alert-error { background: #FEF2F2; color: #991B1B; border: 1px solid #FECACA; }
.alert-success { background: #F0FDF4; color: #166534; border: 1px solid #BBF7D0; }
.alert-info { background: #EFF6FF; color: #1E40AF; border: 1px solid #BFDBFE; }

/* --- App Layout --- */
.app-layout { display: flex; min-height: 100vh; }

/* Aucune page ne defile horizontalement : c'est toujours un conteneur
   interieur (tableau, grille) qui prend le debordement en charge.
   ⚠ `clip`, PAS `hidden` : `overflow-x: hidden` sur body faisait de body un
   conteneur de defilement (overflow-y calcule `auto`) de la hauteur de son
   contenu — l'en-tete `position: sticky` de .page-header se collait a lui,
   jamais a la fenetre, et ne collait donc jamais (feuille d'origine, meme
   defaut ; corrige le 11/10/2026 avec l'accord du proprietaire). `clip` coupe
   le debordement sans creer de conteneur de defilement ; `hidden` reste
   devant, pour les navigateurs qui ignorent `clip` (comme avant chez eux). */
html, body { max-width: 100%; overflow-x: hidden; overflow-x: clip; }
.page-content, .page-header { min-width: 0; max-width: 100%; }

/* --- Sidebar --- */
.sidebar {
  width: var(--sidebar-width); height: 100vh; position: fixed; top: 0; inset-inline-start: 0; z-index: 100;
  display: flex; flex-direction: column;
  transition: transform .3s ease;
  overflow-y: auto;
}

.sidebar-header { padding: 1.5rem; border-bottom: 1px solid rgba(255,255,255,.1); }
.sidebar-logo {
  display: flex; align-items: center; gap: .75rem;
  font-family: 'Poppins', sans-serif; font-size: 1.3rem; font-weight: 700;
}
.sidebar-logo svg { color: var(--secondary); flex-shrink: 0; }

.sidebar-nav { flex: 1; padding: 1rem .75rem; display: flex; flex-direction: column; gap: .25rem; }

.sidebar-link {
  display: flex; align-items: center; gap: .75rem;
  padding: .7rem 1rem; border-radius: var(--radius);
  color: rgba(255,255,255,.7); font-size: .9rem; font-weight: 500;
  transition: var(--transition);
}
.sidebar-link:hover { background: rgba(255,255,255,.1); color: #fff; }
.sidebar-link.active {
  background: rgba(198,113,57,.3); color: #fff;
  box-shadow: inset 3px 0 0 var(--secondary);
}

.sidebar-icon { width: 22px; height: 22px; flex-shrink: 0; }
.sidebar-icon svg { width: 100%; height: 100%; }

.sidebar-footer { padding: 1rem .75rem; border-top: 1px solid rgba(255,255,255,.1); }
.sidebar-user { display: flex; align-items: center; gap: .75rem; padding: .5rem; margin-bottom: .5rem; }
.sidebar-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--secondary); color: #2e2b25;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .9rem; flex-shrink: 0;
}
.sidebar-user-info { display: flex; flex-direction: column; overflow: hidden; }
.sidebar-user-name { font-size: .85rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-user-role { font-size: .75rem; color: rgba(255,255,255,.5); }

.sidebar-logout { color: rgba(255,255,255,.5); }
.sidebar-logout:hover { color: var(--error); background: rgba(239,68,68,.15); }

.sidebar-toggle {
  display: none; align-items: center; justify-content: center;
  background: var(--bg-card); color: var(--text); border: 1px solid var(--o-n-300);
  border-radius: var(--radius); padding: .5rem; cursor: pointer;
}

/* --- Main Content --- */
/* `min-width: 0` EST INDISPENSABLE ICI.
   Un element flex vaut par defaut `min-width: auto` : il refuse de devenir
   plus etroit que son contenu. Un tableau large poussait donc .main-content
   a 965 px dans une fenetre de 613 px, et c'est la PAGE ENTIERE qui partait
   de travers — en-tete compris. Avec `min-width: 0`, l'element accepte de
   se reduire et le debordement retombe la ou il doit etre traite : dans le
   conteneur du tableau, qui defile pour lui-meme. */
.main-content {
  flex: 1; min-width: 0;
  margin-left: var(--sidebar-width);
  /* M8 : le contenu respire (le HANDOVER demande « aucune page ne défile
     horizontalement », pas « aucune marge »). L'en-tête de la coquille et
     l'en-tête de page reprennent toute la largeur par marge négative. */
  padding: 0 1.6rem 2.5rem;
  min-height: 100vh;
}
.main-content > .entete-app,
.main-content > .page-header { margin-inline: -1.6rem; max-width: none; }
/* Le contenu commence sous l'en-tête de page, jamais collé à lui. */
.main-content > .page-header { margin-block-end: 1.35rem; }

.page-header {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem;
  padding: 1.5rem 2rem; background: var(--bg-card); border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 50;
}
.page-title { font-size: 1.5rem; color: var(--text); }
.page-subtitle { font-size: .9rem; color: var(--text-light); margin-top: .15rem; }
.header-date { display: flex; align-items: center; gap: .4rem; font-size: .85rem; color: var(--text-muted); }

.page-content { padding: 2rem; }

/* --- KPI Cards --- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.25rem; margin-bottom: 2rem; }

.kpi-card {
  background: var(--bg-card); border-radius: var(--radius-lg); padding: 1.5rem;
  border: 1px solid var(--border); box-shadow: var(--shadow);
  transition: var(--transition); position: relative; overflow: hidden;
}
/* M8 : la carte ne saute plus au survol — un tableau de bord se lit, il ne
   s'anime pas — et le liseré de couleur a disparu (voir plus bas, `content: none`). */
.kpi-card:hover { box-shadow: var(--shadow-md); }
.kpi-card::before { content: none; }

.kpi-label { font-size: .8rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; font-weight: 600; }
.kpi-value { font-size: 2rem; font-weight: 800; color: var(--text); margin: .25rem 0; font-family: 'Poppins', sans-serif; }
.kpi-detail { font-size: .8rem; color: var(--text-light); }
.kpi-icon {
  position: absolute; top: 1rem; right: 1rem;
  width: 44px; height: 44px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, rgba(198,113,57,.1), rgba(198,113,57,.05));
}
.kpi-icon svg { width: 22px; height: 22px; color: var(--primary); }

/* --- Charts --- */
.charts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; }

.chart-card {
  background: var(--bg-card); border-radius: var(--radius-lg); padding: 1.5rem;
  border: 1px solid var(--border); box-shadow: var(--shadow);
}
.chart-card h3 { font-size: 1rem; margin-bottom: 1rem; color: var(--text); }
.chart-card canvas { max-height: 300px; }

/* --- Data Tables --- */
/* `overflow: hidden` COUPAIT les tableaux plus larges que la carte : les
   dernieres colonnes etaient inatteignables. On defile sur l'axe horizontal ;
   l'arrondi reste respecte, un conteneur de defilement rognant deja a son
   bord. */
.table-container {
  background: var(--bg-card); border-radius: var(--radius-lg);
  border: 1px solid var(--border); box-shadow: var(--shadow);
  overflow-x: auto; overflow-y: visible; margin-bottom: 2rem;
}
.table-header {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem;
  padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--border);
}
.table-header h3 { font-size: 1.1rem; }

table { width: 100%; border-collapse: collapse; }
thead th {
  text-align: left; padding: .75rem 1rem; font-size: .8rem;
  text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted); font-weight: 600; background: var(--bg);
  border-bottom: 2px solid var(--border);
}
tbody td { padding: .75rem 1rem; border-bottom: 1px solid var(--border); font-size: .9rem; }
tbody tr { transition: var(--transition); }
tbody tr:hover { background: rgba(198,113,57,.03); }
tbody tr:last-child td { border-bottom: none; }

.badge {
  display: inline-flex; align-items: center; padding: .2rem .6rem;
  border-radius: 20px; font-size: .75rem; font-weight: 600;
}
.badge-primary { background: rgba(198,113,57,.1); color: var(--primary); }
.badge-success { background: rgba(16,185,129,.1); color: var(--success); }
.badge-warning { background: rgba(245,158,11,.1); color: #B45309; }
.badge-danger { background: rgba(239,68,68,.1); color: var(--error); }

/* --- Forms & Cards --- */
.form-card {
  background: var(--bg-card); border-radius: var(--radius-lg); padding: 2rem;
  border: 1px solid var(--border); box-shadow: var(--shadow);
  /* M8 : 640 px laissait la moitié d'un écran de bureau vide à côté d'un
     formulaire à deux colonnes. 880 px garde une ligne de lecture courte et
     laisse les deux colonnes respirer. */
  max-width: 880px;
  margin-bottom: 2rem;
}
.form-card h3 { font-size: 1.2rem; margin-bottom: 1.5rem; padding-bottom: .75rem; border-bottom: 2px solid var(--border); }

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

select {
  width: 100%; padding: .75rem 1rem; border: 2px solid var(--border);
  border-radius: var(--radius); font-size: 1rem; font-family: inherit;
  color: var(--text); background: var(--bg); outline: none; transition: var(--transition);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236B7280' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center;
}
select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(198,113,57,.15); }

/* --- Modal --- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.5); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; z-index: 200;
  opacity: 0; visibility: hidden; transition: var(--transition);
}
.modal-overlay.active { opacity: 1; visibility: visible; }

.modal {
  background: var(--bg-card); border-radius: var(--radius-lg); padding: 2rem;
  width: 90%; max-width: 600px; max-height: 85vh; overflow-y: auto;
  box-shadow: var(--shadow-xl); transform: scale(.95); transition: var(--transition);
}
.modal-overlay.active .modal { transform: scale(1); }

.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1.5rem; padding-bottom: .75rem; border-bottom: 2px solid var(--border);
}
.modal-header h3 { font-size: 1.2rem; }
.modal-close {
  width: 32px; height: 32px; border: none; background: var(--bg);
  border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center;
  color: var(--text-light); transition: var(--transition);
}
.modal-close:hover { background: var(--error); color: #fff; }

.modal-footer { display: flex; gap: .75rem; justify-content: flex-end; margin-top: 1.5rem; padding-top: .75rem; border-top: 1px solid var(--border); }

/* --- Empty State --- */
.empty-state {
  text-align: center; padding: 3rem; color: var(--text-light);
}
.empty-state svg { width: 64px; height: 64px; margin-bottom: 1rem; color: var(--text-muted); }
.empty-state p { font-size: 1rem; }

/* --- Responsive Overrides --- */
.overflow-x { overflow-x: auto; }

/* --- Animations --- */
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.animate-slide-up { animation: slideUp .5s ease-out both; }
.animate-fade { animation: fadeIn .3s ease-out both; }

/* --- Responsive --- */
@media (max-width: 1024px) {
  .charts-grid { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  .sidebar { transform: translateX(-100%); }
  .sidebar.open { transform: translateX(0); }
  .sidebar-toggle { display: flex; }
  .main-content { margin-left: 0; }
  .page-header { padding: 1rem 1rem 1rem 3.5rem; }
  .page-content { padding: 1rem; }
  .kpi-grid { grid-template-columns: 1fr 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .charts-grid { grid-template-columns: 1fr; }
  .table-header { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 480px) {
  .kpi-grid { grid-template-columns: 1fr; }
}

/* --- Utility --- */
.mt-1 { margin-top: .5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mb-1 { margin-bottom: .5rem; }
.mb-2 { margin-bottom: 1rem; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-success { color: var(--success); }
.text-error { color: var(--error); }
.text-muted { color: var(--text-muted); }
.flex { display: flex; }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.gap-1 { gap: .5rem; }
.gap-2 { gap: 1rem; }
.hidden { display: none !important; }

/* --- Profile Cards --- */
.profile-card {
  background: var(--bg-card);
  border-radius: var(--radius-lg);
  padding: 2.5rem;
  border: 1px solid rgba(0, 0, 0, 0.05);
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.03);
  margin-bottom: 2rem;
  position: relative;
  overflow: hidden;
}
.profile-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; width: 100%; height: 6px;
  background: linear-gradient(90deg, var(--primary), var(--secondary));
}
.profile-header-card {
  display: flex; align-items: center; gap: 1.5rem; margin-bottom: 1.5rem;
  padding-bottom: 1.5rem; border-bottom: 1px solid var(--border);
}
.profile-avatar {
  width: 72px; height: 72px; border-radius: 50%; 
  background: linear-gradient(135deg, var(--primary-light), var(--primary)); 
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1.8rem; flex-shrink: 0;
  box-shadow: 0 4px 10px rgba(198,113,57, 0.3);
}
.profile-header-card h2 { font-size: 1.75rem; margin-bottom: .25rem; font-weight: 700; color: var(--text); }
.profile-info-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;
  padding: 1.5rem; background: var(--bg); border-radius: var(--radius-lg); font-size: .95rem;
  border: 1px solid var(--border);
}
.profile-info-grid div { display: flex; flex-direction: column; gap: 0.25rem; }
.profile-info-grid strong { color: var(--text-muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.5px; }

.bulletin {
  background: #fff; border-radius: 16px; 
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);
  padding: 3rem; margin-bottom: 3rem; 
  border: 1px solid #E5E7EB;
  max-width: 950px; margin-left: auto; margin-right: auto;
  position: relative;
}
.bulletin::before {
  content: ''; position: absolute;
  top: 0; left: 0; right: 0; height: 10px;
  background: linear-gradient(90deg, #474238, #c67139, #7a8a5e);
  border-radius: 16px 16px 0 0;
}
.bulletin-school .small { font-size: .8rem; margin-top: 0.25rem; }
.bulletin-table .matiere-cell { font-weight: 700; color: #1E293B; padding-left: 1.5rem; }
.bulletin-table .center { text-align: center; }
.bulletin-table .bold { font-weight: 800; font-size: 1.05rem; }
.bulletin-table .note-faible { color: #EF4444; }
.bulletin-table .note-bonne { color: #10B981; }
.bulletin-table .text-right { text-align: right; }
.moyenne-box {
  background: linear-gradient(135deg, #b2622d, #474238);
  border: none;
  color: #fff;
}
.moyenne-box .summary-label { color: #ffe1d0; }
.moyenne-box .summary-value,
.moyenne-box .summary-value.text-error,
.moyenne-box .summary-value.text-success { color: #fff !important; }

.appreciation-box { text-align: left; display: flex; flex-direction: column; justify-content: center; }
.summary-label {
  font-size: .8rem; text-transform: uppercase; letter-spacing: 1px;
  color: #64748B; font-weight: 700; margin-bottom: .75rem;
}
.summary-value { font-size: 2rem; font-weight: 800; font-family: 'Inter', sans-serif; }
.summary-appreciation {
  font-size: 1.15rem; font-weight: 700; color: #0F172A;
  margin-top: .25rem;
}
.signature-line {
  width: 200px; height: 1px; background: #94A3B8; margin-top: 4rem;
}

/* --- Print Styles --- */
@media print {
  .no-print, .sidebar, .sidebar-toggle, .page-header, .app-layout > .sidebar { display: none !important; }
  .main-content { margin-left: 0 !important; padding: 0 !important; }
  .page-content { padding: 0 !important; }
  body { background: #fff !important; }
  .bulletin {
    box-shadow: none !important; border: none !important;
    padding: 0 !important; max-width: 100% !important; margin: 0 !important;
  }
  .bulletin::before { display: none; }
  .bulletin-table { border: 1px solid #000; border-radius: 0; }
  .bulletin-table thead th { background: #f0f0f0 !important; color: #000; border-bottom: 1px solid #000; }
  .bulletin-table tbody td { border-bottom: 1px solid #ccc; }
  .bulletin-table tfoot td { background: #f0f0f0 !important; color: #000 !important; border-top: 2px solid #000; border-radius: 0 !important; }
  .moyenne-box { background: #f0f0f0 !important; color: #000 !important; border: 1px solid #000; }
  .moyenne-box .summary-label, .moyenne-box .summary-value { color: #000 !important; }
  .bulletin-student-info, .bulletin-summary-box { background: #fff !important; border: 1px solid #000; border-radius: 0; }
  .bulletin-summary { grid-template-columns: 1fr 1fr 2fr; gap: 1rem; }
  .badge { border: 1px solid #000; color: #000; background: transparent !important; }
  .bulletin-trimestre { border: 1px solid #000; color: #000; background: transparent !important; }
  
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  @page { size: A4; margin: 1.5cm; }
}

/* --- Input date styling --- */
input[type="date"] {
  width: 100%; padding: .75rem 1rem; border: 2px solid var(--border);
  border-radius: var(--radius); font-size: 1rem; font-family: inherit;
  color: var(--text); background: var(--bg); outline: none; transition: var(--transition);
}
input[type="date"]:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(198,113,57,.15); }

/* =============================================================================
   LOGIN PAGE — M8 : la même lumière que l'application
   ============================================================================= */
/* ⚠ LE LOGIN ÉTAIT UN AUTRE PRODUIT : dégradé brun sombre, halos cyan, titre
   Poppins. C'est le premier écran que voit le personnel ; une page de connexion
   qui n'a pas la couleur de l'application fait douter de l'adresse. Elle passe
   donc aux jetons de la maquette — crème, carte blanche, terre cuite. */
.login-body {
  margin: 0; min-height: 100vh; overflow-x: hidden;
  background: var(--o-bg);
  position: relative;
}

.login-bg { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.login-blob {
  position: absolute; border-radius: 50%; filter: blur(90px);
  opacity: .55; animation: float 18s ease-in-out infinite;
}
.login-blob-1 { width: 500px; height: 500px; background: var(--o-a-200); top: -120px; left: -80px; }
.login-blob-2 { width: 420px; height: 420px; background: var(--o-g-200); bottom: -100px; right: -60px; animation-delay: -6s; }
.login-blob-3 { width: 300px; height: 300px; background: var(--o-n-200); top: 40%; left: 50%; animation-delay: -12s; }

@keyframes float {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33%      { transform: translate(40px, -30px) scale(1.08); }
  66%      { transform: translate(-30px, 40px) scale(.95); }
}

.login-page {
  position: relative; z-index: 1;
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 2rem 1rem;
}

.login-container { width: 100%; max-width: 440px; animation: slideUpFade .6s cubic-bezier(.16,1,.3,1); }

.login-brand { text-align: center; margin-bottom: 1.75rem; color: var(--text); }
.login-brand-logo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 72px; height: 72px; margin-bottom: .9rem; border-radius: 18px;
  background: var(--o-accent);
  border: none;
  color: #fff;
  box-shadow: var(--shadow-md);
  backdrop-filter: none;
}
.login-brand h1 {
  font-family: var(--font-heading); font-size: 1.9rem; font-weight: 600;
  letter-spacing: -.01em; margin-bottom: .2rem; color: var(--text);
}
.login-brand p { color: var(--text-light); font-size: .95rem; }

.login-card {
  background: var(--bg-card); border-radius: var(--radius-lg);
  padding: 2.25rem 2rem;
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--o-n-300);
}
.login-card-header { margin-bottom: 1.6rem; text-align: center; }
.login-card-header h2 {
  font-family: var(--font-heading); font-size: 1.4rem;
  color: var(--text); margin-bottom: .2rem;
}
.login-card-header p { color: var(--text-light); font-size: .9rem; }

.form-group-icon .input-wrapper { position: relative; }
.form-group-icon .input-icon {
  position: absolute; left: 1rem; top: 50%; transform: translateY(-50%);
  color: var(--text-muted); pointer-events: none;
}
.form-group-icon input { padding-left: 2.75rem; }
.form-group-icon input:focus ~ .input-icon,
.form-group-icon .input-wrapper:focus-within .input-icon { color: var(--primary); }

.toggle-mdp {
  position: absolute; right: .75rem; top: 50%; transform: translateY(-50%);
  background: transparent; border: none; cursor: pointer;
  color: var(--text-muted); padding: .4rem; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  transition: var(--transition);
}
.toggle-mdp:hover { color: var(--primary); background: rgba(198,113,57,.08); }
.toggle-mdp.shown { color: var(--primary); }

.btn-login {
  width: 100%; padding: .9rem 1.5rem; font-size: 1rem; font-weight: 600;
  margin-top: .5rem;
}
.btn-login.loading { opacity: .8; cursor: wait; }
.btn-login svg { transition: var(--transition); }
.btn-login:hover svg { transform: translateX(3px); }

.login-secure-badge {
  margin-top: 1.5rem; padding-top: 1.25rem;
  border-top: 1px dashed var(--border);
  display: flex; align-items: center; justify-content: center; gap: .4rem;
  font-size: .75rem; color: var(--text-muted); font-weight: 500;
}
.login-secure-badge svg { color: var(--success); }

.login-footer {
  text-align: center; margin-top: 1.5rem;
  /* M8 : le pied de page était blanc sur le dégradé sombre ; sur le crème il
     devenait invisible. Le texte secondaire de la maquette. */
  font-size: .8rem; color: var(--o-n-700);
}

.alert { display: flex; align-items: flex-start; gap: .5rem; }

@keyframes slideUpFade {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 480px) {
  .login-card { padding: 1.75rem 1.25rem; }
  .login-brand h1 { font-size: 1.8rem; }
  .login-brand-logo { width: 64px; height: 64px; }
}
.bulletin-v2-school .annee { font-size: .75rem; color: #9CA3AF; margin-top: .2rem; }
.bulletin-v2-field .lbl {
  color: #6B7280; font-weight: 600; font-size: .75rem;
  text-transform: uppercase; letter-spacing: .5px;
  min-width: 90px;
}
.bulletin-v2-field .val { color: #111827; font-weight: 600; }
.bulletin-v2-table .moy-cell { font-weight: 800; font-size: 1rem; }
.bulletin-v2-table .moy-low  { color: #DC2626; }
.bulletin-v2-table .moy-ok   { color: #059669; }
.bulletin-v2-stat-value.text-error { color: #DC2626; }
.bulletin-v2-stat-value.text-success { color: #059669; }
.bulletin-v2-stat.primary {
  background: linear-gradient(135deg, #b2622d, #474238);
  border: none; color: #fff;
}
.bulletin-v2-stat.primary .bulletin-v2-stat-label { color: rgba(255,255,255,.7); }
.bulletin-v2-stat.primary .bulletin-v2-stat-value { color: #fff !important; }
.bulletin-v2-stat.appreciation {
  background: #FFFBEB; border-color: #FDE68A;
  text-align: left; padding: 1rem 1.25rem;
}
.bulletin-v2-stat.appreciation .bulletin-v2-stat-value {
  font-size: 1rem; line-height: 1.4; color: #92400E; font-weight: 700;
}
.bulletin-v2-sig .lbl {
  font-size: .75rem; color: #6B7280;
  text-transform: uppercase; letter-spacing: 1px;
  font-weight: 700; margin-bottom: 3rem;
}
.bulletin-v2-sig .line {
  height: 1px; background: #9CA3AF; width: 70%; margin: 0 auto;
}

@media print {
  .no-print, .sidebar, .sidebar-toggle, .page-header { display: none !important; }
  body { background: #fff !important; }
  .main-content { margin-left: 0 !important; padding: 0 !important; }
  .page-content { padding: 0 !important; }
  .bulletin-v2 {
    box-shadow: none !important; border: 1px solid #000 !important;
    border-radius: 0 !important; max-width: 100% !important;
  }
  .bulletin-v2-content { padding: 1.5rem !important; }
  .bulletin-v2-watermark { opacity: .03 !important; }
  .bulletin-v2-table { border: 1px solid #000; }
  .bulletin-v2-table tbody tr:nth-child(even) { background: #f7f7f7 !important; }
  .bulletin-v2-stat.primary { background: #474238 !important; }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  @page { size: A4; margin: 1.2cm; }
}

@media (max-width: 768px) {
  .bulletin-v2-content { padding: 1.5rem; }
  .bulletin-v2-head { grid-template-columns: 1fr; text-align: center; }
  .bulletin-v2-title { text-align: center; }
  .bulletin-v2-student { grid-template-columns: 1fr; }
  .bulletin-v2-summary { grid-template-columns: 1fr; }
  .bulletin-v2-foot { grid-template-columns: 1fr; gap: 2rem; }
}

/* =============================================================================
   FIELD ERROR MESSAGES — Inline validation
   ============================================================================= */
.field-error {
  display: block;
  font-size: .78rem;
  color: var(--error);
  margin-top: .3rem;
  min-height: 1rem;
  font-weight: 500;
  transition: all .2s ease;
}
.field-error:empty { min-height: 0; }

.form-group input.input-error,
.form-group select.input-error {
  border-color: var(--error) !important;
  box-shadow: 0 0 0 3px rgba(239,68,68,.12) !important;
}

/* Relevé Print */
@media print {
  .no-print, .sidebar, .sidebar-toggle, .page-header { display: none !important; }
  body { background: #fff !important; }
  .main-content { margin-left: 0 !important; padding: 0 !important; }
  .page-content { padding: 0 !important; }
  .releve-container {
    border: 1px solid #000 !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 1.5cm !important;
  }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  @page { size: A4; margin: 0.5cm; }
}

/* Responsive Relevé */
@media (max-width: 768px) {
  .releve-container { padding: 1rem; }
  .releve-header { grid-template-columns: 1fr; text-align: center; }
  .releve-header-right { text-align: center; direction: rtl; }
  .releve-info-section { grid-template-columns: 1fr; }
  .releve-stamp-section { grid-template-columns: 1fr; }
  .releve-signatures-bottom { grid-template-columns: 1fr; gap: 2rem; }
}

/* ── Print ── */
@media print {
  .no-print, .sidebar, .sidebar-toggle, .page-header, .alert { display: none !important; }
  body { background: #fff !important; }
  .main-content { margin-left: 0 !important; padding: 0 !important; }
  .page-content { padding: 0 !important; }
  .bulletin-off {
    border: 1px solid #000 !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 1cm 1.2cm !important;
    font-size: .75rem !important;
  }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  @page { size: A4 portrait; margin: .5cm; }
}

/* ============================================================================
   HUBS (Finance / Scolarité) — chargement AJAX, design soigné
   ============================================================================ */
.hub-shell { display: flex; flex-direction: column; gap: 1.25rem; }

.hub-nav {
  display: flex; flex-wrap: wrap; gap: .5rem;
  background: var(--surface, #fff);
  padding: .5rem; border-radius: 16px;
  box-shadow: 0 1px 3px rgba(16,24,40,.06), 0 1px 2px rgba(16,24,40,.04);
  border: 1px solid var(--border, #e8eaf0);
}
.hub-tab {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .6rem 1rem; border: none; cursor: pointer;
  background: transparent; color: var(--text-light, #667085);
  font-family: inherit; font-size: .9rem; font-weight: 600;
  border-radius: 11px; transition: background .18s ease, color .18s ease, transform .12s ease;
  white-space: nowrap;
}
.hub-tab:hover { background: rgba(198,113,57,.08); color: var(--primary, #c67139); }
.hub-tab:active { transform: translateY(1px); }
.hub-tab.is-active {
  background: linear-gradient(135deg, #c67139, #7a8a5e);
  color: #fff; box-shadow: 0 4px 12px rgba(198,113,57,.35);
}
.hub-tab-ico { font-size: 1.05rem; line-height: 1; }

.hub-panel { position: relative; min-height: 200px; animation: hubFade .35s ease; }
.hub-panel.is-loading { opacity: .65; }
@keyframes hubFade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.embed-fragment { animation: hubFade .3s ease; }

/* Skeleton loader */
.hub-skeleton { padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
.sk-bar {
  height: 18px; border-radius: 8px;
  background: linear-gradient(90deg, #eef0f5 25%, #f6f7fb 37%, #eef0f5 63%);
  background-size: 400% 100%; animation: skShimmer 1.3s ease infinite;
}
.sk-w70 { width: 70%; } .sk-w40 { width: 40%; }
@keyframes skShimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* Mobile: nav scrolls horizontally, labels stay readable */
@media (max-width: 640px) {
  .hub-nav { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .hub-tab { flex: 0 0 auto; padding: .55rem .8rem; font-size: .82rem; }
}

/* ============================================================================
   MODALES — centrées, fluides, jamais de "drift"
   ============================================================================ */
.modal-overlay,
#modal_paiement, #modal_pay, #modal_cspay {
  position: fixed; inset: 0;
  background: rgba(17,24,39,.55); backdrop-filter: blur(2px);
  z-index: 1000; display: none;
  align-items: center; justify-content: center; padding: 1rem;
  animation: ovFade .2s ease;
}
@keyframes ovFade { from { opacity: 0; } to { opacity: 1; } }
.modal-overlay.is-open, .modal-overlay.active,
#modal_paiement[style*="flex"], #modal_pay[style*="flex"], #modal_cspay[style*="flex"] {
  display: flex !important;
}
.modal-overlay > .form-card,
#modal_paiement > .form-card, #modal_pay > .form-card, #modal_cspay > .form-card {
  max-height: 88vh; overflow-y: auto;
  animation: modalPop .25s cubic-bezier(.2,.9,.3,1.2);
  box-shadow: 0 24px 60px rgba(16,24,40,.28);
}
@keyframes modalPop { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }

/* ============================================================================
   PAYMENT WIDGET — lignes nettes et agréables
   ============================================================================ */
.mp-widget { background: rgba(198,113,57,.04); border: 1px solid rgba(198,113,57,.12);
  border-radius: 12px; padding: .85rem; }
.mp-ligne { background: #fff; border: 1px solid var(--border,#e8eaf0); border-radius: 10px;
  padding: .4rem .5rem; transition: box-shadow .15s ease; }
.mp-ligne:focus-within { box-shadow: 0 0 0 3px rgba(198,113,57,.15); }
.mp-ligne select, .mp-ligne input { border: 1px solid var(--border,#e8eaf0); border-radius: 8px; padding: .45rem .5rem; }
.mp-total { color: var(--text,#1d2939); }

/* ============================================================================
   POLISH GÉNÉRAL — cartes, tableaux, boutons plus doux
   ============================================================================ */
.form-card { border-radius: 16px; transition: box-shadow .2s ease; }
.data-table, .table-container table, .overflow-x table { border-collapse: separate; border-spacing: 0; }
.table-container { border-radius: 16px; overflow-x: auto; overflow-y: visible; }
.data-table thead th, .table-container thead th {
  position: sticky; top: 0; background: var(--o-n-100); z-index: 1;
  font-size: .78rem; letter-spacing: .02em; text-transform: uppercase; color: var(--o-n-700);
}
.data-table tbody tr, .table-container tbody tr { transition: background .12s ease; }
.data-table tbody tr:hover, .table-container tbody tr:hover { background: rgba(198,113,57,.04); }
.btn { transition: transform .12s ease, box-shadow .18s ease, background .18s ease, filter .15s ease; }
.btn:hover { filter: brightness(1.03); }
.btn:active { transform: translateY(1px); }
.btn-primary { box-shadow: 0 2px 8px rgba(198,113,57,.25); }

/* Badges arrondis cohérents */
.badge { border-radius: 999px; padding: .2rem .6rem; font-size: .72rem; font-weight: 700; }

/* Inputs : focus ring homogène */
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primary,#c67139);
  box-shadow: 0 0 0 3px rgba(198,113,57,.15);
}

/* Responsivité : grilles à 2 colonnes -> 1 colonne sur petit écran */
@media (max-width: 760px) {
  .form-card [style*="grid-template-columns:1fr 1fr"],
  .form-card [style*="grid-template-columns: 1fr 1fr"] { grid-template-columns: 1fr !important; }
  [style*="grid-template-columns:1fr 1fr"] { grid-template-columns: 1fr !important; }
}

/* ============================================================================
   HUBS V2 — onglets raffinés, fragments pleine largeur, focus visibles
   ============================================================================ */
/* ⚠ Retiré (M8) : `:root { --danger: #EF4444; }` écrasait, pour toute la
   feuille, le rouge du jeton sémantique (#c0392b) — y compris sur les écrans
   de dette et d'impayés, où ce rouge porte un sens. Le rouge de ce bloc reste
   sur son usage local (`.btn-danger`, plus bas). */

.hub-nav {
  /* ⚠ PLUS COLLANT (M8). Deux barres collent déjà — l'en-tête de la coquille
     (56 px) et l'en-tête de page — et une troisième range de navigation
     collante ne laisserait plus de quoi lire un tableau sur un écran de
     768 px de haut. La rangée défile avec la page. */
  position: static; top: auto; z-index: auto;
  gap: .35rem; padding: .45rem;
  backdrop-filter: none;
  background: var(--bg-card);
}
.hub-tab {
  position: relative;
  padding: .65rem 1.05rem;
  border-radius: var(--radius);
  letter-spacing: .01em;
}
.hub-tab .hub-tab-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 9px;
  background: var(--o-a-100);
  transition: background .18s ease, transform .18s ease;
}
.hub-tab:hover .hub-tab-ico { transform: translateY(-1px) scale(1.06); }
.hub-tab.is-active .hub-tab-ico { background: var(--o-a-200); }
.hub-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--o-a-300);
}
/* M8 : l'onglet courant se lit en terre cuite pâle, comme l'entrée du menu —
   plus de dégradé terre/olive, qui donnait un brun sale au repos. */
.hub-tab.is-active {
  background: var(--o-a-100);
  color: var(--o-a-700);
  box-shadow: inset 0 0 0 1px var(--o-a-300);
}

/* Les fragments embarqués profitent de toute la largeur du panneau */
.embed-fragment .form-card { max-width: none; }
.embed-fragment .btn-primary { width: auto; }
.embed-fragment > .alert:first-child { margin-bottom: 1rem; }

/* Boutons : anneau de focus homogène partout */
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--o-a-300);
}
.btn-danger:focus-visible { box-shadow: 0 0 0 3px rgba(192,57,43,.35); }
/* M8 : plus de dégradés — un aplat, et le rouge reste un contour pour les
   actions destructrices (une page d'impayés pleine de boutons rouges pleins
   crie plus fort que ce qu'elle dit). */
.btn-success { background: var(--success); border-color: var(--success); box-shadow: none; }
.btn-danger  { background: transparent; color: var(--error); border-color: rgba(192,57,43,.42); box-shadow: none; }
.btn[disabled] { opacity: .55; cursor: not-allowed; transform: none !important; }

/* ============================================================================
   GESTION DE CAISSE — gestionnaire de moyens de paiement
   ============================================================================ */
.mp-manager { margin-bottom: 1.5rem; }
.mp-manager-head {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: .5rem;
}
.mp-manager-body { margin-top: 1.1rem; animation: hubFade .25s ease; }
.mp-add-form {
  display: flex; gap: .6rem; align-items: flex-end; flex-wrap: wrap;
  margin-bottom: 1rem; padding: .9rem;
  background: rgba(198,113,57,.05);
  border: 1px dashed rgba(198,113,57,.3); border-radius: 12px;
}
.mp-add-form label { font-size: .82rem; font-weight: 600; display: block; margin-bottom: .35rem; }

.mp-chips { display: flex; gap: .6rem; flex-wrap: wrap; }
.mp-chip {
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .45rem .65rem .45rem .85rem;
  border-radius: 999px; border: 1.5px solid var(--border);
  background: #fff; transition: border-color .18s ease, background .18s ease, box-shadow .18s ease;
}
.mp-chip.is-on { border-color: rgba(16,185,129,.45); background: #F0FDF7; box-shadow: 0 1px 4px rgba(16,185,129,.12); }
.mp-chip.is-off { background: #F9FAFB; }
.mp-chip-dot { width: 8px; height: 8px; border-radius: 50%; background: #D1D5DB; flex-shrink: 0; }
.mp-chip.is-on .mp-chip-dot { background: #10B981; box-shadow: 0 0 0 3px rgba(16,185,129,.18); }
.mp-chip-name { font-weight: 700; font-size: .87rem; color: var(--text); }
.mp-chip.is-off .mp-chip-name { color: #9CA3AF; }

/* Interrupteur (switch) Activer / Désactiver */
.mp-switch {
  position: relative; width: 42px; height: 24px;
  border: none; border-radius: 999px; cursor: pointer; padding: 0;
  background: #D1D5DB; transition: background .2s ease, box-shadow .2s ease;
  flex-shrink: 0;
}
.mp-switch:hover { box-shadow: 0 0 0 4px rgba(198,113,57,.12); }
.mp-switch:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(198,113,57,.35); }
/* Desactive le temps de l'envoi (ajout du 11/10/2026, absent de la feuille
   d'origine : son ecran rechargeait la page, le notre attend la reponse et
   bloque le clic pendant ce temps). Le meme gris que son .btn[disabled]
   ci-dessus, pour que l'etat se voie et ne se devine pas. */
.mp-switch:disabled { opacity: .55; cursor: not-allowed; box-shadow: none; }
.mp-chip.is-on .mp-switch { background: var(--success); }
.mp-switch-knob {
  position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25);
  transition: transform .2s cubic-bezier(.2,.9,.3,1.2);
}
.mp-chip.is-on .mp-switch-knob { transform: translateX(18px); }

/* ============================================================================
   GESTION DE CAISSE — grille des 12 mois
   ============================================================================ */
.mois-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: .65rem; margin-top: 1rem;
}
.mois-card {
  border-radius: var(--radius); padding: .7rem .75rem;
  border: 1px solid var(--border); background: var(--bg-card);
  display: flex; flex-direction: column; gap: .35rem;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.mois-card:hover { box-shadow: var(--shadow-md); }
/* M8 : les états d'un mois se lisent dans les couleurs sémantiques de la
   maquette — vert payé, ambre exempté, terre partiel — et non dans les verts
   et oranges de la feuille d'origine, qui juraient sur le crème. */
.mois-card.is-paye   { border-color: rgba(47,125,79,.45);  background: #e7f3ec; }
.mois-card.is-exempt { border-color: rgba(138,83,0,.4);    background: #fdf3e3; }
.mois-card.is-due:hover { border-color: rgba(180,85,45,.45); }
.mois-nom { font-weight: 700; font-size: .85rem; color: var(--text); }
.mois-etat { font-size: .76rem; font-weight: 600; color: var(--text-muted); }
.mois-card.is-paye .mois-etat   { color: var(--success); }
.mois-card.is-exempt .mois-etat { color: var(--warning); }
.mois-actions { display: flex; gap: .3rem; flex-wrap: wrap; }
.mois-btn { font-size: .72rem !important; padding: .28rem .55rem !important; border-radius: 8px !important; }
.mois-btn-pay {
  width: 100%; font-size: .78rem !important; padding: .42rem .5rem !important;
  border-radius: 9px !important; margin-top: auto;
}

/* ============================================================================
   IMPRESSION — ne jamais imprimer la navigation des hubs
   ============================================================================ */
@media print {
  .hub-nav { display: none !important; }
  .hub-panel { animation: none !important; }
}

/* Petits écrans : la barre d'onglets reste sous le header sticky */
@media (max-width: 768px) {
  .hub-nav { top: 64px; }
}

/* Radios & checkboxes : plus grands, couleur de la marque (appel d'absence…) */
input[type="radio"], input[type="checkbox"] {
  accent-color: var(--primary);
  width: 17px; height: 17px; cursor: pointer;
}

/* Partial payments style */
.mois-card.is-partial { border-color: rgba(180,85,45,.45); background: #fbf0e8; }
.mois-card.is-partial .mois-etat { color: var(--o-a-700); font-weight: 600; }

/* ═══ Impression propre — GLOBAL (v9.8) ═══ */
@media print {
    .sidebar, .app-sidebar, .topbar, .app-topbar, .no-print, nav, .btn, button,
    .sidebar-toggle, .lang-switch, form select, .alert { display: none !important; }
    body, .main-content, .page-content, .content { background: #fff !important; color: #000 !important;
        margin: 0 !important; padding: 0 !important; width: 100% !important; }
    .table-container, .form-card { box-shadow: none !important; border: 1px solid #000 !important; }
    table { border-collapse: collapse !important; width: 100% !important; }
    th, td { border: 1px solid #333 !important; color: #000 !important; padding: 4px 6px !important; }
    th { background: #eee !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    a { color: #000 !important; text-decoration: none !important; }
    * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
.skip-link:focus { top: .6rem; color: #fffaf1; }

/* ── Le sol ──────────────────────────────────────────────────────────────── */
/* Un fond plat, crème. La maquette M8 approuvée n'a ni halo ni dégradé : une
   surface calme laisse les chiffres et les états se lire, et elle ne coûte
   rien à peindre au défilement. */
body {
  background-color: var(--o-bg);
  background-image: none;
}

/* ── Barre latérale ──────────────────────────────────────────────────────── */
/* M8 : claire, sur carte, 264 px. Elle n'est plus un bandeau sombre — la
   navigation et le contenu partagent la même lumière, et l'élément courant se
   lit en terre cuite pâle plutôt qu'en surbrillance. */
.sidebar {
  width: var(--sidebar-width);
  inset-inline-start: 0;
  background: var(--bg-card);
  color: var(--text);
  border-inline-end: 1px solid var(--o-n-300);
  padding-bottom: .5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--o-n-300) transparent;
}
.sidebar::-webkit-scrollbar { width: 8px; }
.sidebar::-webkit-scrollbar-thumb { background: var(--o-n-300); border-radius: 99px; }

.sidebar-header {
  padding: 1.1rem 1.05rem .9rem;
  border-bottom: 1px solid var(--o-n-200);
}
.sidebar-logo {
  font-family: var(--font-heading); font-weight: 600;
  font-size: 1.12rem; letter-spacing: -.01em; color: var(--text); gap: .6rem;
  min-width: 0;
}
/* Le logotype de l'école (O9) quand la plateforme en sert un, la marque sinon. */
.sidebar-logo .logo-ecole {
  width: 38px; height: 38px; border-radius: 11px; object-fit: cover; flex-shrink: 0;
  border: 1px solid var(--o-n-200); background: var(--o-bg);
}
.sidebar-logo .logo-marque {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--o-accent); color: #fff;
}
.sidebar-logo .logo-marque svg { width: 21px; height: 21px; color: #fff; }
.sidebar-logo > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.sidebar-nav { padding: .55rem .55rem .9rem; gap: 2px; }
/* Les sections nommées de la maquette : un repère de lecture, pas une frontière.
   `<details>` les rend repliables sans script (sidebar-liens.tsx). */
.sidebar-section { display: flex; flex-direction: column; gap: 1px; }
.sidebar-section + .sidebar-section { margin-top: .3rem; }
.sidebar-section > summary,
.sidebar-section > h4 {
  font-family: var(--font-body); font-size: .625rem; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase;
  /* n-700, pas n-600 : à 10 px en capitales, le gris n-600 ne donne que
     4,3:1 sur blanc — sous le seuil AA, et axe le signale (M8). */
  color: var(--o-n-700);
  padding: .75rem .7rem .28rem; margin: 0;
  cursor: pointer; list-style: none; user-select: none;
  /* `block` retire le marqueur natif de `<summary>` dans Chromium, où
     `list-style: none` seul ne suffit pas. */
  display: block;
}
.sidebar-section > summary::-webkit-details-marker { display: none; }
.sidebar-section > summary::marker { content: ''; }
.sidebar-section > summary:hover { color: var(--o-n-800); }
.sidebar-section > summary:focus-visible { outline: 2px solid var(--o-accent); outline-offset: -2px; border-radius: 6px; }
/* Le chevron : fermé, il pointe vers la droite ; ouvert, vers le bas. */
.sidebar-section > summary::after {
  content: '›'; float: inline-end; font-size: .9rem; line-height: 1;
  transform: rotate(90deg); transition: transform .15s ease; opacity: .7;
}
.sidebar-section:not([open]) > summary::after { transform: rotate(0deg); }
.sidebar-link {
  padding: .55rem .7rem; border-radius: var(--radius);
  color: var(--o-n-700);
  font-size: .855rem; font-weight: 500; letter-spacing: .002em;
  position: relative;
}
.sidebar-link:hover { background: var(--o-n-200); color: var(--text); }
/* L'élément courant : fond terre cuite pâle et encre terre. La couleur seule ne
   suffit pas à situer la page dans 26 entrées — le gras la double. */
.sidebar-link.active {
  background: var(--o-a-100); color: var(--o-a-700); font-weight: 600; box-shadow: none;
}
.sidebar-link.active::before { content: none; }
.sidebar-icon { width: 19px; height: 19px; opacity: 1; }

.sidebar-footer { padding: .7rem .55rem .2rem; border-top: 1px solid var(--o-n-200); }
.sidebar-user { padding: .35rem .4rem .55rem; gap: .6rem; }
.sidebar-avatar {
  width: 33px; height: 33px; border-radius: 50%;
  background: var(--o-a-100); color: var(--o-a-700);
  font-family: var(--font-body); font-weight: 700; font-size: .88rem;
}
.sidebar-user-name { font-size: .84rem; font-weight: 600; color: var(--text); }
.sidebar-user-role {
  font-size: .68rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--o-n-700);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 11.5rem;
}
.sidebar-logout { color: var(--o-n-700); font-size: .84rem; }
.sidebar-logout:hover { color: var(--error); background: var(--o-a-100); }

/* ── L'en-tête de la coquille (M8) ───────────────────────────────────────── */
/* Fil d'Ariane, recherche, identité. Il colle en haut ; l'en-tête de page se
   colle JUSTE SOUS lui (`top: 56px`), et c'est ce couple que mesure
   e2e/en-tete-collant.spec.ts. */
.entete-app {
  position: sticky; top: 0; z-index: 40;
  min-height: 56px; display: flex; align-items: center; gap: .7rem;
  padding: .4rem 1.25rem;
  background: var(--bg-card);
  border-bottom: 1px solid var(--o-n-300);
}
.entete-app .fil-ariane {
  display: flex; align-items: center; gap: .40rem;
  font-size: .82rem; color: var(--o-n-700); min-width: 0;
}
.entete-app .fil-ariane a { color: var(--o-n-700); }
.entete-app .fil-ariane a:hover { color: var(--o-accent); text-decoration: underline; }
.entete-app .fil-ariane b { color: var(--text); font-weight: 600; }
.entete-app .fil-ariane .sep { opacity: .55; }
.entete-app .identite-ecole {
  display: none; align-items: center; gap: .5rem; min-width: 0;
  font-family: var(--font-heading); font-size: .95rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.entete-app .identite-ecole img { width: 28px; height: 28px; border-radius: 8px; object-fit: cover; }
.entete-app .outils { margin-inline-start: auto; display: flex; align-items: center; gap: .35rem; }
.entete-app .outil {
  width: 36px; height: 36px; border-radius: var(--radius-pill);
  display: grid; place-items: center; color: var(--o-n-700);
  border: 1px solid var(--o-n-300); background: var(--bg-card);
}
.entete-app .outil:hover { background: var(--o-n-200); color: var(--text); }
.entete-app .outil svg { width: 18px; height: 18px; }
.entete-app .avatar-lien {
  display: flex; align-items: center; gap: .5rem; padding: .2rem .5rem .2rem .2rem;
  border-radius: var(--radius-pill); border: 1px solid var(--o-n-300);
  color: var(--text); min-height: 36px;
}
.entete-app .avatar-lien:hover { background: var(--o-n-200); }
.entete-app .avatar-rond {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  background: var(--o-accent); color: #fff;
  display: grid; place-items: center; font-weight: 700; font-size: .78rem;
}
.entete-app .avatar-nom { font-size: .8rem; font-weight: 600; max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── En-tête de page ─────────────────────────────────────────────────────── */
.page-header {
  top: 56px;
  padding: 1.05rem 1.6rem;
  background: var(--bg-card);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom: 1px solid var(--o-n-300);
  gap: .9rem 1.25rem;
}
.page-title { font-size: 1.62rem; color: var(--text); margin: 0; }
.page-subtitle { font-size: .845rem; color: var(--text-light); margin-top: .18rem; max-width: 62ch; }
.page-header-left { min-width: 0; flex: 1 1 18rem; }
.page-header-right { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; flex: 0 0 auto; margin-inline-start: auto; }
.header-date {
  font-size: .78rem; color: var(--text-muted);
  padding: .28rem .6rem; border: 1px solid var(--o-n-300);
  border-radius: var(--radius-pill); background: rgba(255,255,255,.5);
  white-space: nowrap;
}
.header-date svg { width: 15px; height: 15px; opacity: .7; }
.page-content { padding: 1.6rem; max-width: 1560px; }

/* Sélecteur d'année de l'en-tête : c'est un contrôle de contexte, il doit se
   lire comme tel et non comme un champ de formulaire perdu. */
.header-annee select, #hdr-annee {
  font-family: var(--font-body); font-size: .8rem; font-weight: 600;
  padding: .32rem 1.9rem .32rem .7rem;
  border: 1px solid var(--o-a-300); border-radius: var(--radius-pill);
  background-color: var(--o-a-100); color: var(--o-a-800);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238c491a' stroke-width='1.8'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .55rem center; background-size: 13px;
  -webkit-appearance: none; appearance: none; cursor: pointer; max-width: 14rem;
}
.header-annee select:hover, #hdr-annee:hover { background-color: var(--o-a-200); }
.header-annee { display: flex; gap: .4rem; align-items: center; }

/* Sélecteur d'année posé en tête de page (et non dans l'en-tête global). */
.selecteur-annee { display: flex; gap: .55rem; align-items: center; margin-bottom: 1rem; flex-wrap: wrap; }
.selecteur-annee > label { margin: 0; }
.selecteur-annee select { max-width: 15rem; }

/* ── Titres de section ──────────────────────────────────────────────────── */
/* Un court trait terre cuite : sépare les blocs sans ajouter ni encadré ni
   ombre, et donne son rythme à la page. */
.section-title-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .75rem 1rem; flex-wrap: wrap; margin: 1.9rem 0 .85rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--o-n-300);
}
.section-title-row:first-child { margin-top: 0; }
.section-title-row > h2, .section-title-row > h3 { margin: 0; font-size: 1.24rem; position: relative; }
.section-title-row > h2::after, .section-title-row > h3::after {
  content: ''; display: block; width: 2.1rem; height: 2px; margin-top: .42rem;
  background: var(--o-accent); border-radius: 2px;
}

/* ── Cartes, tableaux ───────────────────────────────────────────────────── */
.table-container, .form-card, .chart-card, .profile-card, .profile-header-card,
.kpi-card, .empty-state, .mp-widget, .syn-tile, .st-card {
  background: var(--bg-card);
  border: 1px solid var(--o-n-300);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.form-card, .chart-card { overflow: hidden; }
.table-container { overflow-x: auto; overflow-y: visible; }
.form-card { padding: 1.3rem 1.4rem; }
.form-card > h3, .form-card > h4 { margin: 0 0 1rem; font-size: 1.16rem; }

.table-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: .7rem 1rem; flex-wrap: wrap;
  padding: .9rem 1.15rem;
  background: linear-gradient(180deg, var(--o-n-100), var(--bg-card));
  border-bottom: 1px solid var(--o-n-300);
}
.table-header h3, .table-header h4 { margin: 0; font-size: 1.1rem; }

table { width: 100%; border-collapse: collapse; font-size: .875rem; }
thead th {
  text-align: left; font-family: var(--font-body);
  font-size: .688rem; font-weight: 700; letter-spacing: .075em; text-transform: uppercase;
  color: var(--o-n-700); white-space: nowrap;
  padding: .62rem .85rem;
  background: var(--o-n-100);
  border-bottom: 1px solid var(--o-n-300);
  position: sticky; top: 0; z-index: 2;
}
tbody td { padding: .62rem .85rem; border-bottom: 1px solid rgba(32,30,29,.075); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: rgba(198,113,57,.055); }
/* Les montants : chasse tabulaire pour que les colonnes s'alignent. */
td:has(> strong), .amount, .mp-total, .kpi-value, .syn-tile b, .st-stat b {
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1;
}
.overflow-x, .table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Boutons ────────────────────────────────────────────────────────────── */
/* M8 : rayon de 9 px (la maquette), plus de pilule — une pilule se lit comme
   une étiquette, pas comme une action. Terre cuite pleine pour l'action
   principale, contour pour le reste. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  font-family: var(--font-body); font-weight: 600; font-size: .875rem; line-height: 1.25;
  padding: .55rem 1rem; border-radius: var(--radius);
  border: 1px solid transparent; cursor: pointer; min-height: 40px;
  transition: var(--transition); text-decoration: none; white-space: nowrap;
}
.btn:disabled, .btn[disabled] { opacity: .45; cursor: not-allowed; }
.btn-primary   { background: var(--o-accent); color: #fff; border-color: var(--o-accent); width: auto; }
/* ⚠ Pleine largeur SEULEMENT là où c'est un envoi de formulaire. La règle
   héritée `width: 100%` s'appliquait à TOUT bouton primaire : sur « Impayés »,
   « Imprimer » et « Enregistrer en PDF » prenaient chacun 1 000 px de large et
   empilaient trois pavés orange. Un envoi de formulaire reste pleine largeur ;
   une action isolée reprend sa taille. */
form .btn-primary, .form-card .btn-primary { width: 100%; }
.btn-primary:hover   { background: var(--o-a-700); border-color: var(--o-a-700); color: #fff; }
.btn-primary:active  { background: var(--o-a-800); }
.btn-secondary { background: var(--bg-card); color: var(--text); border-color: var(--o-n-300); }
.btn-secondary:hover { background: var(--o-n-200); border-color: var(--o-n-400); color: var(--text); }
.btn-success   { background: var(--success); color: #fff; border-color: var(--success); }
.btn-success:hover   { background: #276a43; color: #fff; }
.btn-danger    { background: transparent; color: var(--error); border-color: rgba(192,57,43,.42); }
.btn-danger:hover    { background: rgba(192,57,43,.08); color: #96271c; border-color: rgba(192,57,43,.6); }
.btn-sm { padding: .3rem .7rem; font-size: .78rem; min-height: 32px; }
.btn-export-group { display: inline-flex; flex-wrap: wrap; gap: .4rem; }

/* ── Formulaires ────────────────────────────────────────────────────────── */
.form-group { margin-bottom: 1.05rem; }
.form-group label, .field > label, label {
  font-family: var(--font-body); font-size: .74rem; font-weight: 700;
  letter-spacing: .045em; text-transform: uppercase; color: var(--o-n-700);
  margin-bottom: .3rem; display: block;
}
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .9rem; }

input[type=text], input[type=number], input[type=date], input[type=time],
input[type=password], input[type=email], input[type=tel], input[type=search],
select, textarea, .input {
  width: 100%; font-family: var(--font-body); font-size: .875rem; color: var(--text);
  background: #fff;
  border: 1px solid var(--o-n-400); border-radius: var(--radius-pill);
  padding: .5rem .85rem; min-height: 38px;
  transition: border-color .15s, box-shadow .15s, background-color .15s;
  caret-color: var(--o-accent);
}
textarea, textarea.input { border-radius: var(--radius); min-height: 5.5rem; resize: vertical; padding: .6rem .85rem; }
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) { border-color: var(--o-n-500); }
input:focus, select:focus, textarea:focus, .input:focus {
  outline: none; border-color: var(--o-accent);
  box-shadow: 0 0 0 3px rgba(198,113,57,.16);
}
input:disabled, select:disabled, textarea:disabled { background: var(--o-n-200); color: var(--o-n-600); cursor: not-allowed; }
input::placeholder, textarea::placeholder { color: var(--o-n-500); }

/* Le chevron des <select> : dessiné en SVG en ligne, aucune requête réseau. */
select {
  -webkit-appearance: none; appearance: none; padding-right: 2.1rem; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2382796a' stroke-width='1.7'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .7rem center; background-size: 14px;
}
select[multiple] { background-image: none; padding-right: .85rem; border-radius: var(--radius); min-height: 7rem; }

.input-wrapper { position: relative; }
.input-icon { position: absolute; left: .8rem; top: 50%; transform: translateY(-50%); color: var(--o-n-500); pointer-events: none; }
.form-group-icon input { padding-left: 2.3rem; }
.field-error { color: var(--error); font-size: .78rem; margin-top: .28rem; font-weight: 600; }
input[type=radio], input[type=checkbox] { accent-color: var(--o-accent); width: 17px; height: 17px; min-height: 0; }
.toggle-mdp { background: none; border: 0; color: var(--o-n-600); cursor: pointer; }

/* ── Étiquettes, badges, alertes ────────────────────────────────────────── */
.badge, .tag, .st-role, .st-flag, .mp-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--font-body); font-size: .715rem; font-weight: 700;
  letter-spacing: .015em; padding: .16rem .58rem;
  border-radius: var(--radius-pill); border: 1px solid transparent; white-space: nowrap;
}
.badge-primary   { background: var(--o-a-100); color: var(--o-a-800); border-color: var(--o-a-200); }
.badge-secondary { background: var(--o-n-200); color: var(--o-n-800); border-color: var(--o-n-300); }
.badge-success   { background: var(--o-g-100); color: var(--o-g-800); border-color: var(--o-g-200); }
.badge-warning   { background: #fdf1d8; color: #7a4b06; border-color: #f3ddb0; }
.badge-danger    { background: #fbe6e1; color: #7e2716; border-color: #f3cdc4; }

.alert {
  display: flex; gap: .6rem; align-items: flex-start;
  padding: .75rem 1rem; border-radius: var(--radius);
  border: 1px solid transparent; border-left-width: 3px;
  font-size: .865rem; line-height: 1.5; margin-bottom: 1rem;
}
.alert-success { background: var(--o-g-100); color: var(--o-g-800); border-color: var(--o-g-300); border-left-color: var(--o-g-600); }
.alert-info    { background: var(--o-n-100); color: var(--o-n-800); border-color: var(--o-n-300); border-left-color: var(--o-n-600); }
.alert-warning { background: #fdf3de; color: #6f4405; border-color: #f0dcb2; border-left-color: #c98a12; }
.alert-error   { background: #fbe8e3; color: #7e2716; border-color: #f0cabf; border-left-color: #a8341f; }
.alert a { color: inherit; text-decoration: underline; text-underline-offset: 2px; font-weight: 600; }

/* ── Indicateurs chiffrés ───────────────────────────────────────────────── */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr)); gap: .9rem; margin-bottom: 1.6rem; }
.kpi-card { padding: 1.05rem 1.15rem; position: relative; overflow: hidden; }
.kpi-card:hover { border-color: var(--o-n-400); box-shadow: var(--shadow-md); }
.kpi-label {
  font-size: .69rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--o-n-700); margin-bottom: .3rem;
}
.kpi-value {
  font-family: var(--font-body); font-weight: 700; font-size: 1.72rem;
  line-height: 1.05; letter-spacing: -.02em; color: var(--text);
}
.kpi-detail { font-size: .765rem; color: var(--text-muted); margin-top: .3rem; }
.kpi-icon {
  position: absolute; top: .9rem; right: .95rem;
  width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--o-a-100); color: var(--o-a-700);
}
.kpi-icon svg { width: 18px; height: 18px; }
.kpi-success .kpi-icon { background: var(--o-g-100); color: var(--o-g-700); }
.kpi-warning .kpi-icon { background: #fdf1d8; color: #7a4b06; }
.kpi-danger  .kpi-icon { background: #fbe6e1; color: #7e2716; }
/* M8 : plus de liseré haut. La maquette approuvée pose des cartes blanches
   nues, et quatre liserés de couleurs différentes au-dessus de quatre chiffres
   font lire une alerte là où il n'y a qu'un total. */
.kpi-card::before { content: none; }

.charts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1rem; }
.chart-card { padding: 1.15rem; }
.chart-card h3, .chart-card h4 { margin: 0 0 .9rem; font-size: 1.08rem; }

/* ── Fenêtres modales ───────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: none; align-items: center; justify-content: center; padding: 1.1rem;
  background: rgba(32,30,29,.52);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  overflow-y: auto;
}
.modal-overlay.shown, .modal-overlay.open { display: flex; }
.modal {
  width: min(38rem, 100%); max-height: 92vh; overflow-y: auto;
  background: var(--bg-card); border: 1px solid var(--o-n-300);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-xl);
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1rem 1.2rem; border-bottom: 1px solid var(--o-n-300);
  background: var(--o-n-100);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.modal-header h3, .modal-header h4 { margin: 0; font-size: 1.14rem; }
.modal-close {
  background: none; border: 0; cursor: pointer; line-height: 1;
  font-size: 1.4rem; color: var(--o-n-600);
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
}
.modal-close:hover { background: rgba(32,30,29,.08); color: var(--text); }
.modal > form, .modal > div:not(.modal-header):not(.modal-footer) { padding: 1.2rem; }
.modal-footer {
  display: flex; justify-content: flex-end; gap: .5rem; flex-wrap: wrap;
  padding: .9rem 1.2rem; border-top: 1px solid var(--o-n-300); background: var(--o-n-100);
}

/* LA FENÊTRE D'ENCAISSEMENT (02/11/2026, vécu du propriétaire) : sur un écran
   de 1000 px, « Encaisser & imprimer » se trouvait à y≈1120 — SOUS le pli, et
   le défilement du corps était verrouillé : qui ne savait pas qu'il fallait
   faire défiler l'intérieur de la boîte ne voyait aucun bouton pour payer.
   Désormais le pied de CETTE fenêtre est collé au fond : les boutons restent
   visibles quels que soient le nombre de mois, frais, services et alertes. */
.modal.enc-fenetre { padding-bottom: 0; }
.modal.enc-fenetre > form { padding-bottom: 0; }
.modal.enc-fenetre > form > .modal-footer {
  position: sticky; bottom: 0;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* ── États vides, squelettes, pagination ────────────────────────────────── */
.empty-state { padding: 2.6rem 1.2rem; text-align: center; color: var(--text-muted); }
.empty-state h3, .empty-state h4 { color: var(--text); margin-bottom: .35rem; font-size: 1.1rem; }
.empty-state p { font-size: .87rem; max-width: 46ch; margin: 0 auto; }

.sk-bar { height: .7rem; border-radius: 99px; background: var(--o-n-200); animation: skPulse 1.4s ease-in-out infinite; }
.sk-w40 { width: 40%; } .sk-w70 { width: 70%; }
@keyframes skPulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }

.pagination { display: flex; gap: .3rem; flex-wrap: wrap; align-items: center; justify-content: center; padding: .9rem; }
.pagination a, .pagination span {
  min-width: 2.1rem; height: 2.1rem; padding: 0 .55rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .82rem; font-weight: 600; border-radius: var(--radius-pill);
  border: 1px solid var(--o-n-300); color: var(--text); background: var(--bg-card);
}
.pagination a:hover { background: var(--o-a-100); border-color: var(--o-a-300); color: var(--o-a-800); }
.pagination .active, .pagination [aria-current] { background: var(--o-a-700); border-color: var(--o-a-700); color: #fffaf1; }

/* ── Divers propres au domaine ──────────────────────────────────────────── */
.cycle-sep td, .cycle-sep th, .fam-head td {
  background: var(--o-n-200); font-family: var(--font-heading); font-weight: 400;
  font-size: .95rem; color: var(--o-n-800); letter-spacing: 0;
}
.text-muted { color: var(--text-muted); }
.warn { color: var(--warning); font-weight: 600; }
.go   { color: var(--o-g-700); font-weight: 600; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.mois-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: .55rem; }
.mois-card {
  background: var(--bg-card); border: 1px solid var(--o-n-300);
  border-radius: var(--radius); padding: .6rem .7rem; font-size: .82rem;
}
.mois-nom { font-weight: 700; font-size: .84rem; }
.mois-etat { font-size: .74rem; color: var(--text-muted); }
.hub-nav { background: rgba(253,250,243,.94); border-bottom: 1px solid var(--o-n-300); }
.hub-tab { font-family: var(--font-body); font-weight: 600; font-size: .84rem; }
.hub-tab.is-active { color: var(--o-a-800); border-color: var(--o-accent); }

/* ── ADAPTATION AUX ÉCRANS ──────────────────────────────────────────────── */
/* Le tiroir s'ouvre jusqu'à 1024 px et non 768 : sur une tablette en portrait,
   264 px de barre latérale sur 768 ne laissaient pas de quoi lire un tableau. */
@media (max-width: 1024px) {
  .sidebar {
    transform: translateX(-100%); box-shadow: none;
    width: min(84vw, 300px); will-change: transform;
  }
  html[dir='rtl'] .sidebar { transform: translateX(100%); }
  .sidebar.open { transform: translateX(0); box-shadow: var(--shadow-xl); }
  .sidebar-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; padding: 0; flex-shrink: 0;
    background: var(--bg-card); color: var(--text);
    border: 1px solid var(--o-n-300); border-radius: var(--radius);
  }
  .sidebar-toggle:hover { background: var(--o-a-100); border-color: var(--o-a-300); }
  .main-content { margin-left: 0; padding: 0 1rem 2rem; }
  .main-content > .entete-app,
  .main-content > .page-header { margin-inline: -1rem; max-width: none; }
  /* Le bouton du menu vit dans l'en-tête de la coquille (M8) : l'en-tête de page
     n'a plus à lui réserver une gouttière à gauche. */
  .page-header { padding-left: 1rem; }
  /* Voile : sans lui, on croit pouvoir agir sur la page derrière le tiroir. */
  .sidebar-backdrop {
    position: fixed; inset: 0; z-index: 99; background: rgba(32,30,29,.45);
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none; transition: opacity .18s ease;
  }
  .sidebar-backdrop.shown { opacity: 1; pointer-events: auto; }
  .charts-grid { grid-template-columns: 1fr; }
}
@media (min-width: 1025px) { .sidebar-backdrop { display: none; } }

@media (max-width: 900px) {
  /* Sous 900 px, l'identité de l'école passe dans l'en-tête : c'est le seul
     endroit où elle reste visible quand la barre latérale est un tiroir. */
  .entete-app .identite-ecole { display: flex; }
  .entete-app .fil-ariane { display: none; }
}

@media (max-width: 720px) {
  .entete-app { padding-inline: .85rem; gap: .5rem; }
  .entete-app .avatar-nom { display: none; }
  .entete-app .avatar-lien { padding: .2rem; }
  .page-header { padding: .85rem 1rem; }
  .page-title { font-size: 1.3rem; }
  .page-subtitle { font-size: .8rem; }
  .page-content { padding: 1rem .85rem 2.4rem; }
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: .6rem; }
  .kpi-card { padding: .85rem .9rem; }
  .kpi-value { font-size: 1.42rem; }
  .kpi-icon { display: none; }
  .form-card { padding: 1rem; }
  .form-row { grid-template-columns: 1fr; }
  .table-header { align-items: flex-start; }
  .section-title-row > h2, .section-title-row > h3 { font-size: 1.1rem; }
  /* Zone tactile confortable : 44 px, sans grossir le texte. */
  .btn { min-height: 40px; padding: .5rem 1rem; }
  .btn-sm { min-height: 34px; }
  input, select, textarea, .input { min-height: 42px; font-size: .9rem; }
  /* iOS zoome sur tout champ sous 16 px : on force la taille sur le tactile. */
  @supports (-webkit-touch-callout: none) {
    input, select, textarea { font-size: 16px; }
  }
  table { font-size: .82rem; }
  thead th { padding: .5rem .6rem; font-size: .64rem; }
  tbody td { padding: .5rem .6rem; }
  .modal { width: 100%; max-height: 94vh; }
  .modal-footer .btn { flex: 1 1 8rem; }
}

@media (max-width: 420px) {
  .kpi-grid { grid-template-columns: 1fr; }
  .page-header-right { width: 100%; }
  .header-annee select, #hdr-annee { max-width: 100%; width: 100%; }
  .header-date { display: none; }
}

/* Écrans très larges : on laisse respirer plutôt qu'étirer les tableaux. */
@media (min-width: 1800px) {
  .page-content { padding: 2rem 2.4rem; margin-inline: auto; }
}

/* Certains utilisateurs sont gênés par le mouvement, et un poste modeste le
   rend saccadé. On respecte le réglage du système. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* Impression : le fond décoratif ne doit pas partir à l'encre. */
@media print {
  body { background: #fff !important; background-image: none !important; }
  .sidebar-backdrop, .sidebar-toggle { display: none !important; }
}

/* ============================================================================
   COUCHE DE FINITION — HIERARCHIE, LISIBILITE, ACCESSIBILITE
   ============================================================================
   Ajoutee en fin de feuille : elle ne redefinit aucun composant, elle corrige
   ce que l'usage a revele. */

/* ── 1. LE POIDS DES BOUTONS DANS LES LISTES ─────────────────────────────────
   « Gestion de caisse » affichait 1 373 boutons terre cuite pleins : un par
   ligne. Repeter le bouton le plus fort autant de fois supprime toute
   hierarchie — plus rien ne ressort, et l'ecran devient un mur orange.
   Une action de ligne garde son affordance mais reprend un poids discret ;
   les boutons hors tableau (valider, encaisser) restent pleins. */
.table-container tbody .btn-primary,
.data-table tbody .btn-primary,
.table-responsive tbody .btn-primary {
  background: transparent;
  color: var(--o-a-700);              /* 6,5:1 sur le creme — lisible */
  border: 1px solid var(--o-a-300);
  box-shadow: none;
  font-weight: 600;
}
.table-container tbody .btn-primary:hover,
.data-table tbody .btn-primary:hover,
.table-responsive tbody .btn-primary:hover {
  background: var(--o-a-100);
  border-color: var(--o-a-500);
  color: var(--o-a-800);
}

/* Variante explicite, pour les actions vraiment secondaires. */
.btn-ghost {
  background: transparent; color: var(--o-a-700);
  border: 1px solid transparent; box-shadow: none;
}
.btn-ghost:hover { background: var(--o-a-100); border-color: var(--o-a-300); }

/* ── 2. LE FOCUS SE VOIT ─────────────────────────────────────────────────────
   Une partie des controles n'avait aucun indicateur de focus : au clavier, on
   ne savait plus ou l'on etait. L'anneau est pose sur tout ce qui est
   actionnable, dans la couleur d'accent. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--o-a-600);
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* ── 3. RYTHME DES LIGNES ────────────────────────────────────────────────────
   Les cellules dont le texte passait a la ligne rendaient les hauteurs
   irregulieres. On aligne en haut et on donne une hauteur de ligne stable. */
.table-container td, .data-table td, .table-responsive td { vertical-align: middle; }
.table-container th, .data-table th, .table-responsive th { white-space: nowrap; }

/* ── 4. LES NOMBRES S'ALIGNENT ───────────────────────────────────────────────
   Montants et effectifs se comparent en colonne : des chiffres de largeur
   fixe les rendent lisibles d'un coup d'oeil. */
.montant, .table-container td:has(+ td):not(:first-child) { font-variant-numeric: tabular-nums; }
.table-container td, .data-table td { font-variant-numeric: tabular-nums; }

/* ── 5. ZONE TACTILE ─────────────────────────────────────────────────────────
   Sous 1024 px l'application se manipule au doigt : 24 px de haut ne suffisent
   pas. On garantit la cible minimale recommandee sans changer l'aspect au
   bureau. */
@media (max-width: 1024px) {
  .btn, .btn-sm, .modal-close, .sidebar-toggle { min-height: 40px; }
  .btn-sm { padding-inline: .7rem; }
}

/* ── 6. MOUVEMENT ────────────────────────────────────────────────────────────
   Respecte le reglage systeme de ceux que l'animation gene. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ============================================================================
   ACCESSIBILITE — CORRECTIFS MESURES (WCAG 2.2 AA)
   ============================================================================
   Chaque valeur ci-dessous a ete choisie sur un rapport de contraste calcule,
   pas a l'oeil. Les ratios sont indiques en commentaire. */

/* 1. BORDURES DE CHAMPS — 2,01:1, sous le minimum de 3:1 exige pour la
      limite d'un controle. C'etait la bordure au repos de TOUS les champs. */
input[type="text"], input[type="number"], input[type="date"], input[type="email"],
input[type="password"], input[type="tel"], input[type="search"], select, textarea, .input {
  border-color: var(--o-n-600);                    /* 4,29:1 sur blanc */
}
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) {
  border-color: var(--o-n-700);
}
.btn-secondary { border-color: var(--o-n-600); }

/* 2. LIENS — la terre cuite #c67139 ne donne que 3,47:1 sur la carte creme.
      C'est la couleur de tout lien en pleine prose. */
a { color: var(--o-a-700); }                       /* 6,5:1 */
a:hover { color: var(--o-a-800); text-decoration: underline; }

/* 3. LIEN D'EVITEMENT — il n'avait qu'une regle `:focus` qui le passait en
      blanc casse SUR DU CREME (1,15:1) : le seul controle destine a un
      utilisateur au clavier devenait invisible au moment precis ou il
      servait. Il lui manquait aussi tout positionnement. */
.skip-link {
  position: absolute; top: -3rem; left: .6rem; z-index: 1000;
  background: var(--o-a-800); color: #fffaf1;      /* 12,2:1 */
  padding: .6rem 1rem; border-radius: 0 0 8px 8px;
  transition: top .15s ease;
}
.skip-link:focus { top: .6rem; }

/* 4. TEXTE « succes » — le vert olive convient a une barre d'accent (3:1
      suffit) mais pas a du texte : 4,05:1 < 4,5:1. */
.text-success { color: var(--o-g-700); }           /* 6,2:1 */

/* 5. ETATS DE PAIEMENT — libelles de 12 px, donc seuil a 4,5:1. */
.mois-card.is-paye .mois-etat    { color: var(--o-g-700); }   /* 6,1:1 */
.mois-card.is-partial .mois-etat { color: var(--o-a-800); }   /* 9,8:1 */

/* 6. ENCADRE DE MOYENNE — l'etiquette passait a 3,62:1 sur l'extremite
      claire du degrade. M8 : aplat terre cuite sombre, plus de brun. */
.moyenne-box { background: var(--o-a-800); }
.moyenne-box .summary-label { color: var(--o-a-100); }

/* 9. BARRES COLLANTES — l'en-tete de page et la barre d'onglets restent
      fixes en haut. Sans marge de defilement, un element atteint au clavier
      se place DESSOUS et son anneau de focus devient invisible
      (WCAG 2.2 — Focus Not Obscured). */
html { scroll-padding-top: 150px; }

/* 10. CASES ET BOUTONS RADIO — 17 px de cote, sous les 24 px recommandes.
       On etend la zone atteignable sans changer l'aspect. */
input[type="radio"], input[type="checkbox"] { position: relative; }
input[type="radio"]::after, input[type="checkbox"]::after {
  content: ''; position: absolute; inset: -4px;    /* cible effective 25 x 25 */
}
