:root{
  --navy:#1F3864; --navy-dark:#132646; --red:#A31621; --red-dim:#c94656;
  --cream:#F7F5EF; --paper:#FFFFFF; --ink:#20242B; --muted:#6B7280;
  --border:#E3E0D6; --success:#2E7D32; --success-bg:#E8F3E9;
  --warn:#8A5A00; --warn-bg:#FCF1DC; --danger:#A31621; --danger-bg:#FBEAEC;
  --font-display:'Fraunces',serif; --font-body:'Inter',sans-serif; --font-mono:'IBM Plex Mono',monospace;
  --radius:10px;
}
*{box-sizing:border-box;}
html,body{margin:0;padding:0;height:100%;}
body{font-family:var(--font-body);color:var(--ink);background:var(--cream);}
h1,h2,h3{font-family:var(--font-display);font-weight:600;margin:0;}
button{font-family:var(--font-body);cursor:pointer;}
input,select,textarea{font-family:var(--font-body);}
.hidden{display:none !important;}
::selection{background:var(--red);color:#fff;}

/* ---------- Landing (choose portal) ---------- */
#landingScreen{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(circle at 20% 20%,#24406f,var(--navy-dark) 65%);
  padding:24px;
}
.landing-wrap{max-width:640px;width:100%;text-align:center;}
.landing-title{color:#fff;font-size:28px;line-height:1.3;margin-bottom:8px;}
.landing-sub{color:rgba(255,255,255,.75);font-size:14px;margin-bottom:32px;}
.landing-cards{display:grid;grid-template-columns:1fr 1fr;gap:18px;}
.landing-card{
  background:#fff;border-radius:16px;padding:30px 22px;cursor:pointer;
  border-top:5px solid var(--red);box-shadow:0 20px 45px rgba(0,0,0,.25);
  transition:transform .12s ease, box-shadow .12s ease;
}
.landing-card:hover{transform:translateY(-4px);box-shadow:0 26px 55px rgba(0,0,0,.32);}
.landing-card__icon{font-size:38px;margin-bottom:12px;}
.landing-card h3{color:var(--navy);font-size:17px;margin-bottom:8px;}
.landing-card p{color:var(--muted);font-size:12.5px;line-height:1.5;}
@media (max-width:560px){ .landing-cards{grid-template-columns:1fr;} }

/* ---------- Login ---------- */
#loginScreen, #studentLoginScreen, #teacherLoginScreen, #clinicLoginScreen{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:var(--login-bg-image, radial-gradient(circle at 20% 20%,#24406f,var(--navy-dark) 65%));
  background-size:cover;background-position:center;background-repeat:no-repeat;
  padding:24px;
  opacity:0;transition:opacity .25s ease;
  animation:loginRevealFallback 0s 4s forwards; /* pure-CSS safety net: reveals after 4s even if JS never runs at all (e.g. shared.js blocked) -- the .branding-ready path above is what normally fires first (RAPPORT 264 : cache de l'appareil, puis 2,5 s) */
}
@keyframes loginRevealFallback{ to{ opacity:1; } }
/* Avoids a visible flash of the default navy gradient before an institution's custom
   login background (set in Paramètres > Apparence) finishes loading -- the screen stays
   invisible (not display:none, so layout/centering is already correct) until JS adds
   .branding-ready to <html>, which happens right after applyBranding() resolves (or a
   short safety timeout fires, so login never gets stuck hidden if that fetch is slow/fails). */
html.branding-ready #loginScreen, html.branding-ready #studentLoginScreen,
html.branding-ready #teacherLoginScreen, html.branding-ready #clinicLoginScreen{
  opacity:1;
}
.login-card{
  background:var(--paper);width:100%;max-width:400px;border-radius:16px;
  box-shadow:0 30px 60px rgba(0,0,0,.35);overflow:hidden;
  border-top:6px solid var(--red);
}
.login-card__inner{padding:40px 36px 32px;}
.crest{
  width:56px;height:56px;border-radius:50%;background:var(--navy);color:#fff;
  display:flex;align-items:center;justify-content:center;font-family:var(--font-display);
  font-weight:700;font-size:15px;letter-spacing:.5px;margin:0 auto 18px;
  border:3px solid var(--red);
}
.login-card h1{font-size:22px;text-align:center;color:var(--navy);line-height:1.3;}
.login-card p.sub{text-align:center;color:var(--muted);font-size:13px;margin:8px 0 28px;}
.field{margin-bottom:16px;}
.field label{display:block;font-size:12px;font-weight:600;color:var(--muted);margin-bottom:6px;text-transform:uppercase;letter-spacing:.04em;}
.field input,.field select,.field textarea{
  width:100%;padding:11px 13px;border:1.5px solid var(--border);border-radius:8px;
  font-size:14px;background:#fff;color:var(--ink);
}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--navy);}
.btn{
  border:none;border-radius:8px;padding:11px 18px;font-size:14px;font-weight:600;
  display:inline-flex;align-items:center;gap:7px;transition:transform .06s ease, opacity .15s;
}
.btn:active{transform:scale(.98);}
.btn-primary{background:var(--navy);color:#fff;width:100%;justify-content:center;padding:13px;}
.btn-primary:hover{background:var(--navy-dark);}
.btn-ms{
  width:100%;justify-content:center;margin-top:10px;background:#fff;color:#3c3c3c;
  border:1.5px solid var(--border);padding:11px;font-size:13.5px;
}
.btn-ms:hover{background:#f5f5f5;}
.login-card__divider{display:flex;align-items:center;gap:10px;margin:18px 0 14px;color:var(--muted);font-size:11.5px;text-transform:uppercase;letter-spacing:.05em;}
.login-card__divider::before,.login-card__divider::after{content:"";flex:1;height:1px;background:var(--border);}
.btn-red{background:var(--red);color:#fff;}
.btn-red:hover{opacity:.9;}
.btn-ghost{background:transparent;color:var(--navy);border:1.5px solid var(--border);}
.btn-ghost:hover{border-color:var(--navy);}
.btn-sm{padding:6px 10px;font-size:12px;border-radius:6px;}
.btn:disabled{opacity:.45;cursor:not-allowed;}
.storage-note{margin-top:18px;font-size:11.5px;color:var(--muted);text-align:center;line-height:1.5;}

/* ---------- App shell ---------- */
#app{display:none;min-height:100vh;grid-template-rows:auto 1fr;}
#app.active{display:grid;}
.topbar{
  background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:space-between;
  padding:0 22px;height:60px;border-bottom:3px solid var(--red);
}
.topbar__brand{display:flex;align-items:center;gap:12px;}
.topbar__brand .crest{width:34px;height:34px;font-size:10px;margin:0;border-width:2px;}
.topbar__brand h1{font-size:16px;color:#fff;letter-spacing:.01em;}
.topbar__user{display:flex;align-items:center;gap:12px;font-size:13px;}
.role-pill{
  font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  padding:3px 9px;border-radius:999px;background:rgba(255,255,255,.16);color:#fff;
}
.role-pill.admin{background:var(--red);}
.status-pill{
  font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;
  padding:3px 9px;border-radius:999px;display:inline-block;
}
.status-pill.status-actif{background:var(--success-bg);color:var(--success);}
.status-pill.status-suspendu{background:#fff4dd;color:#9a6b00;}
.status-pill.status-desactive{background:var(--danger-bg);color:var(--danger);}
.status-pill.status-transfere{background:#e6ecf5;color:var(--navy);}
/* AUDIT 2026-10-16 (Norman : cohérence) -- UN seul jeu de pastilles pour l'état d'une déclaration
   de paiement, partout (file de l'Économat, portail Étudiant, page publique, candidatures). */
.pill-pending{background:#8A5A00;color:#fff;}
.pill-verified{background:var(--success);color:#fff;}
.pill-rejected{background:var(--danger);color:#fff;}
.pill-unlinked{background:#fff4dd;color:#9a6b00;}
/* Bandeau de retour d'information (feedback) après une action : ce qui vient d'être fait, avec
   l'étape suivante à portée de clic -- jamais un alert() bloquant. */
.feedback-banner{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 14px;border-radius:8px;border:1px solid #cfe3d4;background:var(--success-bg);color:var(--success);font-size:13px;margin-bottom:14px;}
.feedback-banner.danger{border-color:#f0c7cc;background:var(--danger-bg);color:var(--danger);}
.feedback-banner b{font-weight:700;}
.feedback-banner .btn{margin-left:auto;}
.feedback-banner .btn + .btn{margin-left:0;}
.verif-dl{display:grid;grid-template-columns:max-content 1fr;gap:6px 14px;font-size:13px;margin:0 0 12px;}
.verif-dl dt{color:var(--muted);}
.verif-dl dd{margin:0;}
.verif-proof{border:1px solid var(--border);border-radius:8px;background:var(--cream);padding:8px;margin:8px 0 14px;text-align:center;}
.verif-proof img{max-width:100%;max-height:360px;border-radius:4px;}
.verif-proof iframe{width:100%;height:420px;border:none;background:#fff;}
.verif-reasons{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 8px;}
.verif-reasons button{font-size:12px;padding:4px 10px;border-radius:999px;border:1px solid var(--border);background:#fff;cursor:pointer;}
.verif-reasons button.on{background:var(--navy);color:#fff;border-color:var(--navy);}
.modal__foot .btn.danger{border-color:var(--danger);color:var(--danger);}
.modal__foot .spacer{flex:1;}

/* Sync fix: these rules existed only in public/assets/css/shared.css, not here --
   the "myapps-grid"/"myapp-tile" markup (Teams/Outlook/Office 365/OneDrive/Moodle
   tiles) is used by both app/*/index.php (which loads the public/assets copy, so
   it looked fine there) AND the standalone index_admin.html/index_etudiant.html/
   index_enseignant.html/index_clinique.html mirrors (which load THIS file) -- so
   the tiles rendered completely unstyled on the standalone HTML deployment path.
   Keep this block identical between both shared.css copies going forward. */
.myapps-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:16px;}
.myapp-tile{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  background:#fff;border:1px solid var(--border);border-radius:12px;padding:26px 16px;
  text-decoration:none;color:var(--ink);transition:transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.myapp-tile:hover{transform:translateY(-3px);box-shadow:0 10px 24px rgba(0,0,0,.08);border-color:var(--red);}
.myapp-tile__icon{font-size:34px;line-height:1;}
.myapp-tile__name{font-size:13.5px;font-weight:600;text-align:center;}
.myapp-tile__sub{font-size:11px;color:var(--muted);text-align:center;margin-top:-6px;}

.topbar__user button{background:transparent;border:1px solid rgba(255,255,255,.4);color:#fff;border-radius:7px;padding:7px 12px;font-size:12.5px;}
.topbar__user button:hover{background:rgba(255,255,255,.12);}

.layout{display:grid;grid-template-columns:220px 1fr;min-height:0;}
.sidebar{background:#fff;border-right:1px solid var(--border);padding:18px 12px;}
.nav-item{
  display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;
  font-size:13.5px;font-weight:500;color:var(--ink);cursor:pointer;margin-bottom:2px;
  border-left:3px solid transparent;
  transition:background .12s ease,border-color .12s ease,color .12s ease;
}
/* RAPPORT 97 : le survol était quasi invisible (fond crème à peine plus foncé que le
   fond blanc de la barre) -- l'admin devait déjà connaître l'emplacement d'un item pour
   le distinguer au survol (Norman: feedback). Le nouveau survol reprend la teinte rouge
   de la sélection mais en dose plus faible et sans le trait plein gauche, pour rester
   clairement en-deçà de .active (sélection confirmée) tout en étant immédiatement visible. */
.nav-item:hover{background:rgba(163,22,33,.10);border-left-color:var(--red-dim);color:var(--navy);}
.nav-item.active{background:var(--danger-bg);border-left-color:var(--red);color:var(--red);font-weight:700;}
.nav-item.active:hover{background:var(--danger-bg);border-left-color:var(--red);color:var(--red);}
/* Pastille rouge « il y a du nouveau ici » sur un item de navigation (compteur de
   paiements/demandes en attente d'action) -- un seul style partagé par tous les badges
   de nav plutôt qu'un style en ligne répété à chaque fois. */
.count-badge{background:var(--red);color:#fff;border-radius:999px;font-size:10px;padding:1px 7px;margin-left:4px;}
.sidebar .storage-note{padding:14px 8px 0;border-top:1px solid var(--border);margin-top:14px;}

.nav-group{margin-bottom:2px;}
.nav-group__header{
  display:flex;align-items:center;justify-content:space-between;padding:10px 12px;
  font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--nav-teinte, var(--muted));
  cursor:pointer;border-radius:8px;
  transition:background .12s ease,color .12s ease;
}
.nav-group__header:hover{background:var(--nav-teinte-voile, rgba(163,22,33,.10));}
.nav-group__chevron{transition:transform .15s ease;font-size:10px;}
.nav-group.collapsed .nav-group__chevron{transform:rotate(-90deg);}
.nav-group__items{overflow:hidden;max-height:400px;transition:max-height .18s ease;}
.nav-group.collapsed .nav-group__items{max-height:0;}
.nav-group__items .nav-item{padding-left:22px;}

/* ---------- Code couleur du menu (RAPPORT 167) ----------
   Une teinte par section. Elle sert à trois endroits, et c'est cette RÉPÉTITION qui en
   fait un code plutôt qu'une décoration : le libellé du groupe, le filet gauche de l'item
   actif, et le titre de l'écran ouvert. Norman, mapping — la couleur relie l'endroit d'où
   l'on vient à l'endroit où l'on est.

   Trois règles tenues :
   1. **La couleur n'encode jamais rien à elle seule.** Chaque groupe porte son nom en
      toutes lettres ; la teinte accélère la reconnaissance, elle ne la remplace pas. Un
      écran daltonien, imprimé en noir et blanc ou en contraste forcé perd la couleur et
      garde toute l'information.
   2. **Les lettres du groupe et celles de ses items sont de couleurs différentes** : le
      groupe s'écrit dans sa teinte (petites capitales), ses items en encre neutre. La
      hiérarchie se lit donc sans avoir à comparer des tailles.
   3. **Chaque teinte tient 5,8:1 sur blanc** (mesuré, pas estimé) : elles sont portées par
      du texte, pas par des pastilles, et un texte de 11 px en capitales est ce qui pardonne
      le moins un contraste faible.

   Le rouge institutionnel reste réservé à l'ATTENTION (badges, suppressions, erreurs) : lui
   donner en plus un rôle de section l'aurait vidé de son sens là où il compte. */
.nav-group[data-teinte="rapports"]     { --nav-teinte:#1F3864; --nav-teinte-voile:rgba(31,56,100,.10); }
.nav-group[data-teinte="economat"]     { --nav-teinte:#0F6B3C; --nav-teinte-voile:rgba(15,107,60,.10); }
.nav-group[data-teinte="registrariat"] { --nav-teinte:#7B2D8E; --nav-teinte-voile:rgba(123,45,142,.10); }
.nav-group[data-teinte="personnel"]    { --nav-teinte:#8A5A00; --nav-teinte-voile:rgba(138,90,0,.10); }
.nav-group[data-teinte="utilisateurs"] { --nav-teinte:#1F6E80; --nav-teinte-voile:rgba(31,110,128,.10); }
.nav-group[data-teinte="outils"]       { --nav-teinte:#55595E; --nav-teinte-voile:rgba(85,89,94,.10); }

/* Les items d'un groupe : encre neutre au repos, la teinte du groupe au survol et à la
   sélection. L'écart entre le libellé du groupe (teinte) et ses items (encre) est ce que
   l'œil lit comme « ceci est dans cela ». */
.nav-group__items .nav-item{color:var(--ink);}
.nav-group__items .nav-item:hover{
  background:var(--nav-teinte-voile);border-left-color:var(--nav-teinte);color:var(--nav-teinte);
}
.nav-group__items .nav-item.active,
.nav-group__items .nav-item.active:hover{
  background:var(--nav-teinte-voile);border-left-color:var(--nav-teinte);color:var(--nav-teinte);
}
/* Un groupe qui CONTIENT l'écran ouvert garde son libellé lisible même replié : sans cela,
   replier le groupe où l'on travaille efface la seule trace de l'endroit où l'on est. */
.nav-group:has(.nav-item.active) .nav-group__header{background:var(--nav-teinte-voile);}

/* Accès personnels, détachés des sections de l'établissement par un filet. */
.nav-perso{margin-top:10px;padding-top:8px;border-top:1px solid var(--border);}

.main{padding:26px 30px 60px;overflow-y:auto;}
.view{display:none;}
.view.active{display:block;}
.clinic-view{display:none;}
.clinic-view.active{display:block;}
.subtab-view{display:none;}
.subtab-view.active{display:block;}
.subtab-nav{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px;border-bottom:1px solid var(--border);padding-bottom:0;}
.subtab-nav .nav-item{border:none;border-bottom:3px solid transparent;border-radius:8px 8px 0 0;margin-bottom:-1px;padding:9px 12px;}
.subtab-nav .nav-item.active{background:var(--cream);border-bottom-color:var(--red);}
/* RAPPORT 217 -- écran Suspensions à onglets : en-tête de liste (titre + recherche), compteur
   dans l'onglet (le .role-pill est pensé pour le bandeau sombre, illisible sur fond clair),
   et boutons d'action en TEXTE -- .icon-btn fait 32px de large, un libellé y est coupé
   (« ✔ Dérogation » s'affichait « rogat », « 🗑 Lever » « ever »). */
.susp-list-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:18px 18px 10px;}
.susp-list-head h3{margin:0;}
.susp-list-head input[type=search]{max-width:320px;width:100%;}
.susp-count{display:inline-block;min-width:18px;padding:1px 7px;border-radius:999px;background:var(--navy);color:#fff;font-size:11px;font-weight:700;text-align:center;vertical-align:middle;}
.susp-count:empty{display:none;}
.action-icons .btn{white-space:nowrap;}
.susp-etat{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:3px 9px;border-radius:999px;display:inline-block;white-space:nowrap;}
.susp-etat--a_desactiver{background:var(--danger-bg);color:var(--danger);}
.susp-etat--deja_suspendu{background:#fff4dd;color:#9a6b00;}
.susp-etat--solde_regle{background:var(--success-bg);color:var(--success);}
.susp-etat--pas_echu{background:#e6ecf5;color:var(--navy);}
.susp-fiche-table td:first-child{color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;padding-right:14px;}
.view-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:22px;flex-wrap:wrap;gap:12px;}
/* RAPPORT 167 -- le titre de l'écran porte la teinte de sa section (posée sur <html> par
   showView). Même palette que le menu, à la lettre près : c'est ce qui relie les deux. */
:root[data-section="rapports"]     { --section:#1F3864; }
:root[data-section="economat"]     { --section:#0F6B3C; }
:root[data-section="registrariat"] { --section:#7B2D8E; }
:root[data-section="personnel"]    { --section:#8A5A00; }
:root[data-section="utilisateurs"] { --section:#1F6E80; }
:root[data-section="outils"]       { --section:#55595E; }
.view-header h2{font-size:24px;color:var(--section, var(--navy));}
/* Le filet sous le titre reprend la teinte : un rappel discret, à hauteur d'œil, de la
   section dans laquelle on travaille -- utile quand le menu est replié ou hors écran
   (téléphone), c'est-à-dire précisément quand le menu ne peut plus le dire. */
.view-header{border-bottom:2px solid var(--section, var(--border));padding-bottom:12px;}
.view-header p{color:var(--muted);font-size:13px;margin-top:4px;}

/* ---------- Cards / stats ---------- */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:14px;margin-bottom:26px;}
.stat-card{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;}
.stat-card .lbl{font-size:11.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;font-weight:600;}
.stat-card .val{font-family:var(--font-display);font-size:26px;font-weight:600;color:var(--navy);margin-top:6px;}
.stat-card.danger .val{color:var(--red);}
.stat-card.success .val{color:var(--success);}

.panel{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:20px;margin-bottom:20px;overflow-x:auto;}
.panel h3{font-size:15px;color:var(--navy);margin-bottom:14px;}

table{width:100%;border-collapse:collapse;font-size:13px;}
th{text-align:left;padding:9px 10px;background:var(--cream);color:var(--muted);font-size:11px;
   text-transform:uppercase;letter-spacing:.03em;font-weight:700;border-bottom:1px solid var(--border);}
td{padding:9px 10px;border-bottom:1px solid var(--border);vertical-align:middle;}
tr:hover td{background:#FAFAF7;}
.mono{font-family:var(--font-mono);font-size:12px;}
.balance-pos{color:var(--red);font-weight:700;}
.balance-zero{color:var(--success);font-weight:700;}
/* RAPPORT 74 : mini-jauge de taux (Analytique -> notes publiées par niveau). Couleur
   fournie inline par appelant (rouge/ambre/vert selon le taux), jamais codée ici. */
.rate-bar{display:inline-block;width:120px;height:8px;background:var(--border);border-radius:999px;overflow:hidden;vertical-align:middle;margin-right:8px;}
.rate-bar__fill{height:100%;border-radius:999px;}
.price-reveal{cursor:pointer;color:var(--navy);text-decoration:underline dotted;text-underline-offset:2px;}
.price-reveal:hover{color:var(--red);}

/* ---------- Analytique : barres horizontales (RAPPORT 97) ----------
   Barres en HTML/CSS (pas de SVG) : l'Analytique n'était que des tableaux avant ce
   correctif, sans aucune lecture visuelle de grandeur ni de proportion -- un admin devait
   lire chaque ligne pour comparer deux niveaux entre eux. Deux familles seulement :
   .chart-row__fill (une seule barre = une grandeur, ex. effectif par niveau -- une seule
   teinte, jamais une couleur "par catégorie" puisqu'il n'y a qu'une seule série) et un
   groupe de segments contigus dans .chart-row__track (une barre = une proportion
   partie/tout, ex. notes publiées vs. non publiées -- un 2px d'écart réel entre segments,
   jamais un dégradé continu qui maquille la frontière). Les couleurs de statut
   (succès/alerte/danger) restent réservées à leur sens déjà établi ailleurs dans l'appli
   -- jamais recyclées comme simples teintes de remplissage supplémentaires. */
.chart-row{display:grid;grid-template-columns:130px 1fr auto;align-items:center;gap:10px;padding:5px 0;}
.chart-row__label{font-size:12.5px;color:var(--ink);font-weight:600;}
.chart-row__track{position:relative;height:14px;background:var(--cream);border-radius:999px;overflow:hidden;}
.chart-row__fill{position:absolute;top:0;left:0;height:100%;border-radius:999px;background:var(--navy);transition:width .3s ease;}
.chart-row__value{font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right;}
.chart-legend{display:flex;gap:16px;flex-wrap:wrap;margin-bottom:10px;font-size:11.5px;color:var(--muted);}
.chart-legend__item{display:flex;align-items:center;gap:6px;}
.chart-legend__swatch{width:10px;height:10px;border-radius:3px;display:inline-block;flex-shrink:0;}
.chart-data-toggle{margin-top:12px;}
.chart-data-toggle summary{cursor:pointer;font-size:12px;color:var(--navy);font-weight:600;}
.chart-data-toggle table{margin-top:10px;}

/* ---------- Filters ---------- */
.filter-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:end;margin-bottom:16px;}
.filter-bar .field{margin-bottom:0;min-width:150px;}
.filter-bar .field.grow{flex:1;min-width:200px;}

.bulk-bar{
  display:flex;align-items:center;gap:10px;background:var(--danger-bg);border:1px solid #f0c7cc;
  border-radius:8px;padding:10px 14px;margin-bottom:14px;font-size:13px;color:var(--red);font-weight:600;
}
.bulk-bar .spacer{flex:1;}

.action-icons{display:flex;gap:6px;}
.icon-btn{
  background:var(--navy);border:1px solid var(--navy);border-radius:6px;width:32px;height:32px;
  display:flex;align-items:center;justify-content:center;font-size:14px;color:#fff;
}
.icon-btn:hover{background:var(--navy-dark);}
.icon-btn.danger{background:var(--red);border-color:var(--red);}
.icon-btn.danger:hover{opacity:.85;}

.dropzone{
  border:2px dashed var(--border);border-radius:10px;padding:30px 16px;text-align:center;
  cursor:pointer;background:var(--cream);transition:border-color .15s, background .15s;
}
.dropzone:hover{border-color:var(--navy);}
.dropzone--active{border-color:var(--red);background:var(--danger-bg);}
.dropzone__icon{font-size:30px;margin-bottom:6px;}
.dropzone__text{font-size:13px;color:var(--muted);}

/* ---------- Payment split layout ---------- */
.pay-split{display:grid;grid-template-columns:1fr 1.1fr;gap:16px;align-items:start;}
.pay-split__list{padding:0;overflow:auto;max-height:68vh;}
.pay-split__list table{font-size:12.5px;}
/* AUDIT 2026-10-16 (Norman : visibilité) -- plus de défilement INTERNE : le bouton « Enregistrer » n'est plus caché sous le pli d'un panneau qui défile. */
.pay-split__detail{align-self:start;}
@media (max-width:900px){
  .pay-split{grid-template-columns:1fr;}
  .pay-split__detail{position:static;}
}

/* ---------- Modal ---------- */
.overlay{
  position:fixed;inset:0;background:rgba(19,38,70,.55);display:none;align-items:center;justify-content:center;
  padding:24px;z-index:100;
}
.overlay.active{display:flex;}
.modal{background:#fff;border-radius:14px;max-width:560px;width:100%;max-height:88vh;overflow-y:auto;
       box-shadow:0 40px 80px rgba(0,0,0,.3);}
.modal.wide{max-width:720px;}
/* RAPPORT 89 : un document sur papier officiel a une largeur fixe (612 pt = 816 px) : la
   fenêtre d'aperçu s'élargit pour le montrer sans le comprimer, et défile sinon. */
.modal.wide:has(.receipt-page){max-width:880px;}
.modal__body:has(> .receipt-page), #receiptPreviewBody{overflow-x:auto;}
.modal__head{padding:20px 24px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;}
.modal__head h3{font-size:17px;color:var(--navy);}
.modal__close{background:none;border:none;font-size:20px;color:var(--muted);}
.modal__body{padding:22px 24px;}
.modal__foot{padding:16px 24px;border-top:1px solid var(--border);display:flex;justify-content:flex-end;gap:10px;}
/* RAPPORT 198 -- rappel visible de l'orientation qui sera imprimée, juste à côté du bouton
   Imprimer (visibilité + retour d'information au point de la décision, pas en haut d'un
   aperçu qui défile). Calculé par :has() depuis le document déjà injecté dans
   #receiptPreviewBody -- jamais par script -- donc ne peut pas se désynchroniser de ce que
   la page imprimera réellement. Complète le durcissement CSS/JS ci-dessus : si un pilote
   d'impression impose malgré tout son réglage « Mise en page » mémorisé, l'utilisateur le
   voit avant de cliquer plutôt que de le découvrir sur le papier. */
.print-orientation-hint{display:none;margin-right:auto;align-self:center;font-size:12px;color:var(--muted);font-weight:600;}
#modalReceiptPreview:has(#receiptPreviewBody .receipt-page--paysage) .print-orientation-hint--paysage{display:inline;}
#modalReceiptPreview:has(#receiptPreviewBody .receipt-page:not(.receipt-page--paysage)) .print-orientation-hint--portrait{display:inline;}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;}
.note{font-size:12px;color:var(--muted);line-height:1.5;background:var(--cream);border-radius:8px;padding:10px 12px;margin-bottom:14px;}
/* Indication "(optionnel)" / "(requis pour…)" à l'intérieur d'un <label> -- même règle que
   .cand-hint dans admission/index.php, partagée depuis RAPPORT 83/84 (panneau de
   configuration Admissions, modal de rendez-vous) pour ne pas la redéfinir par portail. */
.cand-hint{text-transform:none;letter-spacing:0;font-weight:400;color:var(--muted);}
/* RAPPORT 173 -- l'intitulé d'un groupe de champs. Un formulaire long sans groupes se lit
   comme une liste de cases à remplir ; groupé, il se lit comme trois questions. */
.form-legend{
  font-size:11.5px;font-weight:700;color:var(--navy);text-transform:uppercase;letter-spacing:.06em;
  margin:18px 0 10px;padding-bottom:6px;border-bottom:1px solid var(--border);
}
.form-legend:first-child{margin-top:0;}
/* RAPPORT 173 -- garde-fou. `.note` porte un fond, une marge et un rembourrage : placée
   DANS un <label>, elle hérite en plus des majuscules et de l'interlettrage du label, et
   se dessine en bande grise par-dessus le libellé qu'elle devait éclairer (capture de
   production : « CAPACITÉ (PLACES) » recouvert par sa propre explication). La règle rend
   ce placement inoffensif au lieu de compter sur le fait que personne ne le refera :
   l'indication redevient une note en ligne, comme .cand-hint. */
.field label .note, label .note{
  display:inline;background:none;padding:0;margin:0;border-radius:0;
  text-transform:none;letter-spacing:0;font-weight:400;
}

/* ---------- Receipt (print) ---------- */
#receiptContainer{display:none;}
.receipt-page, .receipt-page::before, .doc-letterhead__crest, .receipt-page *{
  /* Chrome/Edge/Firefox hide background-colors and background-images on print by
     default unless the person manually checks "Print backgrounds" in the print
     dialog -- easy to miss, and silently drops the logo circle and the decorative
     side stripe (both background-based) while leaving borders/text untouched. This
     forces them to print regardless of that setting. */
  -webkit-print-color-adjust:exact;print-color-adjust:exact;
}
.receipt-page{
  /* RAPPORT 88/89 : papier à en-tête officiel (templateAttestation.docx / PDF), reproduit
     à la GÉOMÉTRIE du modèle, en points (1 pt = 1/72 po ; la page Lettre fait 612 × 792 pt)
     -- mêmes valeurs à l'écran (aperçu) et à l'impression : logo en haut à gauche,
     titre de l'établissement en rouge, filet marine sous l'en-tête jusqu'au bord droit,
     filets verticaux rouge (x = 47 pt) et marine (x = 95 pt), texte entre 72 et 540 pt,
     retrait de première ligne de 45 pt, filigrane dans la moitié basse, filet marine +
     coordonnées centrées sur la page en pied de page, sceau QR en bas à droite hors du
     bloc des coordonnées, mention de vérification sur une ligne centrée tout en bas. */
  --doc-font-title: Calibri, 'Carlito', 'Segoe UI', Arial, sans-serif;
  --doc-font-body: 'Times New Roman', Times, 'Liberation Serif', serif;
  --doc-font-footer: 'Baskerville Old Face', Baskerville, 'Libre Baskerville', Georgia, serif;
  --doc-title-color:#FF0000;   /* rouge du papier officiel (titre de l'établissement) */
  --doc-navy:#1F497D;          /* marine du papier officiel (filets) */
  width:612pt;max-width:none;min-height:792pt;margin:0 auto 40px;padding:137pt 72pt 96pt 72pt;background:#fff;border:1px solid var(--border);
  page-break-after:always;position:relative;box-sizing:border-box;display:flex;flex-direction:column;
  font-family:var(--doc-font-body);color:#111;font-size:12pt;line-height:20.7pt;
}
/* Filets verticaux du papier officiel : rouge à l'extrême gauche (toute la hauteur),
   marine juste à droite, du bas de l'en-tête au pied de page -- dessinés en pseudo-
   éléments pour ne jamais gêner le flux ni la pagination. (La lettre-courriel de la
   Messagerie, .receipt-page--letter, n'est pas sur ce papier.) */
.receipt-page:not(.receipt-page--letter)::before{
  content:'';position:absolute;top:30pt;bottom:42pt;left:35pt;width:1.2pt;background:var(--red);
}
.receipt-page:not(.receipt-page--letter)::after{
  content:'';position:absolute;top:30pt;bottom:42pt;left:49pt;width:1.2pt;background:var(--doc-navy);
}
.doc-watermark{
  position:absolute;top:42%;left:50%;transform:translate(-50%,-50%) rotate(-28deg);
  font-size:46px;font-weight:800;color:rgba(179,38,30,.13);text-transform:uppercase;
  letter-spacing:.04em;pointer-events:none;z-index:0;white-space:nowrap;font-family:var(--font-display);
}
/* Logo en filigrane (RAPPORT 91) : position, taille et opacité relevées dans le XML du
   modèle Word (word/footer1.xml -- ancrage relatif à la marge, extent en EMU, <a:alphaModFix
   amt="5000"/> = 5 % d'opacité exactement) plutôt qu'estimées à l'œil : x 196-433 pt,
   y 548-778 pt, 5 % d'opacité. */
.doc-watermark-logo{
  position:absolute;left:196pt;top:548pt;width:236pt;height:230pt;
  opacity:.05;pointer-events:none;z-index:0;mix-blend-mode:multiply;
}
.receipt-page > *:not(.doc-watermark):not(.doc-watermark-logo):not(.receipt-foot):not(.doc-letterhead){position:relative;z-index:1;}
.receipt-page > .receipt-foot{z-index:1;}
/* En-tête (positions du modèle) : logo x 58 pt / y 24 pt, titre de l'établissement x 162 pt
   / y 38 pt en Calibri gras rouge, filet marine à y 68 pt de x 62 pt au bord droit (575 pt). */
.doc-letterhead{position:absolute;top:0;left:0;right:0;height:95pt;margin:0;z-index:1;}
.doc-letterhead__crest{
  position:absolute;left:58pt;top:22pt;width:78pt;height:58pt;border-radius:0;background:transparent;color:var(--navy);
  display:flex;align-items:center;justify-content:center;font-family:var(--font-display);
  font-weight:700;font-size:14px;letter-spacing:.5px;overflow:hidden;
}
.doc-letterhead__crest img{width:100%;height:100%;object-fit:contain;object-position:left top;}
.doc-letterhead__text{position:absolute;left:162pt;top:40pt;right:37pt;}
.receipt-page .doc-letterhead h2{
  font-family:var(--doc-font-title);color:var(--doc-title-color);text-align:left;font-size:18pt;font-weight:700;
  letter-spacing:0;line-height:1.2;margin:0;padding:0;border:none;white-space:nowrap;
}
.doc-letterhead::after{content:'';position:absolute;left:141pt;right:37pt;top:68pt;height:1.2pt;background:var(--doc-navy);}
/* RAPPORT 262 -- logo d'un partenaire (ESGAE, Maîtrise en Finance) en haut à droite du papier officiel, au-dessus du filet ; le nom de l'établissement se resserre pour lui laisser la place. */
/* RAPPORT 264 -- même niveau et même hauteur que l'écusson UNAP (top 22pt, 58pt) : les deux logos
   se répondent, l'un à gauche, l'autre à droite ; le filet et le nom s'arrêtent avant lui. */
.doc-letterhead__partner{position:absolute;right:37pt;top:22pt;width:104pt;height:58pt;}
.doc-letterhead__partner img{width:100%;height:100%;object-fit:contain;object-position:right center;}
/* Avec le logo partenaire, le nom de l'établissement garde 300 pt (162 → 459 pt) : à 14 pt il tient
   sur une ligne ; s'il devait passer à deux, elles restent au-dessus du filet (top 36 pt, 68 pt). */
.doc-letterhead--partner .doc-letterhead__text{right:153pt;top:36pt;}
.receipt-page .doc-letterhead--partner h2{font-size:14pt;white-space:normal;line-height:1.1;}
.doc-letterhead--partner::after{right:153pt;}
.doc-letterhead .sub{display:none;}
/* Titre du document (« Attestation ») : Times gras 36 pt centré, à 140 pt du haut de la
   page -- puis une ligne de contexte discrète (nom, code, faculté...) pour les documents
   qui en ont une. */
.doc-title{font-family:var(--doc-font-body);font-size:36pt;line-height:42pt;font-weight:700;color:#111;text-align:center;margin:0 0 25pt;letter-spacing:0;}
.doc-context{font-family:var(--doc-font-body);font-size:10pt;line-height:14pt;color:#555;text-align:center;margin:-16pt 0 20pt;}
.doc-body{font-family:var(--doc-font-body);font-size:12pt;line-height:20.7pt;color:#111;}
.doc-body p, .receipt-page p{font-family:var(--doc-font-body);}
.doc-para{font-size:12pt;line-height:20.7pt;text-align:justify;text-indent:45pt;margin:0 0 20pt;}
.doc-para--noindent{text-indent:0;}
.doc-option{text-align:center;font-weight:700;font-style:italic;font-size:12pt;line-height:20.7pt;margin:0 0 16pt;}
.doc-place{font-size:12pt;line-height:20.7pt;margin:36pt 0 0 45pt;}
.receipt-page__rule{border:none;border-top:2px solid var(--navy);margin:10px 0 18px;}
.receipt-page h2{color:var(--navy);font-size:20px;text-align:center;}
.receipt-page .sub{text-align:center;color:var(--muted);font-size:12px;margin-top:4px;}
/* Bloc de signatures : signataire principal à DROITE (ligne + titre en gras), approbation
   « App. : » à GAUCHE en dessous -- exactement la disposition du papier officiel. */
/* Signatures (positions du modèle) : « Registraire » à droite -- filet de 108 pt dont le
   bord droit est à 51 pt du bord droit du texte, titre centré dessous ; « App.: » à gauche
   plus bas -- filet de 168 pt en retrait de 30 pt, puis SUR LA MÊME LIGNE « App.: » au bord
   gauche et le titre à 68 pt. */
.doc-signatures{margin-top:64pt;font-size:12pt;line-height:13.5pt;}
.doc-sig{display:flex;flex-direction:column;}
.doc-sig--right{align-items:flex-end;text-align:center;padding-right:51pt;}
.doc-sig--left{align-items:flex-start;text-align:left;margin-top:38pt;}
/* RAPPORT 203 -- « ATTESTATION SHOULD FIT IN ONE PAGE » : les 64pt/38pt ci-dessus viennent
   du papier officiel et restent inchangés pour les 3 AUTRES documents qui appellent
   documentSignatures() (certificat, diplôme, attestation d'inscription) -- aucun d'eux ne
   les a jamais fait déborder. Seule l'attestation bancaire porte un .doc-sig__seal-mid
   (imagesKey, une seule occurrence dans tout le fichier -- voir documentSignatures) : le
   sélecteur :has() cible donc CE bloc-là exclusivement, par une propriété structurelle
   plutôt qu'une classe ajoutée à la main qu'un futur appelant pourrait oublier de retirer.
   Resserré ici, pas retiré : garder un espace visible entre « Fait à ... » et la signature,
   et entre le sceau et « App.: », juste moins que la version pensée pour un document sans
   image. */
.doc-signatures:has(.doc-sig__seal-mid){margin-top:16pt;}
.doc-signatures:has(.doc-sig__seal-mid) .doc-sig--left{margin-top:12pt;}
.doc-sig--row{flex-direction:row;justify-content:space-between;gap:24pt;text-align:center;}
.doc-sig__line{display:inline-block;min-width:108pt;border-top:1pt solid #111;padding-top:2pt;font-weight:700;}
.doc-sig--row .doc-sig__line{min-width:150pt;}
.doc-sig__approval-rule{display:block;width:168pt;margin-left:30pt;border-top:1pt solid #111;height:0;}
.doc-sig__approval{display:flex;align-items:baseline;margin-top:2pt;font-weight:700;}
.doc-sig__approval-label{display:inline-block;width:68pt;flex-shrink:0;}
.doc-sig__approval b{white-space:nowrap;}
.doc-sig__name{font-weight:400;font-size:13px;color:#333;}
/* RAPPORT 199 -- signature manuscrite juste AU-DESSUS du filet de signature principal (à
   droite). Toujours en flux normal (jamais absolute, contrairement à .doc-seal__qr dans le
   pied de page) : la hauteur réservée (min-height) évite un saut de mise en page au moment
   où renderSignatureImages() remplit ce bloc de façon asynchrone -- même principe que le
   placeholder vide de #sealqr-{id} avant renderSealGraphics(). Vide (aucune image, ni
   téléversée ni par défaut) -- le bloc garde sa hauteur et ne casse rien.
   RAPPORT 200 -- déplacé légèrement vers le milieu de la page par un `transform` (jamais
   une `margin` : ça décalerait aussi le filet de signature juste en dessous, qui doit
   rester à sa place).
   RAPPORT 202 -- le sceau institutionnel (auparavant chevauché ici, sous la signature) a
   son propre emplacement désormais, voir .doc-sig__seal-mid plus bas : min-height réduit
   à la seule hauteur de la signature (34pt + marge), la signature n'a plus besoin d'être
   décalée pour se lover sous un sceau qui n'est plus dans ce bloc. */
.doc-sig__images{display:flex;align-items:flex-end;justify-content:flex-end;min-height:36pt;margin-bottom:2pt;transform:translateX(-14pt);}
.doc-sig__signature{height:34pt;width:auto;max-width:104pt;object-fit:contain;}
/* RAPPORT 202 -- retour explicite : le sceau institutionnel scelle les DEUX signatures, pas
   seulement la manuscrite -- posé au milieu du bloc .doc-signatures, ENTRE le signataire
   principal (à droite, au-dessus) et la ligne d'approbation « App.: » (à gauche, en
   dessous, quand elle est incluse -- voir opts.masquerApprobation), centré sur la largeur
   du document. Même min-height anti-saut-de-mise-en-page que .doc-sig__images.
   RAPPORT 203 -- « ATTESTATION SHOULD FIT IN ONE PAGE » : le sceau (48pt avant le point 200,
   agrandi à 60pt) est ramené à 50pt et ses marges resserrées (22pt → 11pt au total) --
   toujours nettement plus grand que l'original, mais ce point-ci et le suivant (marge de
   .doc-signatures) sont ce qui a fait déborder le document sur une deuxième page une fois
   mesuré (voir RAPPORT 203, Contexte) : rentrer sur UNE page prime ici sur la taille exacte
   choisie au point 200, aucune autre valeur du papier officiel (titre, pied de page,
   interligne du corps) n'est touchée. */
.doc-sig__seal-mid{text-align:center;min-height:50pt;margin:3pt 0 8pt;}
.doc-sig__sceau{height:50pt;width:auto;max-width:50pt;object-fit:contain;opacity:.9;}
/* RAPPORT 200 avait ici un encart séparé (.doc-projection-box) pour le total projeté.
   RAPPORT 201 -- retour explicite : le total projeté remplace directement le total
   affiché dans le .receipt-table normal ci-dessous, plus d'encart séparé à styler. */
.receipt-table{width:100%;margin:18px 0;border-collapse:collapse;}
.receipt-table td{padding:6px 4px;border-bottom:1px dashed var(--border);font-size:13.5px;}
/* RAPPORT 203 -- même resserrement que .doc-body--serre (plus bas) mais pour le tableau
   financier : seule l'attestation bancaire (seule à passer imagesKey, donc seule à pouvoir
   porter .doc-sig__seal-mid) est concernée -- voir le sélecteur :has() sur .doc-signatures
   pour la même logique de portée appliquée au bloc de signatures. */
.doc-body--serre .receipt-table{margin:8pt 0;}
.doc-body--serre .doc-para{margin-bottom:8pt;}
.doc-body--serre .doc-place{margin-top:16pt;}
.receipt-table td:first-child{color:var(--muted);width:45%;}
.receipt-total{display:flex;justify-content:space-between;font-family:var(--font-display);font-size:17px;
  font-weight:700;color:var(--navy);margin-top:14px;padding-top:14px;border-top:2px solid var(--navy);}
/* Pied de page du papier officiel (positions du modèle) : filet marine à 708 pt du haut,
   de x 95 pt (filet vertical marine) au bord droit (575 pt) ; coordonnées en Baskerville
   9 pt centrées sur la PAGE (x 306 pt) à partir de 713 pt ; sceau QR en bas à DROITE, hors
   du bloc des coordonnées (aligné sur le bord droit du filet, sur la hauteur des
   coordonnées) ; mention de vérification sur UNE ligne centrée tout en bas (y 770 pt). */
.receipt-foot{
  position:absolute;left:95pt;right:37pt;bottom:0;height:84pt;
  border-top:1.5pt solid var(--doc-navy);display:block;margin:0;padding:0;
}
.receipt-foot__text{position:absolute;left:-95pt;width:612pt;top:4pt;font-family:var(--doc-font-footer);font-size:9pt;line-height:10.3pt;color:#111;text-align:center;padding:0;}
.receipt-foot__text a{color:#0000ff;text-decoration:underline;}
.doc-foot-note{font-family:var(--doc-font-body);font-size:10pt;line-height:14pt;color:#555;margin:14pt 0 0;}
.doc-seal-mount{position:static;}
.doc-seal{position:static;}
.doc-seal__qr{position:absolute;right:0;top:5pt;width:46pt;height:46pt;}
.doc-seal__qr svg{width:100%;height:100%;}
.doc-seal__caption{position:absolute;left:-95pt;width:612pt;top:62pt;text-align:center;font-family:var(--doc-font-footer);font-size:6.5pt;line-height:8pt;color:#444;white-space:nowrap;}
.doc-seal__caption b{font-family:var(--font-mono);font-weight:600;letter-spacing:.03em;color:#222;}

/* ---------- Student ID card (CR80 ratio, ~85.6mm x 53.98mm) ---------- */
.id-card{
  width:340px;height:214px;margin:0 auto 40px;border-radius:14px;overflow:hidden;
  background:#fff;border:1px solid var(--border);box-shadow:0 10px 26px rgba(0,0,0,.12);
  display:flex;flex-direction:column;page-break-after:always;
}
.id-card__head{background:var(--navy);color:#fff;padding:10px 12px;display:flex;align-items:center;gap:10px;}
.id-card__crest{
  width:30px;height:30px;border-radius:50%;background:#fff;color:var(--navy);
  display:flex;align-items:center;justify-content:center;font-family:var(--font-display);
  font-weight:700;font-size:9px;flex-shrink:0;overflow:hidden;
}
/* RAPPORT 223 -- l'écusson réel (crest-unap.png) dans le rond, le texte « UNAP » ne restant
   qu'en repli si l'image ne charge pas ; et, pour une faculté de santé, le caducée à droite. */
.id-card__crest img{width:100%;height:100%;object-fit:contain;display:block;}
.id-card__head-text{min-width:0;flex:1;}
.id-card__badge-med{width:30px;height:30px;flex-shrink:0;margin-left:auto;border-radius:50%;background:#fff;padding:1px;}
.id-card__badge-med svg{width:100%;height:100%;display:block;}
.id-card__inst{font-size:9.5px;line-height:1.25;opacity:.9;}
.id-card__title{font-family:var(--font-display);font-weight:700;font-size:12.5px;letter-spacing:.03em;margin-top:1px;}
.id-card__body{flex:1;display:flex;gap:12px;padding:12px;}
.id-card__photo{width:76px;height:92px;border-radius:8px;overflow:hidden;background:var(--cream);border:1px solid var(--border);flex-shrink:0;}
.id-card__photo img{width:100%;height:100%;object-fit:cover;}
.id-card__photo-placeholder{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:30px;color:var(--muted);}
.id-card__info{flex:1;min-width:0;}
.id-card__name{font-family:var(--font-display);font-weight:700;font-size:13px;color:var(--navy);margin-bottom:6px;line-height:1.2;}
.id-card__row{display:flex;justify-content:space-between;font-size:10px;color:var(--muted);padding:2px 0;border-bottom:1px dotted var(--border);}
.id-card__row b{color:var(--ink);font-weight:600;}
.id-card__foot{background:var(--cream);color:var(--muted);font-size:8px;text-align:center;padding:5px 10px;border-top:2px solid var(--red);}
.id-card__name{overflow-wrap:anywhere;}

/* ---------- Portail Étudiant : « Ma Carte Étudiant » (RAPPORT 223) ----------
   Le bloc de sceau (.doc-seal) est conçu pour un document imprimé : QR et légende y sont
   positionnés en absolu, par rapport à la page. Affiché tel quel dans le portail, il
   s'ancrait sur l'application entière -- QR par-dessus l'en-tête, légende par-dessus le
   titre (capture du signalement). Ici, tout est remis dans le flux, sous la carte. */
.stu-carte{display:flex;flex-direction:column;align-items:center;gap:14px;}
.stu-carte .id-card{margin:0;}
.stu-carte-sceau .doc-seal{position:static;display:flex;align-items:center;gap:14px;padding:10px 12px;border:1px dashed var(--border);border-radius:10px;background:#fff;max-width:340px;}
.stu-carte-sceau .doc-seal__qr{position:static;width:84px;height:84px;flex-shrink:0;}
.stu-carte-sceau .doc-seal__caption{position:static;left:auto;top:auto;width:auto;white-space:normal;text-align:left;font-size:12px;line-height:1.45;color:var(--muted);font-family:var(--font-body,inherit);}
.stu-carte-sceau .doc-seal__caption b{font-size:12.5px;}
.stu-photo-cadre{width:150px;height:200px;border-radius:10px;border:2px dashed var(--border);background:var(--cream);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:12px;text-align:center;overflow:hidden;flex-shrink:0;}
.stu-photo-cadre img{width:100%;height:100%;object-fit:cover;display:block;}
.stu-photo-exigences{margin:8px 0 14px 18px;padding:0;font-size:13px;line-height:1.5;}
#stuCartePhotoVerdict:empty{display:none;}

/* ---------- Papier BRUT (.receipt-page--brut) ----------
   Une feuille blanche ordinaire : ni en-tête, ni filets, ni filigrane, ni coordonnées.

   Pourquoi ce mode existe. Tous les documents ci-dessus sont DÉLIVRÉS : ils sortent de
   l'université, portent son papier et engagent sa signature -- d'où les 137 pt réservés en
   haut pour le blason, les deux filets verticaux et le sceau de vérification. Un dossier de
   candidature n'est rien de tout cela : c'est une pièce de TRAVAIL INTERNE, lue en
   commission, annotée au stylo, classée dans une chemise. L'imprimer sur le papier officiel
   coûterait une feuille à en-tête par candidat(e), gaspillerait le tiers supérieur de chaque
   page, et surtout donnerait à un document de travail l'apparence d'un acte délivré.

   Le mode neutralise donc les décors et REND l'espace au contenu : marges de 54 pt sur les
   quatre côtés au lieu de 137/72/96/72. Le contenu peut couler sur plusieurs feuilles --
   c'est aussi pourquoi les décors doivent partir : ils sont en position absolue par rapport
   à la première page et ne se répéteraient pas sur les suivantes. */
.receipt-page--brut{
  padding:54pt 54pt 48pt 54pt;
  font-family:var(--font-body);font-size:10.5pt;line-height:1.45;color:#111;
  min-height:792pt;
}
/* Les filets verticaux et le filigrane sont des pseudo-éléments/images en position absolue :
   on les supprime plutôt que de les masquer, pour qu'ils ne réservent aucune place. */
.receipt-page--brut::before, .receipt-page--brut::after{content:none;display:none;}
.receipt-page--brut .doc-letterhead,
.receipt-page--brut .doc-watermark,
.receipt-page--brut .doc-watermark-logo,
.receipt-page--brut .receipt-foot{display:none;}
/* En-tête de travail : une seule ligne, le nom de l'établissement et le titre, séparés du
   corps par un filet fin. Elle sert à savoir de quoi il s'agit quand la feuille traîne sur
   un bureau -- pas à représenter l'institution. */
.doc-brut__head{display:flex;justify-content:space-between;align-items:baseline;gap:12pt;
  border-bottom:1pt solid #333;padding-bottom:5pt;margin-bottom:14pt;}
.doc-brut__head h1{font-family:var(--font-display);font-size:15pt;font-weight:700;margin:0;color:#111;letter-spacing:0;}
.doc-brut__head .doc-brut__org{font-size:9pt;color:#444;text-align:right;line-height:1.35;}
.doc-brut__foot{margin-top:auto;padding-top:6pt;border-top:.75pt solid #999;
  font-size:8.5pt;color:#555;display:flex;justify-content:space-between;gap:12pt;}
/* Sections du dossier. `break-inside:avoid` : un bloc « Contact » coupé en deux entre deux
   feuilles se relit mal et se classe encore plus mal. */
.doc-brut__sec{margin:0 0 12pt;break-inside:avoid;page-break-inside:avoid;}
.doc-brut__sec > h2{font-family:var(--font-display);font-size:10pt;font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;color:#111;margin:0 0 5pt;text-align:left;
  background:#eee;padding:3pt 6pt;border-left:3pt solid #333;}
/* Deux colonnes d'étiquettes/valeurs. `table-layout:fixed` : sans cela une valeur longue
   (une adresse) élargit sa colonne et désaligne toutes les autres lignes. */
.doc-brut__kv{width:100%;border-collapse:collapse;table-layout:fixed;}
.doc-brut__kv td{padding:2.5pt 6pt 2.5pt 0;vertical-align:top;font-size:10pt;border-bottom:.5pt dotted #ccc;}
.doc-brut__kv td.k{width:23%;color:#555;font-size:9pt;}
.doc-brut__kv td.v{width:27%;font-weight:600;}
/* Une valeur absente est marquée, jamais laissée vide : une case blanche ne dit pas si
   l'information manque ou si personne ne l'a encore cherchée. */
.doc-brut__vide{color:#999;font-weight:400;font-style:italic;}
.doc-brut__tab{width:100%;border-collapse:collapse;font-size:9.5pt;}
.doc-brut__tab th{text-align:left;font-size:8.5pt;text-transform:uppercase;letter-spacing:.04em;
  color:#444;border-bottom:1pt solid #333;padding:3pt 5pt;}
.doc-brut__tab td{padding:3pt 5pt;border-bottom:.5pt solid #ddd;}
.doc-brut__tab td.num{text-align:right;font-variant-numeric:tabular-nums;}
/* Case à cocher imprimée : le dossier se relit crayon en main, en commission. */
.doc-brut__case{display:inline-block;width:9pt;height:9pt;border:1pt solid #333;margin-right:5pt;vertical-align:-1pt;}
.doc-brut__case--ok{background:#333;}
.doc-brut__sig{display:flex;gap:24pt;margin-top:10pt;break-inside:avoid;}
/* L'espace d'écriture est AU-DESSUS du filet (on écrit SUR la ligne) et le libellé nomme,
   en dessous, ce qui vient d'y être écrit. L'inverse -- filet puis libellé puis vide --
   laisse la personne signer dans le blanc, sans ligne pour tenir l'écriture. */
.doc-brut__sig > div{flex:1;font-size:8.5pt;color:#444;}
.doc-brut__sig > div::before{content:'';display:block;height:42pt;border-bottom:.75pt solid #333;margin-bottom:4pt;}

/* ---------- Rapport exécutif du Recteur (RAPPORT 165) ----------
   Trois tableaux serrés sur UNE page à en-tête. La taille de police descend à 8 pt : ce
   n'est pas une lecture continue mais une lecture de colonnes, et tenir en une page est
   ici une exigence du document, pas une économie -- un rapport de direction qui déborde
   sur une deuxième feuille se lit sur la première seulement. */
.rec-page{font-size:9.5pt;line-height:1.35;}
.rec-page .rec-h2{font-family:var(--font-display);font-size:9.5pt;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:#1F497D;margin:12pt 0 4pt;text-align:left;}
.rec-tab{width:100%;border-collapse:collapse;font-size:8pt;font-variant-numeric:tabular-nums;}
.rec-tab th, .rec-tab td{padding:2.5pt 3pt;text-align:right;border-bottom:.5pt solid #ccc;white-space:nowrap;}
.rec-tab thead th{font-size:7pt;text-transform:uppercase;letter-spacing:.02em;color:#444;
  border-bottom:1pt solid #1F497D;font-weight:700;}
.rec-tab th:first-child, .rec-tab td:first-child{text-align:left;}
.rec-tab td.rec-f{font-weight:600;}
.rec-tab tfoot th{border-top:1pt solid #1F497D;border-bottom:none;font-weight:700;padding-top:3.5pt;}
.rec-tab .rec-du{color:#A31621;font-weight:700;}
.rec-inst{font-size:8.5pt;margin:8pt 0 0;padding:4pt 6pt;background:#f2f2f2;border-left:2.5pt solid #1F497D;}
/* Les réserves ne sont pas une note de bas de page décorative : c'est la partie du
   document qui empêche de lire les colonnes pour plus qu'elles ne disent. Elles restent
   donc dans le flux, encadrées, et jamais en corps plus petit que le reste. */
.rec-reserves{margin:10pt 0 0;padding:6pt 8pt;border:.75pt solid #8A5A00;background:#FCF9F1;font-size:8pt;}
.rec-reserves b{display:block;margin-bottom:3pt;text-transform:uppercase;letter-spacing:.04em;font-size:7.5pt;color:#8A5A00;}
.rec-reserves ul{margin:0;padding-left:12pt;}
.rec-reserves li{margin-bottom:2pt;}

/* Petit écran : le papier officiel garde sa géométrie (identique à l'impression) et est
   réduit en bloc plutôt que recomposé -- écran seulement, jamais à l'impression. */
@media screen and (max-width:900px){
  .receipt-page{zoom:.6;}
}
.receipt-page--paysage{max-width:1040px;}
/* RAPPORT 182 -- sur un rapport paysage, le titre est un titre de tableau, pas une une de lettre. */
.receipt-page--paysage .doc-title{font-size:16pt;line-height:20pt;margin:6px 0 2px;}
/* RAPPORT 183 -- les lettres de service (honoraires, salaire) portent un intitulé de
   direction, pas une une : 16 pt, demandé tel quel. */
.receipt-page--titre16 .doc-title{font-size:16pt;line-height:20pt;margin:0 0 4pt;}
.receipt-page--titre16 .doc-context{margin:0 0 10pt;}
/* RAPPORT 224 -- la lettre d'honoraires tient sur UNE page. Mesurée avant : 1 161 px de haut
   pour 1 056 px de papier (792 pt) -- le bloc de signature et le nom de la faculté passaient
   sous le pied de page, et l'impression « en PDF » rejetait le pied (QR, coordonnées) seul sur
   une seconde page. Le papier officiel (lettre réelle « Session I ») est en Times 12 pt sur un
   interligne simple, pas sur les 20,7 pt de l'attestation : c'est cet interligne qui est
   repris ici (18 pt), avec des marges de paragraphe de 6 pt et des tableaux au pas du texte.
   Rien n'est retiré du contenu ; la signature (manuscrite + sceau au milieu) garde la même
   taille que sur l'attestation bancaire (.doc-sig__seal-mid : même sélecteur :has()). */
.lettre-honoraires{line-height:18pt;}
.lettre-honoraires .lh-date{margin:0 0 6pt;text-align:right;}
.lettre-honoraires .lh-entete{margin:0 0 6pt;}
.lettre-honoraires .lh-entete td{padding:2pt 4pt;font-size:12pt;line-height:16pt;border-bottom:1px dashed var(--border);}
.lettre-honoraires .lh-entete td:first-child{color:#111;width:90px;font-weight:700;}
.lettre-honoraires .lh-corps p{margin:0 0 6pt;text-align:justify;font-size:12pt;line-height:18pt;}
.lettre-honoraires .lh-versements{width:60%;margin:3pt 0 6pt;}
.lettre-honoraires .lh-versements th{font-family:var(--doc-font-body);font-size:11pt;line-height:14pt;padding:2pt 6pt;text-align:left;border-bottom:1pt solid #111;background:transparent;color:#111;letter-spacing:0;text-transform:none;}
.lettre-honoraires .lh-versements td{padding:2pt 6pt;font-size:12pt;line-height:16pt;border-bottom:1px dashed var(--border);color:#111;width:auto;}
.lettre-honoraires .lh-versements td:first-child{width:110px;color:#111;}
.lettre-honoraires .lh-nb{margin:0 0 6pt;font-size:11pt;line-height:15pt;}
.lettre-honoraires .lh-salutations{margin:2pt 0 0;}
.lettre-honoraires .doc-signatures{margin-top:8pt;}
.lettre-honoraires .doc-signatures:has(.doc-sig__seal-mid){margin-top:8pt;}
.lettre-honoraires .doc-sig__seal-mid{margin:2pt 0 2pt;}
.lettre-honoraires .lh-faculte{margin:0;text-align:right;font-size:11pt;color:#333;line-height:14pt;}
/* RAPPORT 185 -- le rapport exécutif imprimé : chiffres clés en une ligne (pas les cartes de
   l'écran), deux graphiques côte à côte, tableaux en petit corps. */
.rapport-exec .doc-title{font-size:16pt;}
.rapport-exec__chiffres{width:100%;border-collapse:separate;border-spacing:6px 0;margin:2pt 0 8pt;}
.rapport-exec__chiffres td{border:1px solid #d9d7d1;border-radius:6px;padding:3pt 6pt;background:#fbfaf7;vertical-align:top;}
.rapport-exec__chiffres .lbl{font-size:8.5pt;text-transform:uppercase;letter-spacing:.04em;color:#52514e;}
.rapport-exec__chiffres .val{font-size:10.5pt;font-weight:700;color:#0b0b0b;font-family:var(--doc-font-body);white-space:nowrap;}
.rapport-exec__graphiques{display:flex;gap:18pt;align-items:flex-start;margin:0 0 6pt;}
.rapport-exec__graphiques > div{flex:1;min-width:0;}
.rapport-exec__graphiques h4{margin:0 0 2pt;font-size:10.5pt;}
.rapport-exec__graphiques svg{max-width:100%;height:auto;}
.rapport-exec__detail{font-size:9pt;}
.rapport-exec__detail th,.rapport-exec__detail td{padding:3pt 4pt;}
.rapport-exec__detail .btn,.rapport-exec__detail .icon-btn{display:none;}
.rapport-exec__detail{font-size:8.5pt;}
.rapport-exec__detail td,.rapport-exec__detail th{white-space:nowrap;padding:2pt 4pt;line-height:1.3;}
.rapport-exec__detail td:nth-child(4){white-space:normal;min-width:150pt;font-size:8pt;}
.rapport-exec__detail .status-pill,.rapport-exec__detail .role-pill{display:inline;padding:0;background:none !important;color:#0b0b0b !important;font-size:8.5pt;text-transform:none;letter-spacing:0;border:none;}
.rapport-exec__detail .status-pill::before{content:'• ';}
.rapport-exec .receipt-table th{font-size:8.5pt;}
.rapport-exec .receipt-table td.mono{white-space:nowrap;font-size:9pt;}
.rapport-exec .receipt-table td{padding:2pt 5pt;}
.rapport-exec__facultes{font-size:9pt;}
.rapport-exec__facultes th,.rapport-exec__facultes td{padding:2pt 5pt;line-height:1.25;}
@media print{ .rapport-exec{page-break-after:always;} .rapport-exec:last-child{page-break-after:auto;} }
/* RAPPORT 186 -- les rapports PAYSAGE ne sont pas sur le papier officiel : ni filets
   verticaux dans la marge (rouge / marine), ni filet marine au-dessus du pied de page ; les
   coordonnées restent, centrées sur la largeur de la page paysage (792 pt), pas sur les
   612 pt du portrait. Les chiffres clés passent à la ligne par devise. */
.receipt-page.receipt-page--paysage::before,.receipt-page.receipt-page--paysage::after{content:none;display:none;}
.receipt-page--paysage .receipt-foot{border-top:none;left:40pt;right:40pt;height:64pt;}
.receipt-page--paysage .receipt-foot__text{left:0;width:auto;right:0;top:6pt;color:#52514e;}
.rapport-exec__chiffres .val{white-space:normal;line-height:1.3;}
.rapport-exec__note{font-weight:400;color:#52514e;font-size:9pt;}
.rapport-exec__lecture{font-size:8.5pt;line-height:1.35;color:#52514e;margin:4pt 0 0;font-family:var(--doc-font-body);}
/* Le logo en filigrane est placé pour la page portrait (y 548-778 pt) : sur une page
   paysage de 612 pt il déborderait du papier -- centré, même opacité. */
.receipt-page--paysage .doc-watermark-logo{top:50%;left:50%;transform:translate(-50%,-50%);margin:0;}
.receipt-page--paysage .doc-foot-note{margin-top:auto;padding-top:8pt;}
/* RAPPORT 193 -- dossier budgétaire : tables serrées, une ligne par rubrique. */
.dossier-budget .receipt-table th,.dossier-budget .receipt-table td{white-space:nowrap;padding:1.5pt 5pt;font-size:8.5pt;line-height:1.25;}
.dossier-budget .receipt-table td:first-child,.dossier-budget .receipt-table th:first-child{width:52pt;}
.dossier-budget .rapport-exec__lecture ul{margin:2pt 0 0;padding-left:14pt;font-size:8.5pt;}
.dossier-budget .rapport-exec__graphiques{margin:0 0 2pt;}
.dossier-budget .rapport-exec__chiffres{margin:0 0 4pt;}
.dossier-budget .rapport-exec__chiffres .val{font-size:9.5pt;}
.dossier-budget .rapport-exec__chiffres .lbl{font-size:7.5pt;white-space:nowrap;}
.dossier-budget .rapport-exec__graphiques h4{font-size:9pt;}
.dossier-budget .rapport-exec__lecture{margin:2pt 0 0;}
/* RAPPORT 194 -- le budget annuel (portrait, papier officiel) dans la forme du modèle. */
.budget-annuel__section{font-family:var(--doc-font-body);font-size:12.5pt;font-weight:700;color:#111;margin:7pt 0 3pt;text-align:left;}
.budget-annuel__entete td{font-size:10pt;padding:1.5pt 4pt;}
.budget-annuel .receipt-table th,.budget-annuel .receipt-table td{font-size:9.5pt;padding:2.5pt 5pt;line-height:1.3;}
.budget-annuel__notes{font-family:var(--doc-font-body);font-size:9.5pt;line-height:13pt;color:#111;}
.budget-annuel .doc-title{margin-bottom:2pt;}
/* RAPPORT 196 -- simulation : une ligne vide (effectif ou montant à zéro) est teintée. */
#simTableBody tr.sim-vide{background:var(--warn-bg);}
.viz-pastille{display:inline-block;width:8pt;height:8pt;border-radius:2pt;margin-right:4pt;vertical-align:-1pt;}
.receipt-page--paysage .doc-context{margin:0 0 8px;}
@media print{
  /* RAPPORT 198 -- dimensions explicites en points plutôt que le mot-clé « letter » : un
     format nommé fait dépendre le résultat de la table de correspondance nom→dimensions du
     pilote d'impression, alors que des points sont sans ambiguïté. Même raisonnement pour
     la règle @page paysage ci-dessous et pour imprimerAvecOrientation() (shared.js). */
  @page{size:612pt 792pt;margin:0;}
  body *{visibility:hidden;}
  #receiptContainer, #receiptContainer *{visibility:visible;}
  /* RAPPORT 88 : les autres blocs de la page (application, modals) restaient dans le flux
     d'impression même invisibles -- d'où des pages blanches après le document. Retirés du
     flux : #receiptContainer est un enfant direct de <body> dans les 4 portails. */
  body > *:not(#receiptContainer){display:none !important;}
  #receiptContainer{display:block !important;position:static;width:100%;}
  /* Une page Lettre par document : largeur utile pleine, hauteur minimale de la page
     (le pied de page reste en bas grâce au flex de .receipt-page). */
  /* Page Lettre entière (612 × 792 pt, marges @page à 0) : la géométrie en points du papier
     officiel s'applique telle quelle -- l'aperçu écran et l'impression sont identiques. */
  /* RAPPORT 194 -- 790 pt et non 792 : même arrondi qu'en paysage (point 193), un pied de
     page rejeté sur une feuille vide dès que le contenu remplit la page. */
  .receipt-page{border:none;box-shadow:none;max-width:none;width:612pt;min-height:790pt;margin:0;padding:137pt 72pt 96pt 72pt;}
  /* Doit venir APRÈS la règle ci-dessus, qui réserve les 137 pt du blason : sans cela le
     papier brut s'imprimerait avec le tiers supérieur vide qu'il existe justement pour
     récupérer. Marges de feuille ordinaire sur les quatre côtés. */
  .receipt-page--brut{padding:54pt 54pt 48pt 54pt;}
  /* RAPPORT 178 -- les rapports à tableaux larges (masse salariale, suivi des versements,
     rapport individuel) s'impriment en PAYSAGE : page nommée, Lettre 792 × 612 pt, marges
     de feuille ordinaire (le blason n'a pas de place réservée sur un rapport). */
  /* RAPPORT 186 -- 76 pt en bas : la place du pied de page (coordonnées), pour que la
     mention du document ne s'imprime plus par-dessus. */
  /* RAPPORT 193 -- 610 pt et non 612 : à hauteur EXACTE de la feuille, l'arrondi du moteur
     d'impression rejetait le pied de page sur une feuille suivante, vide. */
  .receipt-page--paysage{page:paysage;width:792pt;min-height:610pt;padding:100pt 40pt 76pt 40pt;}
  @page paysage{size:792pt 612pt;margin:0;}
  .receipt-page:last-child{page-break-after:auto;}
  .id-card{border:none;box-shadow:none;}
}

/* ---------- Email queue ---------- */
.email-queue-item{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--border);}
.email-queue-item .info{flex:1;font-size:13px;}
.email-queue-item .info b{display:block;}
.email-queue-item .info span{color:var(--muted);font-size:12px;}

/* ---- Éditeur de texte enrichi (RAPPORT 88) ----
   Posé par-dessus un textarea (attachRichEditor) : barre d'outils façon traitement de
   texte + zone contenteditable avec le correcteur du navigateur (lang fr/en/es). */
.rte{border:1.5px solid var(--border);border-radius:8px;background:#fff;overflow:hidden;}
.rte:focus-within{border-color:var(--navy);}
.rte__toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 5px;background:var(--cream);border-bottom:1px solid var(--border);}
.rte__toolbar button{border:1px solid transparent;background:transparent;color:var(--ink);border-radius:6px;min-width:26px;height:28px;padding:0 5px;font-size:12.5px;line-height:1;white-space:nowrap;}
.rte__toolbar button:hover{background:#fff;border-color:var(--border);}
.rte__toolbar button:active{background:var(--border);}
.rte__toolbar button:focus-visible{outline:2px solid var(--navy);outline-offset:1px;}
.rte__sep{width:1px;height:20px;background:var(--border);margin:0 3px;}
.rte .rte__lang{width:auto;height:28px;padding:0 6px;border:1px solid var(--border);border-radius:6px;background:#fff;font-size:12px;color:var(--ink);} /* .field select (100%) ne s'applique pas ici */
.rte__area{min-height:140px;max-height:60vh;overflow:auto;padding:11px 13px;font-size:14px;line-height:1.55;color:var(--ink);outline:none;white-space:pre-wrap;word-break:break-word;}
.rte__area:empty::before{content:attr(data-placeholder);color:var(--muted);pointer-events:none;}
.rte__area h1,.rte__area h2,.rte__area h3,.rte__area h4{font-family:var(--font-body);font-weight:700;margin:8px 0 4px;color:var(--ink);}
.rte__area h2{font-size:18px;} .rte__area h3{font-size:15.5px;} .rte__area h4{font-size:14px;}
.rte__area p{margin:0 0 6px;} .rte__area ul,.rte__area ol{margin:4px 0 8px;padding-left:24px;}
.rte__area a{color:var(--navy);text-decoration:underline;} .rte__area blockquote{margin:6px 0;padding:2px 12px;border-left:3px solid var(--border);color:var(--muted);}
.rte--compact .rte__area{min-height:90px;}

/* ============================================================
   Responsive — tablet and phone. Two breakpoints: general tablet/
   narrow-desktop adjustments at 900px, and a tighter phone pass at
   600px (stacked filters, full-width modals, larger touch targets).
   ============================================================ */
@media (max-width:900px){
  .layout{grid-template-columns:1fr;}
  .sidebar{display:flex;overflow-x:auto;border-right:none;border-bottom:1px solid var(--border);padding:10px 8px;}
  .nav-item{white-space:nowrap;margin-bottom:0;}
  .nav-group, .nav-group__items{display:contents;} /* dissolve the group wrapper so its nav-items become direct flex children of .sidebar */
  .nav-group__header{display:none;} /* grouping/collapsing only makes sense in the vertical desktop sidebar */
  .nav-group__items .nav-item{padding-left:12px;}
  .grid2{grid-template-columns:1fr;}
  .grid3{grid-template-columns:1fr;}
  .main{padding:18px 16px 50px;}
  .stat-grid{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));}
}

@media (max-width:600px){
  body{font-size:14px;}
  .topbar{padding:0 12px;height:54px;}
  .topbar__brand h1{font-size:13px;}
  .topbar__brand .crest{width:28px;height:28px;font-size:9px;}
  .topbar__user{gap:8px;font-size:12px;}
  .topbar__user button{padding:6px 9px;font-size:11.5px;}
  .role-pill{display:none;} /* saves space on very narrow screens; role still shown via username context */

  .login-card__inner{padding:28px 22px 24px;}
  .login-card h1{font-size:19px;}

  .view-header{flex-direction:column;align-items:stretch;gap:10px;}
  .view-header h2{font-size:20px;}
  .view-header > button, .view-header > a{width:100%;justify-content:center;}

  /* Filter bars: one field per row instead of cramped multi-column wrapping */
  .filter-bar{flex-direction:column;align-items:stretch;}
  .filter-bar .field, .filter-bar .field.grow{min-width:0;width:100%;}

  .stat-grid{grid-template-columns:repeat(2,1fr);gap:10px;}
  .stat-card{padding:12px 14px;}
  .stat-card .val{font-size:20px;}

  table{font-size:12px;}
  th,td{padding:7px 6px;}

  /* iOS Safari auto-zooms the page when a focused input is under 16px -- keep form
     fields at 16px here even though body text itself is smaller. */
  .field input, .field select, .field textarea{font-size:16px;}

  /* Touch targets: 32px icon buttons are below the ~44px comfortable minimum */
  .icon-btn{width:38px;height:38px;font-size:15px;}
  .action-icons{gap:8px;}
  .btn{padding:11px 16px;}
  .btn-sm{padding:9px 12px;}

  /* Modals: near full-width, no side gutters wasted, body scrolls internally */
  .overlay{padding:0;align-items:flex-end;}
  .modal, .modal.wide{max-width:100%;width:100%;border-radius:16px 16px 0 0;max-height:92vh;}
  .modal__body{padding:16px 18px;}
  .modal__head, .modal__foot{padding:14px 18px;}
  .modal__foot{flex-wrap:wrap;}
  .modal__foot .btn{flex:1;min-width:120px;}

  .pay-split{grid-template-columns:1fr;}
  .pay-split__list{max-height:280px;}

  /* Petit écran : l'aperçu garde le papier à en-tête mais resserre les marges ; les filets
     verticaux et le logo se rapprochent du bord. */

  .landing-cards{grid-template-columns:1fr;}
  .landing-title{font-size:22px;}

  /* Dashboard action buttons (Dashboard sidebar-style quick actions) stack cleanly */
  div[style*="display:flex"][style*="gap:10px"][style*="flex-wrap:wrap"] .btn{flex:1;min-width:140px;}
}

/* RAPPORT 119 -- indicateur d'attente sans texte (les portails n'affichent plus « Connexion en cours… »
   ni aucun nom pendant la remise de session depuis la page d'accueil). */
.quiet-spinner{display:inline-block;width:18px;height:18px;border-radius:50%;border:2px solid var(--border);border-top-color:var(--navy);animation:quietspin .7s linear infinite;vertical-align:middle;}
@keyframes quietspin{to{transform:rotate(360deg);}}

/* RAPPORT 234 -- tableau de suivi des candidatures (Portail Personnel -> Admissions) */
.adm-funnel{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-top:12px;}
.adm-stage{border:1px solid var(--border);border-radius:10px;padding:10px 12px;background:var(--cream,#f7f7f9);cursor:pointer;text-align:left;font:inherit;color:inherit;position:relative;}
.adm-stage:hover,.adm-stage.active{border-color:var(--navy);box-shadow:0 0 0 3px rgba(31,56,100,.08);}
.adm-stage__n{font-size:22px;font-weight:700;color:var(--navy);line-height:1.1;}
.adm-stage__l{font-size:11.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;font-weight:600;margin-top:2px;}
.adm-stage__s{font-size:11.5px;color:var(--muted);margin-top:4px;}
.adm-queues{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;margin-top:14px;}
.adm-queue h4{margin:0 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);display:flex;align-items:center;gap:6px;}
.adm-queue ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;}
.adm-queue li button{width:100%;display:flex;justify-content:space-between;align-items:center;gap:8px;border:1px solid var(--border);border-radius:8px;background:#fff;padding:7px 10px;font:inherit;font-size:12.5px;color:var(--ink,#222);cursor:pointer;text-align:left;}
.adm-queue li button:hover,.adm-queue li button.active{border-color:var(--navy);background:var(--cream,#f7f7f9);}
.adm-queue li button.zero{color:var(--muted);}
.adm-queue li button b{font-variant-numeric:tabular-nums;min-width:26px;text-align:center;border-radius:999px;padding:1px 8px;background:var(--cream,#f3f4f6);color:var(--navy);}
.adm-queue li button.alert b{background:#8A5A00;color:#fff;}
.adm-queue li button.danger b{background:var(--red,#A31621);color:#fff;}
.adm-queue li button.zero b{background:transparent;color:var(--muted);}

/* RAPPORT 239 -- Paramètres → État du système. Un constat par ligne : un niveau, une valeur,
   et la commande exacte qui répare. Les quatre niveaux ont chacun leur teinte parce qu'un
   rapport qui rend tout de la même couleur oblige à le lire en entier pour savoir s'il y a
   quelque chose à faire -- ce qui revient à ne pas le lire. `inconnu` est GRIS, pas rouge :
   « je n'ai pas les moyens de répondre ici » n'est pas un défaut. */
.sante-pill{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:3px 9px;border-radius:999px;display:inline-block;white-space:nowrap;}
.sante-pill--ok{background:var(--success-bg);color:var(--success);}
.sante-pill--attention{background:var(--warn-bg);color:var(--warn);}
.sante-pill--grave{background:var(--danger-bg);color:var(--danger);}
.sante-pill--inconnu{background:#ECEAE4;color:var(--muted);}
.sante-verdict{border-left:4px solid var(--border);padding:12px 14px;border-radius:8px;margin:0 0 14px;font-size:14px;line-height:1.55;}
.sante-verdict--ok{border-left-color:var(--success);background:var(--success-bg);}
.sante-verdict--attention{border-left-color:var(--warn);background:var(--warn-bg);}
.sante-verdict--grave{border-left-color:var(--danger);background:var(--danger-bg);}
.sante-detail{color:var(--muted);font-size:12.5px;margin-top:5px;line-height:1.5;}
.sante-action{display:block;margin-top:7px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;background:#F5F3EE;border:1px solid var(--border);border-radius:6px;padding:6px 9px;word-break:break-word;}
.sante-action::before{content:"À faire : ";font-family:inherit;color:var(--muted);}

/* 22 octobre 2026 -- Paiement : parcours en trois étapes (Norman) */
.pay-step__title{font-family:var(--font-display);font-weight:700;font-size:15px;color:var(--navy);display:flex;align-items:center;gap:8px;margin-bottom:10px;}
.pay-step__num{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--navy);color:#fff;font-size:13px;font-weight:700;}
.pay-row{cursor:pointer;}
.pay-row:hover td{background:var(--cream);}
.pay-row--active td{background:var(--danger-bg) !important;}
.pay-row--active td:first-child{box-shadow:inset 3px 0 0 var(--red);}
