/* =========================================================================
   alterForge — Système de design (V4 — migration design system complète)
   --------------------------------------------------------------------------
   NOTE SUR LES VERSIONS (pour éviter toute confusion) :
   - Ce "V4" est la version ÉDITORIALE de la charte graphique (rare, humaine).
     V3 = sémantique couleur ; V4 = refonte design system (sidebar, composants af-*).
   - Le numéro qui s'incrémente à CHAQUE modif CSS/JS est ASSET_VERSION (lib/db.php),
     purement technique : il force le navigateur à recharger (cache-buster). Sans
     rapport avec ce commentaire. Les deux numéros sont indépendants, c'est normal.
   --------------------------------------------------------------------------
   - Tokens en custom properties dans :root
   - Convention BEM-light, préfixe `.af-`
   - Zéro dépendance, zéro inline style, JS séparé (voir app.js)
   - Couleurs sémantiques strictes :
       brand   (bordeaux)  → marque / nav / logo. JAMAIS sur une action.
       action  (teal)      → tous les boutons qui FONT quelque chose.
       info    (bleu)      → labels purement informatifs.
       danger  (rouge)     → suppression / destruction (discret).
       success (vert)      → présent, confirmé.
       warn    (ambre)     → retard, alerte légère.
   --------------------------------------------------------------------------
   ORGANISATION :
   1. Tokens (:root) et base
   2. Layout admin (sidebar, topbar) + composants du designer
   3. Compléments de migration alterForge (à partir de "MIGRATION alterForge")
      regroupés par page/usage.
   ========================================================================= */

/* -------------------------------------------------------------------------
   Nettoyage v153 — fichier réorganisé sans modifier l'intention visuelle.
   - doublons exacts supprimés ;
   - déclaration interne répétée supprimée ;
   - alias --af-border ajouté pour les anciens patchs encore utilisés ;
   - les surcharges intentionnelles de fin de fichier sont conservées.
   ------------------------------------------------------------------------- */

/* ---------- 1. Reset minimal -------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
button { font: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
input, select, textarea { font: inherit; color: inherit; }
img, svg { display: block; max-width: 100%; }
[hidden] { display: none !important; }

/* ---------- 2. Design tokens -------------------------------------------- */
:root {
  /* Fonds neutres (papier chaud — pas de sens sémantique) */
  --af-bg:            #F6F3EE;
  --af-surface:       #FFFFFF;
  --af-surface-soft:  #FBF9F5;
  --af-surface-mute:  #F4F0E8;

  /* Encres */
  --af-ink:           #1A1816;
  --af-ink-2:         #4A4641;
  --af-ink-3:         #807A72;
  --af-on-color:      #FFFFFF;

  /* Lignes */
  --af-line:          #E7E2DA;
  --af-line-2:        #EFEBE3;
  --af-border:        var(--af-line); /* compatibilité anciens patchs */

  /* —— Couleurs sémantiques —————————————————————————————— */
  /* Brand — bordeaux (identité, nav, logo) */
  --af-brand:         #9B2C2C;
  --af-brand-ink:     #7A2222;
  --af-brand-soft:    #F4E6E6;

  /* Action — teal (boutons, CTA, "gérer", "créer"...) */
  --af-action:        #0D9488;
  --af-action-hover:  #0B7C72;
  --af-action-soft:   #E6F5F3;

  /* Information — bleu froid (codes, labels neutres) */
  --af-info:          #1E6091;
  --af-info-ink:      #154A70;
  --af-info-soft:     #E8F0F6;

  /* Danger — rouge (suppression) */
  --af-danger:        #C0392B;
  --af-danger-ink:    #9A2C21;
  --af-danger-soft:   #FDECEC;

  /* Succès — vert (présent, confirmé) */
  --af-success:       #2D6A4F;
  --af-success-ink:   #1F4D38;
  --af-success-soft:  #EEF6ED;

  /* Avertissement — ambre */
  --af-warn:          #B8860B;
  --af-warn-ink:      #8C6608;
  --af-warn-soft:     #FBF3E0;

  /* Neutre (statut fermé, badge gris) */
  --af-neutral-soft:  #EEEAE3;
  --af-neutral-ink:   #6C645A;

  /* Typographie */
  --af-font-sans:   'Geist', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --af-font-serif:  'Newsreader', 'Source Serif Pro', Georgia, serif;
  --af-font-mono:   'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Rayons */
  --af-r-sm: 6px;
  --af-r-md: 8px;
  --af-r-lg: 10px;
  --af-r-xl: 14px;
  --af-r-pill: 999px;

  /* Élévations */
  --af-shadow-sm:  0 1px 0 rgba(0, 0, 0, 0.04);
  --af-shadow-cta: 0 1px 0 rgba(0, 0, 0, 0.04), 0 6px 16px -8px rgba(13, 148, 136, 0.55);
  --af-shadow-pop: 0 10px 28px -10px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.06);

  /* Mesures */
  --af-side-w: 240px;
  --af-content-max: 1240px;
}

/* ---------- 3. Page shell ----------------------------------------------- */
body {
  background: var(--af-bg);
  color: var(--af-ink);
  font-family: var(--af-font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.af-app {
  display: grid;
  grid-template-columns: var(--af-side-w) 1fr;
  min-height: 100vh;
}

/* ---------- 4. Sidebar -------------------------------------------------- */
.af-side {
  background: var(--af-surface);
  border-right: 1px solid var(--af-line);
  padding: 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.af-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 14px;
  border-bottom: 1px solid var(--af-line-2);
}
.af-brand__mark { color: var(--af-brand); display: flex; }
.af-brand__word {
  font-family: var(--af-font-serif);
  font-size: 20px;
  letter-spacing: -0.2px;
  color: var(--af-ink);
}
.af-brand__word b { font-weight: 600; }

.af-side__label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--af-ink-3);
  padding: 14px 10px 6px;
}
.af-nav { display: flex; flex-direction: column; gap: 2px; }
.af-nav__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--af-r-md);
  color: var(--af-ink-2);
  font-size: 13.5px;
  font-weight: 500;
}
.af-nav__item:hover { background: var(--af-bg); color: var(--af-ink); }
.af-nav__item--active {
  background: var(--af-brand-soft);
  color: var(--af-brand-ink);
}
.af-nav__item--active::after {
  content: '';
  position: absolute;
  right: 8px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--af-brand);
  transform: translateY(-50%);
}

/* ---------- 5. Top bar -------------------------------------------------- */
.af-col { display: flex; flex-direction: column; min-width: 0; }
.af-top {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 28px;
  background: var(--af-surface);
  border-bottom: 1px solid var(--af-line);
}
.af-search {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 1 420px;
  padding: 8px 12px;
  background: var(--af-bg);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  color: var(--af-ink-3);
}
.af-search input {
  border: 0;
  outline: 0;
  background: transparent;
  flex: 1;
  font-size: 13.5px;
  color: var(--af-ink);
}
.af-kbd {
  font-family: var(--af-font-mono);
  font-size: 11px;
  padding: 2px 6px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: 5px;
  color: var(--af-ink-3);
}
.af-top__right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}
.af-lang {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  color: var(--af-ink-2);
  font-size: 12.5px;
  font-weight: 500;
}
.af-user {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 12px 4px 4px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-pill);
}
.af-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--af-brand);
  color: var(--af-on-color);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
}
.af-user__name { display: flex; flex-direction: column; line-height: 1.15; }
.af-user__name strong { font-size: 13px; font-weight: 500; color: var(--af-ink); }
.af-user__name span  { font-size: 11px; color: var(--af-ink-3); }

/* ---------- 6. Layout main --------------------------------------------- */
.af-main { padding: 28px 40px 48px; max-width: var(--af-content-max); width: 100%; }
.af-titlebar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}
.af-titlebar__text { min-width: 0; flex: 1; }
.af-meta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.af-h1 {
  font-family: var(--af-font-serif);
  font-size: 34px;
  font-weight: 500;
  margin: 0;
  letter-spacing: -0.4px;
  color: var(--af-ink);
}
.af-h2 {
  font-family: var(--af-font-serif);
  font-size: 24px;
  font-weight: 500;
  margin: 0 0 8px;
  letter-spacing: -0.3px;
  color: var(--af-ink);
}
.af-sub {
  margin: 6px 0 0;
  color: var(--af-ink-3);
  font-size: 13.5px;
  max-width: 560px;
}
.af-crumbs {
  font-size: 12.5px;
  color: var(--af-ink-3);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.af-crumbs a:hover { color: var(--af-ink); text-decoration: underline; }
.af-crumbs__sep { color: var(--af-ink-3); opacity: 0.5; }

/* ---------- 7. Buttons (système complet) ------------------------------- */
.af-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  border: 1px solid transparent;
  border-radius: var(--af-r-md);
  font-size: 13.5px;
  font-weight: 500;
  background: transparent;
  color: var(--af-ink);
  line-height: 1.2;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.af-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.af-btn-primary {
  background: var(--af-action);
  color: var(--af-on-color);
  padding: 10px 16px;
  border-radius: var(--af-r-lg);
  font-size: 14px;
  font-weight: 500;
  border: 0;
  box-shadow: var(--af-shadow-cta);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.af-btn-primary:hover { background: var(--af-action-hover); }

.af-btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  background: var(--af-action-soft);
  color: var(--af-action-hover);
  border: 1px solid transparent;
  border-radius: var(--af-r-md);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.af-btn-secondary:hover {
  background: var(--af-action);
  color: var(--af-on-color);
}

.af-btn-ghost {
  padding: 7px 12px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  color: var(--af-ink-2);
  font-size: 13px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.af-btn-ghost:hover { color: var(--af-ink); border-color: var(--af-ink-3); }

.af-btn-danger {
  background: var(--af-danger-soft);
  color: var(--af-danger);
  border: 1px solid transparent;
  padding: 7px 12px;
  border-radius: var(--af-r-md);
  font-size: 13px;
  font-weight: 500;
}
.af-btn-danger:hover { background: var(--af-danger); color: var(--af-on-color); }

/* Icon-only button (32×32, neutre par défaut) */
.af-icon-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  color: var(--af-ink-3);
  cursor: pointer;
}
.af-icon-btn:hover { color: var(--af-ink); border-color: var(--af-ink-3); }
.af-icon-btn--ghost { background: transparent; border-color: transparent; }
.af-icon-btn--ghost:hover { background: var(--af-bg); }
.af-icon-btn--danger { color: var(--af-danger); }
.af-icon-btn--danger:hover { background: var(--af-danger-soft); border-color: var(--af-danger-soft); color: var(--af-danger-ink); }

/* ---------- 8. Stat strip ---------------------------------------------- */
.af-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
.af-stat {
  padding: 16px 18px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: 12px;
}
.af-stat__k { font-family: var(--af-font-serif); font-size: 28px; font-weight: 500; line-height: 1; color: var(--af-ink); }
.af-stat__l { font-size: 12.5px; font-weight: 500; color: var(--af-ink-2); margin-top: 8px; }
.af-stat__s { font-size: 11.5px; color: var(--af-ink-3); margin-top: 2px; }

/* ---------- 9. Tabs ---------------------------------------------------- */
/* 9a. Filter tabs (segmented pill — pour filtrer une liste) */
.af-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  margin-bottom: 14px;
}
.af-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 7px;
  border: 0;
  background: transparent;
  color: var(--af-ink-2);
  font-size: 13px;
  font-weight: 500;
}
.af-tab:hover { color: var(--af-ink); }
.af-tab--active { background: var(--af-ink); color: var(--af-on-color); }
.af-tab__count {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: var(--af-r-pill);
  background: rgba(0, 0, 0, 0.06);
}
.af-tab--active .af-tab__count { background: rgba(255, 255, 255, 0.18); color: inherit; }
.af-tools { margin-left: auto; display: flex; gap: 8px; }

/* 9b. Page tabs (underline — pour naviguer dans une page de détail) */
.af-tabs-page {
  display: flex;
  align-items: center;
  gap: 4px;
  border-bottom: 1px solid var(--af-line);
  margin-bottom: 22px;
}
.af-tab-page {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  border: 0;
  background: transparent;
  color: var(--af-ink-3);
  font-size: 14px;
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.af-tab-page:hover { color: var(--af-ink-2); }
.af-tab-page--active {
  color: var(--af-ink);
  border-bottom-color: var(--af-ink);
}
.af-tab-page__count {
  font-size: 11px;
  padding: 1px 7px;
  border-radius: var(--af-r-pill);
  background: var(--af-surface-mute);
  color: var(--af-ink-2);
}

/* ---------- 10. Table -------------------------------------------------- */
.af-table {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  overflow: hidden;
}
.af-row {
  display: grid;
  grid-template-columns: 130px 1.4fr 150px 120px 90px 120px 110px;
  align-items: center;
  padding: 14px 18px;
  gap: 14px;
  font-size: 14px;
}
.af-row + .af-row { border-top: 1px solid var(--af-line-2); }
.af-row--head {
  padding: 11px 18px;
  background: var(--af-surface-soft);
  font-size: 11.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--af-ink-3);
}
.af-row__name { font-weight: 500; color: var(--af-ink); }
.af-row__teams { color: var(--af-ink-2); display: inline-flex; align-items: center; gap: 6px; }
.af-row__updated { color: var(--af-ink-3); font-size: 13px; }
.af-row__actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }

/* Variantes de grille pour autres tables */
.af-row--students {
  grid-template-columns: 40px minmax(160px, 1.4fr) minmax(180px, 1fr) minmax(105px, .7fr) minmax(90px, .65fr) 72px 120px;
}

/* ---------- 11. Code / theme / pills ----------------------------------- */
.af-code {
  font-family: var(--af-font-mono);
  font-size: 12.5px;
  color: var(--af-ink);
  background: var(--af-surface-mute);
  padding: 3px 7px;
  border-radius: var(--af-r-sm);
  border: 1px solid var(--af-line);
}
.af-theme {
  font-family: var(--af-font-mono);
  font-size: 11.5px;
  letter-spacing: 0.4px;
  color: var(--af-info);
  text-transform: uppercase;
}

.af-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px 3px 8px;
  border-radius: var(--af-r-pill);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
}
.af-pill::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.9;
}
.af-pill--open    { background: var(--af-success-soft); color: var(--af-success); }
.af-pill--draft   { background: var(--af-warn-soft);    color: var(--af-warn-ink); }
.af-pill--closed  { background: var(--af-neutral-soft); color: var(--af-neutral-ink); }
.af-pill--info    { background: var(--af-info-soft);    color: var(--af-info); }
.af-pill--present { background: var(--af-success-soft); color: var(--af-success); }
.af-pill--absent  { background: var(--af-danger-soft);  color: var(--af-danger); }
.af-pill--late    { background: var(--af-warn-soft);    color: var(--af-warn-ink); }

/* ---------- 12. Detail-page header ------------------------------------- */
.af-detail-header {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 24px 26px;
  margin-bottom: 22px;
  display: flex;
  align-items: flex-start;
  gap: 24px;
}
.af-detail-header__main { flex: 1; min-width: 0; }
.af-detail-header__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

/* Editable title (h1 + bouton crayon ; passe en input quand actif) */
.af-editable {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.af-editable__title {
  font-family: var(--af-font-serif);
  font-size: 32px;
  font-weight: 500;
  margin: 0;
  letter-spacing: -0.4px;
  color: var(--af-ink);
  line-height: 1.15;
}
.af-editable__edit {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--af-r-md);
  color: var(--af-ink-3);
  cursor: pointer;
  flex-shrink: 0;
}
.af-editable__edit:hover { color: var(--af-action); background: var(--af-action-soft); }
.af-editable__input {
  font-family: var(--af-font-serif);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.4px;
  color: var(--af-ink);
  background: var(--af-surface);
  border: 1px solid var(--af-action);
  border-radius: var(--af-r-md);
  padding: 4px 10px;
  width: 100%;
  outline: none;
  box-shadow: 0 0 0 3px var(--af-action-soft);
}
.af-editable--editing .af-editable__title,
.af-editable--editing .af-editable__edit { display: none; }
.af-editable:not(.af-editable--editing) .af-editable__input,
.af-editable:not(.af-editable--editing) .af-editable__save,
.af-editable:not(.af-editable--editing) .af-editable__cancel { display: none; }
.af-editable__save, .af-editable__cancel {
  font-size: 12px;
  padding: 6px 10px;
  border-radius: var(--af-r-sm);
  border: 1px solid var(--af-line);
  background: var(--af-surface);
  color: var(--af-ink-2);
  cursor: pointer;
  flex-shrink: 0;
}
.af-editable__save { background: var(--af-action); color: var(--af-on-color); border-color: var(--af-action); }
.af-editable__save:hover { background: var(--af-action-hover); }

/* Metadata row (code · thème · dates · statut) */
.af-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  color: var(--af-ink-2);
  font-size: 13px;
}
.af-meta__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.af-meta__sep { color: var(--af-ink-3); opacity: 0.5; }
.af-meta__icon { color: var(--af-ink-3); display: inline-flex; }

/* Définition list de l'en-tête de détail (alternative à .af-meta) */
.af-defs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 18px 24px;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--af-line-2);
}
.af-defs__item dt {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--af-ink-3);
  margin-bottom: 4px;
}
.af-defs__item dd {
  margin: 0;
  font-size: 14px;
  color: var(--af-ink);
  font-weight: 500;
}

/* ---------- 13. Section / Card ----------------------------------------- */
.af-section { margin-bottom: 28px; }
.af-section__header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}
.af-section__title {
  font-family: var(--af-font-serif);
  font-size: 22px;
  font-weight: 500;
  margin: 0;
  letter-spacing: -0.2px;
}
.af-section__sub { color: var(--af-ink-3); font-size: 13px; margin: 4px 0 0; }
.af-card {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 22px 24px;
}

/* ---------- 14. Empty state ------------------------------------------- */
.af-empty {
  background: var(--af-surface);
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 48px 24px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.af-empty__icon {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--af-bg);
  border-radius: var(--af-r-pill);
  color: var(--af-ink-3);
  margin-bottom: 6px;
}
.af-empty__title {
  font-family: var(--af-font-serif);
  font-size: 20px;
  font-weight: 500;
  margin: 0;
  color: var(--af-ink);
}
.af-empty__sub {
  margin: 0 0 14px;
  color: var(--af-ink-3);
  font-size: 13.5px;
  max-width: 360px;
}

/* ---------- 15. Formulaires (système générique) ----------------------- */
.af-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 640px;
}
.af-form--wide { max-width: 100%; }

.af-form__section {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--af-line-2);
}
.af-form__section:last-of-type { border-bottom: 0; padding-bottom: 0; }
.af-form__section-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--af-ink);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin: 0 0 4px;
}
.af-form__section-sub {
  font-size: 13px;
  color: var(--af-ink-3);
  margin: 0 0 8px;
}

/* Grille 2 colonnes pour formulaire dense */
.af-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px 20px;
}
.af-form-grid--full { grid-column: 1 / -1; }

/* Field : groupe label + input + help/error */
.af-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.af-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--af-ink-2);
}
.af-field--required .af-label::after {
  content: ' *';
  color: var(--af-danger);
}
.af-help {
  font-size: 12.5px;
  color: var(--af-ink-3);
  margin: 0;
}
.af-error {
  font-size: 12.5px;
  color: var(--af-danger);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Inputs / select / textarea */
.af-input,
.af-select,
.af-textarea {
  width: 100%;
  padding: 10px 12px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  font-size: 14px;
  color: var(--af-ink);
  font-family: inherit;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.af-input::placeholder,
.af-textarea::placeholder { color: var(--af-ink-3); }
.af-input:hover,
.af-select:hover,
.af-textarea:hover { border-color: var(--af-ink-3); }
.af-input:focus,
.af-select:focus,
.af-textarea:focus {
  outline: none;
  border-color: var(--af-action);
  box-shadow: 0 0 0 3px var(--af-action-soft);
}
.af-textarea { min-height: 96px; resize: vertical; }
.af-select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 20 20' fill='none' stroke='%23807A72' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><path d='m6 8 4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px;
}

/* État erreur — appliqué au .af-field parent */
.af-field--error .af-input,
.af-field--error .af-select,
.af-field--error .af-textarea {
  border-color: var(--af-danger);
  background: var(--af-danger-soft);
}
.af-field--error .af-input:focus,
.af-field--error .af-select:focus,
.af-field--error .af-textarea:focus {
  box-shadow: 0 0 0 3px var(--af-danger-soft);
}

/* Hint inline à droite du label (ex : "Optionnel") */
.af-label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.af-label-row .af-help { font-size: 11.5px; }

/* Form actions (bottom bar de boutons) */
.af-form-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 8px;
}
.af-form-actions__spacer { margin-left: auto; }

/* Checkbox + radio (rendu uniforme léger) */
.af-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--af-ink-2);
  cursor: pointer;
}
.af-check input { accent-color: var(--af-action); width: 16px; height: 16px; }

/* ---------- 16. Confirmation popover (delete) ------------------------- */
.af-confirm {
  position: absolute;
  z-index: 30;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  box-shadow: var(--af-shadow-pop);
  padding: 14px 14px 12px;
  width: 280px;
}
.af-confirm__title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--af-ink);
  margin: 0 0 4px;
}
.af-confirm__text { font-size: 12.5px; color: var(--af-ink-3); margin: 0 0 12px; }
.af-confirm__actions { display: flex; justify-content: flex-end; gap: 8px; }

/* ---------- 17. Avatars (liste personnes) ----------------------------- */
.af-avatar-sm {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--af-surface-mute);
  color: var(--af-ink-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
}

/* ---------- 18. Focus visible (a11y) ---------------------------------- */
:where(button, a, [role="tab"], [role="button"], input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--af-action);
  outline-offset: 2px;
  border-radius: var(--af-r-md);
}
.af-input:focus-visible,
.af-select:focus-visible,
.af-textarea:focus-visible { outline: none; } /* géré via box-shadow */

/* ---------- 18b. Page sommaire (handoff/index.html) ------------------ */
.af-handoff-main { max-width: 920px; margin: 0 auto; }
.af-link-list { list-style: none; padding: 0; margin: 16px 0 0; display: grid; gap: 10px; }
.af-link-list .af-btn-secondary { justify-content: flex-start; }
.af-file-list { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; gap: 8px; font-family: var(--af-font-mono); font-size: 13px; }

/* ---------- 19. Utilitaires accessibilité ---------------------------- */
.af-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- 20. Responsive ------------------------------------------- */
@media (max-width: 1080px) {
  .af-app { grid-template-columns: 1fr; }
  .af-side { display: none; } /* JS : transformer en drawer */
  .af-burger { display: inline-flex !important; } /* visible seulement ici */
  /* Sidebar en drawer : s'ouvre par-dessus le contenu quand data-open */
  .af-side[data-open] {
    display: flex; position: fixed; top: 0; left: 0; bottom: 0; z-index: 50;
    width: var(--af-side-w); box-shadow: 0 0 40px rgba(0,0,0,.18);
  }
  .af-stats { grid-template-columns: repeat(2, 1fr); }
  .af-row { grid-template-columns: 110px 1fr 110px 100px; gap: 10px; }
  .af-row__theme, .af-row__teams, .af-row__updated { display: none; }
  .af-detail-header { flex-direction: column; }
}
@media (max-width: 640px) {
  .af-main { padding: 20px; }
  .af-titlebar { flex-direction: column; align-items: flex-start; }
  .af-stats { grid-template-columns: 1fr 1fr; }
  .af-editable__title, .af-editable__input { font-size: 26px; }
}

/* █████████████████████████████████████████████████████████████████████████
   MIGRATION alterForge — compléments ajoutés lors du passage au design system.
   Classes regroupées par page/usage. Ajoutées au fil de la migration des pages
   (dashboard, classes, sessions, feedback, émargement, projection, étudiant).
   █████████████████████████████████████████████████████████████████████████ */

/* ===== Compléments alterForge (ajouts à l'intégration) ===== */
/* Message flash (confirmation d'action) */
.af-flash{background:var(--af-success-soft);color:var(--af-success-ink);border:1px solid var(--af-success);
  border-radius:var(--af-r-md);padding:10px 14px;margin:0 0 18px;font-size:14px;}
/* Titre de carte */
.af-card__title{font-family:var(--af-font-serif);font-size:18px;margin:0 0 14px;color:var(--af-ink);}
/* Formulaire en ligne (champs + bouton sur une rangée) */
.af-form-inline{display:flex;gap:10px;align-items:center;flex-wrap:wrap;}
/* Texte discret */
.af-muted{color:var(--af-ink-3);}
/* Grille table : référentiel modules (Code, Intitulé, Action) */
.af-row--modules{grid-template-columns:160px 1fr 90px;}
/* Grille table : liste des classes (Nom, Étudiants, Action) */
.af-row--classes{grid-template-columns:1.6fr 120px 200px;}

/* ===== Impression (feuille d'émargement) ===== */
@media print {
  .af-side, .af-top, .af-noprint { display: none !important; }
  .af-app { grid-template-columns: 1fr !important; }
  .af-col { display: block !important; }
  .af-main { padding: 0 !important; }
  .af-table, .af-row { box-shadow: none !important; border-color: #ccc !important; }
}
.af-sig-mini { height: 40px; }
/* Grille feuille d'émargement (créneau) : Nom, Prénom, Statut, Signature, Heure, [action] */
.af-row--sheet { grid-template-columns: 1.2fr 1.2fr 100px 140px 70px 130px; }
.af-row--slots { grid-template-columns: 1.4fr 1fr 130px 110px 80px 110px 110px; }

/* Bouton burger : masqué par défaut (grand écran), affiché en responsive (voir @media 1080px) */
.af-burger{display:none;align-items:center;justify-content:center;width:38px;height:38px;
  border:1px solid var(--af-line);border-radius:var(--af-r-md);background:var(--af-surface);
  color:var(--af-ink-2);cursor:pointer;}
.af-burger:hover{background:var(--af-surface-soft);}

/* ===== Page gestion de session ===== */
/* Bloc équipe */
.af-team-block{border:1px solid var(--af-line);border-radius:var(--af-r-lg);padding:14px 16px;margin:0 0 14px;background:var(--af-surface);}
.af-team-block__head{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;}
.af-team-block__actions{display:flex;gap:6px;align-items:center;}
/* Liste de membres / animateurs */
.af-members{list-style:none;margin:8px 0 0;padding:0;}
.af-members__item{padding:10px 0;border-top:1px dashed var(--af-line-2);display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;}
.af-member-edit summary{cursor:pointer;color:var(--af-action);font-size:13px;}
/* Carte danger */
.af-card--danger{border-color:#f0c4c4;}
/* Modale (QR) */
.af-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:9999;align-items:center;justify-content:center;display:flex;}
.af-modal{background:var(--af-surface);border-radius:var(--af-r-xl);padding:24px;text-align:center;max-width:360px;}
/* Message flash erreur (rouge) */
.af-flash--error{background:var(--af-danger-soft);color:var(--af-danger-ink);border-color:var(--af-danger);}

/* ===== Page projection QR (qr_all.php) — plein écran, imprimable ===== */
.af-qr-bar{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:14px 24px;border-bottom:1px solid var(--af-line);background:var(--af-surface);}
.af-qr-head{text-align:center;padding:24px 24px 0;}
.af-qr-head h1{font-family:var(--af-font-serif);margin:0 0 6px;}
.af-qr-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(360px,1fr));gap:40px;padding:30px 40px 60px;}
.af-qr-card{text-align:center;border:4px solid var(--af-line-2);border-radius:18px;background:var(--af-surface);padding:0 0 24px;overflow:hidden;page-break-inside:avoid;break-inside:avoid;}
.af-qr-band{font-size:28px;font-weight:700;color:#fff;padding:14px 18px;margin-bottom:16px;display:flex;align-items:center;justify-content:center;gap:10px;font-family:var(--af-font-serif);}
.af-qr-colour{font-size:14px;font-weight:600;background:rgba(255,255,255,.25);padding:2px 10px;border-radius:999px;}
.af-qr-code{font-size:18px;color:var(--af-ink-2);letter-spacing:2px;margin-bottom:16px;font-weight:600;}
.af-qr-img{display:flex;justify-content:center;}
.af-qr-scan{margin-top:14px;color:var(--af-ink-3);font-size:15px;}
@media print{ .af-qr-bar{display:none;} .af-qr-grid{grid-template-columns:repeat(2,1fr);gap:30px;} }

/* ===== Page bugs (suivi des signalements) ===== */
.af-bug-filters{display:flex;gap:14px;flex-wrap:wrap;margin:0 0 18px;}
.af-bug-filters a{font-size:14px;text-decoration:none;color:var(--af-ink-3);}
.af-bug-filters a.on{color:var(--af-action);font-weight:700;}
.af-bug{border:1px solid var(--af-line);border-radius:var(--af-r-lg);padding:16px;margin:12px 0;background:var(--af-surface);}
.af-bug__sev{display:inline-block;padding:2px 10px;border-radius:var(--af-r-pill);font-size:12px;color:#fff;}
.af-bug__meta{font-size:12px;color:var(--af-ink-3);margin:6px 0;}
.af-bug pre{background:var(--af-surface-mute);padding:8px;border-radius:6px;overflow:auto;font-size:12px;max-height:200px;}
.af-bug details summary{cursor:pointer;color:var(--af-action);font-size:13px;margin-top:6px;}

/* ===== Page feedback (critères + notes) ===== */
.af-subject{border:1px solid var(--af-line);border-radius:var(--af-r-lg);padding:14px 16px;margin:12px 0;background:var(--af-surface);}
.af-crit-table{width:100%;border-collapse:collapse;}
.af-crit-table td{padding:4px 6px;}
.af-crit-table th{padding:4px 6px;text-align:left;font-size:13px;color:var(--af-ink-3);font-weight:600;}
/* Grille créneaux émargement session (Label, Date, Mode, Présents, Ouvert, Action) */
.af-row--slots2{grid-template-columns:1.4fr 130px 110px 80px 110px 140px;}
/* Barre projection : grouper langue + imprimer à droite */
.af-qr-bar__right{display:flex;align-items:center;gap:16px;}

/* ===== Layout ÉTUDIANT (me.php, join.php, my.php) — épuré, sans sidebar ===== */
.af-student{min-height:100vh;background:var(--af-bg);}
.af-student__top{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid var(--af-line);background:var(--af-surface);}
/* Dans l'en-tête étudiant, le logo n'a pas de menu en dessous : pas de trait séparateur */
.af-student__top .af-brand{border-bottom:0;padding-bottom:6px;}
.af-student__main{max-width:640px;margin:0 auto;padding:28px 20px 60px;}
.af-student__lang{font-size:14px;}
/* Canvas de signature */
.af-sigpad{border:2px dashed var(--af-action);border-radius:var(--af-r-md);width:100%;height:180px;touch-action:none;background:#fff;display:block;}
.af-sig-preview{max-height:80px;border:1px solid var(--af-line);border-radius:8px;}
/* Créneau émargement (côté étudiant) */
.af-slot{border:1px solid var(--af-line);border-radius:var(--af-r-lg);padding:14px 16px;margin:10px 0;display:flex;justify-content:space-between;align-items:center;gap:10px;background:var(--af-surface);}
.af-ok-badge{color:var(--af-success-ink);font-weight:600;}

/* ===== Enrôlement étudiant (join.php) : lignes de membres ===== */
.af-enrol-head,.af-enrol-row{display:grid;grid-template-columns:1fr 1fr 1.4fr 40px;gap:8px;align-items:center;margin-bottom:8px;}
.af-enrol-head{font-size:12px;font-weight:600;color:var(--af-ink-3);margin-bottom:4px;}
.af-enrol-row input{width:100%;}
.af-link-sm{font-size:12px;color:var(--af-brand);word-break:break-all;}

/* Bibliothèque de grilles (modèles) dans feedback.php */
.af-tpl-bar{margin-top:18px;padding-top:16px;border-top:1px dashed var(--af-line);display:flex;flex-direction:column;gap:12px;}
.af-tpl-load,.af-tpl-save{display:flex;gap:8px;align-items:center;flex-wrap:wrap;}
.af-tpl-bar label{font-size:13px;}

/* Évaluations (feedback.php) : en-tête de carte avec action + champs étiquetés */
.af-card__head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:4px;}
.af-card__head .af-card__title{margin:0;}
.af-field-mini{display:flex;flex-direction:column;gap:2px;font-size:12px;}
.af-field-mini span{font-size:11px;}

/* Liste des évaluations (feedback.php) : nom · type · date · notes · actions */
.af-row--evals{grid-template-columns:1.6fr 150px 120px 80px 160px;}

/* Formulaire vertical (création d'évaluation, etc.) */
.af-stack{display:flex;flex-direction:column;gap:14px;max-width:520px;}
.af-stack .af-label{display:flex;flex-direction:column;gap:4px;font-weight:500;}

/* =========================================================================
   SECTION 21 — « Composer les équipes » (admin)
   Ajoutée le 25/05/2026. Toutes les variables --af-* requises sont déjà
   définies plus haut dans ce fichier (vérifié). Classes réutilisées
   existantes : af-pill, af-empty, af-btn-*, af-avatar-sm, af-label, af-select.
   ========================================================================= */

/* ---- 21a. Toolbar de paramétrage --------------------------------- */
.af-toolbar {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 18px 22px;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 20px 24px;
  margin-bottom: 18px;
}
.af-toolbar__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 200px;
}
.af-toolbar__field--grow { flex: 1; }
.af-toolbar__sep {
  width: 1px;
  align-self: stretch;
  background: var(--af-line-2);
  margin: 4px 0;
}

/* ---- 21b. Segmented control (form input, type radio caché) ------- */
.af-segments {
  display: inline-flex;
  background: var(--af-bg);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  padding: 3px;
  gap: 2px;
}
.af-segment { position: relative; margin: 0; display: inline-flex; }
.af-segment > input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0; height: 0;
}
.af-segment > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  padding: 8px 14px;
  border-radius: 7px;
  font-size: 14px;
  font-weight: 600;
  color: var(--af-ink-2);
  cursor: pointer;
  user-select: none;
  transition: background-color .12s ease, color .12s ease, box-shadow .12s ease;
}
.af-segment:hover > span { color: var(--af-ink); }
.af-segment > input:checked + span {
  background: var(--af-action);
  color: var(--af-on-color);
  box-shadow: 0 1px 3px rgba(13, 148, 136, 0.25);
}
.af-segment > input:checked:hover + span { color: var(--af-on-color); }
.af-segment > input:focus-visible + span {
  outline: 2px solid var(--af-action);
  outline-offset: 2px;
}

/* ---- 21c. Synthesis banner ---------------------------------------- */
.af-summary {
  background: var(--af-success-soft);
  border: 1px solid color-mix(in srgb, var(--af-success) 22%, transparent);
  border-radius: var(--af-r-xl);
  padding: 18px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.af-summary--info {
  background: var(--af-info-soft);
  border-color: color-mix(in srgb, var(--af-info) 22%, transparent);
}
.af-summary--alert {
  background: var(--af-danger-soft);
  border-color: color-mix(in srgb, var(--af-danger) 22%, transparent);
}
.af-summary--warn {
  background: var(--af-warn-soft);
  border-color: color-mix(in srgb, var(--af-warn) 25%, transparent);
}

.af-summary__main { display: flex; align-items: center; gap: 18px; min-width: 0; }
.af-summary__big {
  font-family: var(--af-font-serif);
  font-size: 44px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -1px;
  color: var(--af-success);
  flex-shrink: 0;
}
.af-summary--info  .af-summary__big { color: var(--af-info); }
.af-summary--alert .af-summary__big { color: var(--af-danger); }
.af-summary--warn  .af-summary__big { color: var(--af-warn-ink); }

.af-summary__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.af-summary__title {
  font-family: var(--af-font-serif);
  font-size: 19px;
  font-weight: 500;
  color: var(--af-ink);
  margin: 0;
  letter-spacing: -0.2px;
}
.af-summary__breakdown {
  font-size: 13.5px;
  color: var(--af-ink-2);
  margin: 0;
}
.af-summary__check {
  font-family: var(--af-font-mono);
  font-size: 11.5px;
  color: var(--af-ink-3);
  margin: 2px 0 0;
}
.af-summary__actions { display: flex; gap: 10px; flex-shrink: 0; }

/* ---- 21d. Grille de cartes équipes ------------------------------- */
.af-team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}

.af-team {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 18px 18px 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.af-team__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.af-team__name {
  font-family: var(--af-font-serif);
  font-size: 19px;
  font-weight: 500;
  margin: 0;
  color: var(--af-ink);
  letter-spacing: -0.2px;
}
.af-team__members {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.af-member {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 13.5px;
  color: var(--af-ink);
}
.af-member + .af-member { border-top: 1px solid var(--af-line-2); }

/* ---- 21e. État validé : carte avec code d'accès ------------------- */
.af-team--validated {
  border-color: color-mix(in srgb, var(--af-success) 38%, var(--af-line));
  background:
    linear-gradient(180deg, var(--af-success-soft) 0%, transparent 60%),
    var(--af-surface);
}
.af-access-code {
  background: var(--af-ink);
  color: var(--af-on-color);
  font-family: var(--af-font-mono);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 4px;
  padding: 10px 14px;
  border-radius: var(--af-r-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.af-access-code__label {
  font-family: var(--af-font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  display: block;
  margin-bottom: 2px;
}
.af-access-code__value { letter-spacing: 4px; }
.af-access-code__copy {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: var(--af-on-color);
  font-family: var(--af-font-sans);
  font-size: 11.5px;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: var(--af-r-sm);
  cursor: pointer;
  letter-spacing: 0;
  flex-shrink: 0;
  transition: background-color .12s ease;
}
.af-access-code__copy:hover { background: rgba(255, 255, 255, 0.12); }
.af-access-code__copy[data-copied="true"] {
  background: var(--af-success);
  border-color: var(--af-success);
}

/* ---- 21f. Hint (sous la toolbar : nombre d'étudiants) ------------- */
.af-hint {
  font-size: 12.5px;
  color: var(--af-ink-3);
  margin: -6px 0 16px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.af-hint strong { color: var(--af-ink-2); font-weight: 500; }


/* ---- 21f. Composition manuelle / drag and drop -------------------- */
.af-toolbar__field--mode { min-width: 260px; }
.af-segments--mode .af-segment > span { min-width: 94px; }
.af-btn-xs {
  padding: 5px 8px;
  font-size: 12px;
  line-height: 1.1;
}
.af-pill--warn {
  background: var(--af-warn-soft);
  color: var(--af-warn-ink);
}
.af-summary__error {
  margin: 4px 0 0;
  color: var(--af-warn-ink);
  font-size: 13px;
  font-weight: 600;
}
.af-compose-board {
  display: grid;
  grid-template-columns: minmax(240px, 320px) 1fr;
  gap: 14px;
  align-items: start;
}
.af-roster-pool {
  background: var(--af-surface);
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 16px;
  position: sticky;
  top: 16px;
}
.af-roster-pool__head,
.af-team__head-right,
.af-team__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.af-roster-pool__head {
  justify-content: space-between;
  margin-bottom: 10px;
}
.af-team__head-right { flex-shrink: 0; }
.af-team--editable { min-height: 170px; }
.af-dropzone {
  min-height: 52px;
  border: 1px dashed transparent;
  border-radius: var(--af-r-md);
  padding: 4px;
  margin: -4px;
  transition: background-color .12s ease, border-color .12s ease;
}
.af-member--draggable {
  cursor: grab;
  border-radius: var(--af-r-md);
  padding-left: 6px;
  padding-right: 6px;
}
.af-member--empty {
  justify-content: center;
  color: var(--af-ink-3);
  font-size: 13px;
  border: 1px dashed var(--af-line-2);
  border-radius: var(--af-r-md);
  padding: 12px;
}
.af-member__meta {
  color: var(--af-ink-3);
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.af-member__actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.af-member-move {
  max-width: 118px;
  min-width: 98px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-sm);
  padding: 5px 8px;
  background: var(--af-surface);
  color: var(--af-ink-2);
  font-size: 12px;
}

@media (max-width: 860px) {
  .af-compose-board { grid-template-columns: 1fr; }
  .af-roster-pool { position: static; }
  .af-toolbar__field--mode { min-width: 100%; }
}

@media (max-width: 560px) {
  .af-segments--mode { display: grid; grid-template-columns: 1fr; width: 100%; }
  .af-segments--mode .af-segment > span { width: 100%; min-width: 0; }
  .af-team__head-right { align-items: flex-end; flex-direction: column; }
  .af-member { align-items: flex-start; }
  .af-member__actions { width: 100%; justify-content: flex-end; }
  .af-member-move { max-width: 100%; }
}

/* =========================================================================
   SECTION 22 — Alignement visuel du composeur d'équipes manuel
   Style proche de l'onglet Classes > Équipes : carte blanche, lignes sobres,
   actions à droite, badges compacts et séparation horizontale.
   ========================================================================= */
.af-toolbar {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 22px 28px;
  box-shadow: none;
}

.af-compose-panel {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 24px 28px 18px;
  margin-top: 18px;
}
.af-compose-panel__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 24px;
}
.af-compose-panel__titlebox {
  min-width: 0;
  max-width: 680px;
}
.af-compose-panel__title {
  font-family: var(--af-font-serif);
  font-size: 24px;
  line-height: 1.15;
  font-weight: 500;
  color: var(--af-ink);
  margin: 0 0 10px;
  letter-spacing: -0.25px;
}
.af-compose-panel__hint {
  margin: 0;
  color: var(--af-ink-3);
  font-size: 14px;
  line-height: 1.45;
}
.af-compose-panel__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  flex: 0 0 auto;
}
.af-compose-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin: 0 0 16px;
  color: var(--af-ink-3);
  font-family: var(--af-font-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
.af-compose-meta span + span::before {
  content: '·';
  margin-right: 12px;
  color: var(--af-ink-3);
  opacity: .65;
}
.af-compose-meta--warn { color: var(--af-warn-ink); }
.af-compose-error {
  margin: -4px 0 14px;
  color: var(--af-warn-ink);
  background: var(--af-warn-soft);
  border: 1px solid color-mix(in srgb, var(--af-warn) 22%, transparent);
  border-radius: var(--af-r-md);
  padding: 10px 12px;
  font-size: 13px;
  font-weight: 600;
}

.af-team-list {
  display: flex;
  flex-direction: column;
}
.af-team-grid { display: flex; flex-direction: column; gap: 0; }
.af-compose-panel .af-team {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--af-line-2);
  border-radius: 0;
  padding: 16px 4px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}
.af-compose-panel .af-team:first-child { border-top-color: var(--af-line); }
.af-compose-panel .af-team--validated {
  background: transparent;
  border-color: var(--af-line-2);
}
.af-team__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  width: 100%;
}
.af-team__identity {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.af-team__name {
  font-family: var(--af-font-sans);
  font-size: 14px;
  line-height: 1.2;
  font-weight: 700;
  color: var(--af-ink);
  margin: 0;
  letter-spacing: 0;
  white-space: nowrap;
}
.af-team__head-right {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-shrink: 0;
}
.af-compose-panel .af-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
}
.af-compose-panel .af-pill::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: currentColor;
  display: inline-block;
  margin-right: 6px;
  opacity: .8;
}

.af-compose-panel .af-team__members {
  list-style: none;
  margin: 2px 0 0 22px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.af-compose-panel .af-member {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  border-top: 0;
  color: var(--af-ink);
  font-size: 14px;
  line-height: 1.25;
}
.af-compose-panel .af-member + .af-member { border-top: 0; }
.af-member__dot {
  display: inline-flex;
  width: 18px;
  justify-content: center;
  color: var(--af-ink);
  font-size: 18px;
  line-height: 1;
  flex: 0 0 auto;
}
.af-member__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
.af-member__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-member__meta {
  color: var(--af-ink-3);
  font-size: 12px;
  line-height: 1.2;
}
.af-member__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-left: auto;
  flex: 0 0 auto;
}
.af-member-move {
  min-width: 122px;
  max-width: 160px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  padding: 7px 9px;
  background: var(--af-surface);
  color: var(--af-ink-2);
  font-size: 12px;
}
.af-member-remove {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--af-danger);
  cursor: pointer;
  font-size: 20px;
  line-height: 1;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--af-r-sm);
}
.af-member-remove:hover {
  background: var(--af-danger-soft);
  color: var(--af-danger-ink);
}
.af-member--draggable {
  cursor: grab;
  border-radius: var(--af-r-md);
  padding-left: 4px;
  padding-right: 4px;
}
.af-member--draggable:hover { background: var(--af-bg); }
.af-member--dragging { opacity: .45; }
.af-compose-panel .af-member--empty {
  justify-content: center;
  color: var(--af-ink-3);
  font-size: 13px;
  border: 1px dashed var(--af-line-2);
  border-radius: var(--af-r-md);
  padding: 12px;
  margin: 4px 0;
}
.af-compose-panel .af-member--empty .af-member__dot { display: none; }

.af-compose-board {
  display: grid;
  grid-template-columns: minmax(260px, 330px) 1fr;
  gap: 20px;
  align-items: start;
}
.af-roster-pool {
  background: var(--af-surface-soft);
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 16px;
  position: sticky;
  top: 16px;
}
.af-roster-pool__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.af-roster-pool__title {
  font-family: var(--af-font-sans);
  font-size: 14px;
  font-weight: 700;
  margin: 0 0 4px;
  color: var(--af-ink);
}
.af-roster-pool__hint {
  margin: 0;
  color: var(--af-ink-3);
  font-size: 12.5px;
  line-height: 1.35;
}
.af-roster-pool .af-team__members { margin-left: 0; }
.af-dropzone {
  min-height: 52px;
  border: 1px dashed transparent;
  border-radius: var(--af-r-md);
  padding: 4px;
  transition: background-color .12s ease, border-color .12s ease;
}
.af-dropzone--active {
  background: var(--af-info-soft);
  border-color: color-mix(in srgb, var(--af-info) 35%, transparent);
}
.af-access-code {
  margin: 2px 0 4px 0;
  max-width: 320px;
}

@media (max-width: 980px) {
  .af-compose-panel__head {
    flex-direction: column;
    align-items: stretch;
  }
  .af-compose-panel__actions {
    justify-content: flex-start;
  }
  .af-compose-board { grid-template-columns: 1fr; }
  .af-roster-pool { position: static; }
}

@media (max-width: 560px) {
  .af-compose-panel { padding: 20px 16px 14px; }
  .af-compose-panel__actions { width: 100%; }
  .af-compose-panel__actions > * { flex: 1 1 100%; justify-content: center; }
  .af-team__head {
    align-items: flex-start;
  }
  .af-team__identity {
    align-items: flex-start;
    flex-direction: column;
    gap: 6px;
  }
  .af-team__head-right { align-items: flex-end; }
  .af-compose-panel .af-team__members { margin-left: 0; }
  .af-compose-panel .af-member {
    align-items: flex-start;
    flex-wrap: wrap;
  }
  .af-member__actions {
    width: 100%;
    justify-content: flex-end;
    padding-left: 26px;
  }
  .af-member-move { max-width: 100%; flex: 1 1 auto; }
}

/* =========================================================================
   SECTION 23 — Patterns « Équipes de classe » (class-teams.php)
   Ajoutée le 28/05/2026. Patterns introduits pour redessiner l'onglet
   Classes > Équipes : carte de section avec en-tête à deux zones,
   listes-roster compactes, sous-groupes datés.

   Composants réutilisables sur d'autres pages :
   - .af-section--card    : carte englobante avec header
   - .af-section__head    : titre/sous-titre à gauche, formulaire inline à droite
   - .af-inline-form      : alias d'usage de .af-form-inline avec largeur d'input
                            calibrée pour les en-têtes (200px)
   - .af-roster           : liste de lignes (TP, équipes, etc.)
   - .af-roster-group     : sous-groupe daté avec action de suppression
   - .af-link-danger      : lien texte rouge discret (≠ .af-btn-danger plein)
   - .af-btn-generate     : CTA secondaire d'action automatique (icône éclair)
   ========================================================================= */

/* ---- 23a. Section avec carte englobante ---------------------------- */
.af-section--card {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 24px 26px 22px;
  margin-bottom: 18px;
}
.af-section__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 18px;
}
.af-section__head-text { min-width: 0; flex: 1; }
.af-section__head-title {
  font-family: var(--af-font-serif);
  font-size: 22px;
  font-weight: 500;
  margin: 0;
  letter-spacing: -0.2px;
  color: var(--af-ink);
}
.af-section__head-sub {
  margin: 4px 0 0;
  color: var(--af-ink-3);
  font-size: 13.5px;
  max-width: 560px;
}

/* ---- 23b. Formulaire inline calibré pour les en-têtes -------------- */
/* Note : .af-form-inline (déjà défini) reste pour les formulaires libres.
   .af-inline-form fige la largeur de l'input à 200px et le padding réduit
   pour rester aligné avec un titre de section sur une seule ligne. */
.af-inline-form {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.af-inline-form .af-input,
.af-inline-form .af-select {
  width: 200px;
  padding: 9px 12px;
  font-size: 13.5px;
}

/* ---- 23c. Roster — liste de lignes simples (TP, Équipe…) ----------- */
.af-roster {
  display: flex;
  flex-direction: column;
}
.af-roster__row {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 12px 4px;
  font-size: 14px;
}
.af-roster__row + .af-roster__row { border-top: 1px solid var(--af-line-2); }
.af-roster__name {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-weight: 500;
  color: var(--af-ink);
  min-width: 0;
}
.af-roster__name strong { font-weight: 600; }
.af-roster__pill { flex-shrink: 0; }

/* ---- 23d. Sous-groupe daté ----------------------------------------- */
.af-roster-group { margin-top: 6px; }
.af-roster-group + .af-roster-group {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px dashed var(--af-line);
}
.af-roster-group__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 4px 4px 10px;
  border-bottom: 1px solid var(--af-line-2);
  margin-bottom: 4px;
}
.af-roster-group__label {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  font-weight: 500;
}
.af-roster-group__label strong { color: var(--af-ink-2); font-weight: 600; }
.af-roster-group__action { margin-left: auto; }

/* ---- 23e. Lien d'action rouge discret ------------------------------ */
/* Pour les actions destructives en sous-groupe, où un bouton plein
   serait trop visuel (ex : « Supprimer ce groupe d'équipes »). */
.af-link-danger {
  background: transparent;
  border: 0;
  padding: 4px 6px;
  color: var(--af-danger);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: var(--af-r-sm);
}
.af-link-danger:hover {
  background: var(--af-danger-soft);
  color: var(--af-danger-ink);
}

/* ---- 23f. Bouton « Générer » (action automatique) ------------------ */
/* CTA secondaire teal-soft + icône éclair, pour les actions où l'app
   produit quelque chose (génération aléatoire d'équipes, etc.). */
.af-btn-generate {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 14px;
  background: var(--af-action-soft);
  color: var(--af-action-hover);
  border: 1px solid transparent;
  border-radius: var(--af-r-md);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.af-btn-generate:hover {
  background: var(--af-action);
  color: var(--af-on-color);
}
.af-btn-generate svg { color: currentColor; }

/* ---- 23g. État vide intra-section (plus discret que .af-empty) ----- */
.af-roster__empty {
  text-align: center;
  padding: 22px 12px;
  color: var(--af-ink-3);
  font-size: 13.5px;
}

/* ---- 23h. Responsive ---------------------------------------------- */
@media (max-width: 720px) {
  .af-section__head { flex-direction: column; align-items: stretch; }
  .af-inline-form { flex-wrap: wrap; }
  .af-inline-form .af-input { flex: 1; width: auto; }
  .af-roster__row { grid-template-columns: 1fr auto auto; row-gap: 6px; }
  .af-roster__row > :nth-child(2) { grid-column: 1 / 2; grid-row: 2; }
  .af-roster-group__head { flex-wrap: wrap; }
}

/* =========================================================================
   SECTION 24 — Roster row déplié (panneau de gestion des membres)
   Ajoutée le 28/05/2026. Permet d'éditer les membres d'un groupe TP / d'une
   équipe directement sous sa ligne, sans modale.

   Patron :
     <div class="af-roster">
       <div class="af-roster__row af-roster__row--expanded">…</div>
       <div class="af-roster__expanded">
         <ul class="af-roster__members-list">
           <li class="af-roster__member">…avatar / nom / retirer…</li>
         </ul>
         <form class="af-roster__add">
           <select class="af-select">…</select>
           <button class="af-btn-primary">Ajouter</button>
         </form>
       </div>
       <div class="af-roster__row">…suivante…</div>
     </div>
   ========================================================================= */

/* ---- 24a. La ligne marquée comme dépliée --------------------------- */
.af-roster__row--expanded {
  background: var(--af-surface-soft);
  border-radius: var(--af-r-md);
  margin: 0 -8px;
  padding-left: 12px;
  padding-right: 12px;
}
/* Pas de séparateur entre une ligne dépliée et son panneau */
.af-roster__row--expanded + .af-roster__expanded { border-top: 0; }
/* Pas non plus entre le panneau et la ligne suivante : un dashed plus discret */
.af-roster__expanded + .af-roster__row { border-top: 1px dashed var(--af-line-2); }

/* ---- 24b. Le panneau lui-même -------------------------------------- */
.af-roster__expanded {
  background: var(--af-bg);
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-md);
  padding: 14px 16px;
  margin: 4px 0 10px;
}

/* ---- 24c. Liste des membres dans le panneau ------------------------ */
.af-roster__members-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.af-roster__member {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  font-size: 14px;
  color: var(--af-ink);
  border-radius: var(--af-r-sm);
  transition: background-color .12s ease;
}
.af-roster__member + .af-roster__member { border-top: 1px solid var(--af-line-2); }
.af-roster__member:hover { background: var(--af-surface); }
.af-roster__member-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Variante compacte de l'icon-btn pour les actions en bout de ligne */
.af-icon-btn--sm {
  width: 24px;
  height: 24px;
  border-radius: var(--af-r-sm);
}
.af-icon-btn--sm svg { width: 11px; height: 11px; }

/* ---- 24d. Formulaire d'ajout d'un membre --------------------------- */
.af-roster__add {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-top: 12px;
  border-top: 1px dashed var(--af-line);
}
.af-roster__add .af-select { flex: 1; min-width: 0; }
.af-roster__add .af-btn-primary {
  padding: 9px 14px;
  font-size: 13.5px;
  flex-shrink: 0;
  white-space: nowrap;
}

/* ---- 24e. Chevron de bouton (rotation à l'ouverture) --------------- */
.af-btn-secondary[aria-expanded="true"] .af-chevron,
.af-btn-ghost[aria-expanded="true"] .af-chevron { transform: rotate(180deg); }
.af-chevron { transition: transform .15s ease; }

/* ---- 24f. État vide du panneau (groupe sans membre) ---------------- */
.af-roster__members-list--empty {
  margin: 0 0 12px;
  padding: 18px 12px;
  text-align: center;
  color: var(--af-ink-3);
  font-size: 13.5px;
  background: var(--af-surface);
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-sm);
}

/* ---- 24g. Responsive ---------------------------------------------- */
@media (max-width: 560px) {
  .af-roster__add { flex-direction: column; align-items: stretch; }
  .af-roster__add .af-btn-primary { justify-content: center; }
}

/* =========================================================================
   SECTION 25 — Planning pédagogique (planning.php)
   Ajoutée le 31/05/2026. Deux vues : calendrier mensuel synthétique +
   timeline hebdomadaire (gantt classes × heures).

   Palette catégorielle « établissement / source » — c'est le SEUL endroit
   du système où l'on introduit des couleurs non sémantiques : chaque
   établissement a une teinte stable, dérivée pour rester dans l'harmonie
   papier-chaud. Utiliser via les classes .af-cat--{n} (1..6).
   ========================================================================= */

:root {
  --af-cat-1:      #0D9488;  --af-cat-1-soft: #E6F5F3;  /* teal   — interne */
  --af-cat-2:      #1E6091;  --af-cat-2-soft: #E8F0F6;  /* bleu   — partenaire A */
  --af-cat-3:      #B8860B;  --af-cat-3-soft: #FBF3E0;  /* ambre  — partenaire B */
  --af-cat-4:      #8C5A8C;  --af-cat-4-soft: #F3EAF3;  /* prune  — alternance */
  --af-cat-5:      #2D6A4F;  --af-cat-5-soft: #EAF3EE;  /* vert   — distanciel */
  --af-cat-6:      #B05A3C;  --af-cat-6-soft: #F8EAE3;  /* terre  — externe */
}

/* ---- 25a. Barre d'outils planning (navigation + filtres) ----------- */
.af-plan-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 14px 18px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  margin-bottom: 14px;
}
/* Navigation période ‹ Titre › */
.af-plan-nav {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.af-plan-nav__btn {
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  color: var(--af-ink-2);
  cursor: pointer;
  transition: border-color .12s ease, color .12s ease, background-color .12s ease;
}
.af-plan-nav__btn:hover { border-color: var(--af-ink-3); color: var(--af-ink); }
.af-plan-nav__title {
  font-family: var(--af-font-serif);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.2px;
  color: var(--af-ink);
  min-width: 168px;
  text-align: center;
  text-transform: capitalize;
}
.af-plan-today {
  padding: 7px 12px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  font-size: 13px;
  font-weight: 500;
  color: var(--af-ink-2);
  cursor: pointer;
}
.af-plan-today:hover { border-color: var(--af-ink-3); color: var(--af-ink); }

.af-plan-bar__spacer { flex: 1; }

/* Mini-filtre inline (label au-dessus + select compact) */
.af-plan-filter { display: inline-flex; flex-direction: column; gap: 3px; }
.af-plan-filter > .af-label { font-size: 11px; margin: 0; }
.af-plan-filter .af-select {
  padding: 7px 30px 7px 11px;
  font-size: 13px;
  min-width: 150px;
  height: 34px;
}

/* Segmented Mois / Semaine (réutilise .af-segments mais en boutons) */
.af-plan-modes { display: inline-flex; background: var(--af-bg); border: 1px solid var(--af-line); border-radius: var(--af-r-md); padding: 3px; gap: 2px; }
.af-plan-mode {
  padding: 6px 14px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--af-ink-2);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.af-plan-mode--active {
  background: var(--af-surface);
  color: var(--af-ink);
  box-shadow: var(--af-shadow-sm);
}

/* ---- 25b. Légende établissements ----------------------------------- */
.af-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  padding: 10px 18px;
  margin-bottom: 14px;
  font-size: 12.5px;
  color: var(--af-ink-2);
}
.af-legend__title {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  margin-right: 4px;
}
.af-legend__item { display: inline-flex; align-items: center; gap: 7px; }
.af-legend__dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }

/* ---- 25c. Vue MOIS — grille calendrier ----------------------------- */
.af-cal {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  overflow: hidden;
}
.af-cal__head,
.af-cal__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
.af-cal__head { border-bottom: 1px solid var(--af-line); background: var(--af-surface-soft); }
.af-cal__dow {
  padding: 11px 14px;
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  font-weight: 500;
}
.af-cal__dow:nth-child(n+6) { color: var(--af-ink-3); } /* week-end un poil plus doux possible */

.af-cal__cell {
  min-height: 116px;
  padding: 8px 8px 10px;
  border-right: 1px solid var(--af-line-2);
  border-bottom: 1px solid var(--af-line-2);
  display: flex;
  flex-direction: column;
  gap: 5px;
  position: relative;
  background: var(--af-surface);
  transition: background-color .1s ease;
}
.af-cal__cell:nth-child(7n) { border-right: 0; }
.af-cal__grid > .af-cal__cell:nth-last-child(-n+7) { border-bottom: 0; }
.af-cal__cell--out { background: var(--af-surface-soft); }
.af-cal__cell--out .af-cal__num { color: var(--af-line); }
.af-cal__cell--weekend { background: #FCFAF6; }
.af-cal__cell:hover { background: var(--af-bg); }

.af-cal__num {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--af-ink-2);
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}
.af-cal__cell--today .af-cal__num { background: var(--af-brand); color: var(--af-on-color); }

/* Bouton + d'ajout, visible au survol de la case */
.af-cal__add {
  position: absolute;
  top: 9px;
  right: 9px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--af-line);
  background: var(--af-surface);
  color: var(--af-ink-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity .1s ease, color .12s ease, border-color .12s ease;
}
.af-cal__cell:hover .af-cal__add { opacity: 1; }
.af-cal__add:hover { color: var(--af-action); border-color: var(--af-action); }

/* Chips d'événements dans une case */
.af-cal__events { display: flex; flex-direction: column; gap: 3px; margin-top: 2px; }
.af-evt {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 7px 3px 6px;
  border-radius: 5px;
  font-size: 11.5px;
  line-height: 1.3;
  color: var(--af-ink);
  background: var(--af-cat-1-soft);
  border-left: 3px solid var(--af-cat-1);
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.af-evt:hover { filter: brightness(0.97); }
.af-evt__time { font-family: var(--af-font-mono); font-size: 10.5px; color: var(--af-ink-3); flex-shrink: 0; }
.af-evt__label { overflow: hidden; text-overflow: ellipsis; }
.af-cal__more { font-size: 11px; color: var(--af-ink-3); font-weight: 500; padding: 1px 6px; cursor: pointer; }
.af-cal__more:hover { color: var(--af-action); }

/* Mapping catégorie → couleur (chips + dots de légende) */
.af-cat--1 { background: var(--af-cat-1-soft); border-left-color: var(--af-cat-1); }
.af-cat--2 { background: var(--af-cat-2-soft); border-left-color: var(--af-cat-2); }
.af-cat--3 { background: var(--af-cat-3-soft); border-left-color: var(--af-cat-3); }
.af-cat--4 { background: var(--af-cat-4-soft); border-left-color: var(--af-cat-4); }
.af-cat--5 { background: var(--af-cat-5-soft); border-left-color: var(--af-cat-5); }
.af-cat--6 { background: var(--af-cat-6-soft); border-left-color: var(--af-cat-6); }
.af-legend__dot.af-cat--1 { background: var(--af-cat-1); }
.af-legend__dot.af-cat--2 { background: var(--af-cat-2); }
.af-legend__dot.af-cat--3 { background: var(--af-cat-3); }
.af-legend__dot.af-cat--4 { background: var(--af-cat-4); }
.af-legend__dot.af-cat--5 { background: var(--af-cat-5); }
.af-legend__dot.af-cat--6 { background: var(--af-cat-6); }

/* ---- 25d. Vue SEMAINE — grille jours × heures (agenda vertical) ---- */
.af-week {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  overflow: hidden;
}
.af-week__head {
  display: grid;
  grid-template-columns: 64px repeat(5, 1fr);
  border-bottom: 1px solid var(--af-line);
  background: var(--af-surface-soft);
}
.af-week__corner { border-right: 1px solid var(--af-line-2); }
.af-week__day {
  padding: 9px 8px;
  text-align: center;
  border-left: 1px solid var(--af-line-2);
}
.af-week__day-name {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--af-ink-3);
}
.af-week__day-num {
  font-family: var(--af-font-serif);
  font-size: 18px;
  font-weight: 500;
  color: var(--af-ink);
  margin-top: 1px;
}
.af-week__day--today { background: var(--af-brand-soft); }
.af-week__day--today .af-week__day-num {
  color: var(--af-on-color);
  background: var(--af-brand);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.af-week__body { display: flex; }
.af-week__gutter { width: 64px; flex-shrink: 0; }
.af-week__hourlabel {
  height: 52px;
  position: relative;
  border-right: 1px solid var(--af-line-2);
}
.af-week__hourlabel span {
  position: absolute;
  top: -7px;
  right: 8px;
  font-family: var(--af-font-mono);
  font-size: 10.5px;
  color: var(--af-ink-3);
  background: var(--af-surface);
  padding: 0 2px;
}
.af-week__hourlabel:first-child span { top: 4px; }

.af-week__cols {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}
.af-week__col {
  position: relative;
  border-left: 1px solid var(--af-line-2);
  /* lignes horaires horizontales */
  background-image: repeating-linear-gradient(
    to bottom,
    var(--af-line-2) 0, var(--af-line-2) 1px,
    transparent 1px, transparent 52px
  );
}
.af-week__col--today { background-color: #FCF7F5; }
.af-week__col--weekend { background-color: var(--af-surface-soft); }

/* Bloc de cours (top/height posés inline en px) */
.af-week-evt {
  position: absolute;
  left: 4px;
  right: 4px;
  border-radius: 6px;
  padding: 5px 8px;
  background: var(--af-cat-1-soft);
  border-left: 3px solid var(--af-cat-1);
  box-shadow: var(--af-shadow-sm);
  cursor: pointer;
  overflow: hidden;
  transition: box-shadow .12s ease;
}
.af-week-evt:hover { box-shadow: var(--af-shadow-pop); z-index: 4; }
.af-week-evt__time {
  font-family: var(--af-font-mono);
  font-size: 10px;
  color: var(--af-ink-3);
}
.af-week-evt__title {
  font-size: 12px;
  font-weight: 600;
  color: var(--af-ink);
  line-height: 1.25;
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.af-week-evt__meta {
  font-size: 10.5px;
  color: var(--af-ink-2);
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Trait "maintenant" (dans la colonne du jour courant) */
.af-week__now {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--af-brand);
  z-index: 3;
  pointer-events: none;
}
.af-week__now::before {
  content: "";
  position: absolute;
  left: -4px;
  top: -4px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--af-brand);
}

/* ---- 25e. Responsive ---------------------------------------------- */
@media (max-width: 880px) {
  .af-plan-bar { gap: 10px; }
  .af-plan-bar__spacer { display: none; }
  .af-plan-filter { flex: 1; }
  .af-plan-filter .af-select { width: 100%; }
  .af-cal__cell { min-height: 88px; }
  .af-evt__time { display: none; }
}
@media (max-width: 560px) {
  .af-plan-nav__title { min-width: 120px; font-size: 16px; }
  .af-cal__dow { padding: 8px 6px; font-size: 10px; }
  .af-cal__cell { min-height: 64px; padding: 5px; }
}

/* =========================================================================
   SECTION 26 — Cycle de vie d'un cours
   Ajoutée le 31/05/2026.
   - .af-emarge     : statut d'émargement (5 états)
   - .af-scrim      : voile d'arrière-plan (drawer + modale)
   - .af-drawer     : panneau latéral droit (détail / formulaire de cours)
   - .af-dl         : liste descriptive (label + valeur) du détail
   - .af-emarge-card: bloc de pilotage de l'émargement dans le détail
   - .af-modal      : modale centrée (confirmation de suppression)
   - .af-callout    : encart d'avertissement contextuel
   ========================================================================= */

/* ---- 26a. Statut d'émargement (pill + point) ----------------------- */
.af-emarge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px 3px 8px;
  border-radius: var(--af-r-pill);
  font-size: 11.5px;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid transparent;
}
.af-emarge::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: currentColor;
}
.af-emarge--none      { background: var(--af-surface-mute); color: var(--af-ink-3); }
.af-emarge--prepared  { background: var(--af-info-soft);    color: var(--af-info-ink); }
.af-emarge--open      { background: var(--af-action-soft);  color: var(--af-action-hover); }
.af-emarge--done      { background: var(--af-success-soft); color: var(--af-success-ink); }
.af-emarge--incomplete{ background: var(--af-warn-soft);    color: var(--af-warn-ink); }

/* Variante point seul, pour poser sur un chip de cours */
.af-emarge-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 1.5px var(--af-surface);
}
.af-emarge-dot--none      { background: var(--af-ink-3); }
.af-emarge-dot--prepared  { background: var(--af-info); }
.af-emarge-dot--open      { background: var(--af-action); }
.af-emarge-dot--done      { background: var(--af-success); }
.af-emarge-dot--incomplete{ background: var(--af-warn); }

/* ---- 26b. Voile d'arrière-plan ------------------------------------- */
.af-scrim {
  position: fixed;
  inset: 0;
  background: rgba(26, 24, 22, 0.38);
  opacity: 0;
  visibility: hidden;
  transition: opacity .18s ease, visibility .18s ease;
  z-index: 40;
}
.af-scrim--open { opacity: 1; visibility: visible; }

/* ---- 26c. Drawer latéral ------------------------------------------- */
.af-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  max-width: 92vw;
  background: var(--af-surface);
  border-left: 1px solid var(--af-line);
  box-shadow: var(--af-shadow-pop);
  transform: translateX(100%);
  transition: transform .22s cubic-bezier(.4, 0, .2, 1);
  z-index: 41;
  display: flex;
  flex-direction: column;
}
.af-drawer--open { transform: translateX(0); }

/* Variante statique : pour présenter le drawer hors overlay (doc, comparaison) */
.af-drawer--static {
  position: relative;
  inset: auto;
  transform: none;
  width: 420px;
  max-width: none;
  height: 100%;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  box-shadow: var(--af-shadow-sm);
}

.af-drawer__head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 22px 16px;
  border-bottom: 1px solid var(--af-line);
}
.af-drawer__head-text { flex: 1; min-width: 0; }
.af-drawer__eyebrow {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  margin: 0 0 4px;
}
.af-drawer__title {
  font-family: var(--af-font-serif);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.2px;
  color: var(--af-ink);
  margin: 0;
  line-height: 1.2;
}
.af-drawer__close {
  width: 32px;
  height: 32px;
  border-radius: var(--af-r-md);
  border: 1px solid var(--af-line);
  background: var(--af-surface);
  color: var(--af-ink-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.af-drawer__close:hover { border-color: var(--af-ink-3); color: var(--af-ink); }

.af-drawer__body { flex: 1; overflow-y: auto; padding: 20px 22px; }
.af-drawer__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-top: 1px solid var(--af-line);
  background: var(--af-surface-soft);
}
.af-drawer__foot .af-drawer__foot-spacer { flex: 1; }

/* ---- 26d. Liste descriptive (détail) ------------------------------- */
.af-dl { display: flex; flex-direction: column; gap: 2px; margin: 0 0 20px; }
.af-dl__row {
  display: grid;
  grid-template-columns: 22px 110px 1fr;
  align-items: start;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--af-line-2);
}
.af-dl__row:last-child { border-bottom: 0; }
.af-dl__icon { color: var(--af-ink-3); display: flex; padding-top: 1px; }
.af-dl__key {
  font-size: 12.5px;
  color: var(--af-ink-3);
  padding-top: 1px;
}
.af-dl__val { font-size: 13.5px; color: var(--af-ink); font-weight: 500; }
.af-dl__val a { color: var(--af-action-hover); text-decoration: underline; }

/* ---- 26e. Carte d'émargement (pilotage dans le détail) ------------- */
.af-emarge-card {
  background: var(--af-bg);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  padding: 16px;
}
.af-emarge-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.af-emarge-card__label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--af-ink-2);
}
.af-emarge-card__hint { font-size: 12.5px; color: var(--af-ink-3); margin: 0 0 12px; line-height: 1.45; }
.af-emarge-card__bar { display: flex; gap: 8px; }

/* Mini-progress d'émargement (signatures) */
.af-emarge-prog {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 2px 0 12px;
}
.af-emarge-prog__track {
  flex: 1;
  height: 7px;
  background: var(--af-surface-mute);
  border-radius: 999px;
  overflow: hidden;
}
.af-emarge-prog__fill { height: 100%; border-radius: 999px; background: var(--af-success); }
.af-emarge-prog__num {
  font-family: var(--af-font-mono);
  font-size: 12px;
  color: var(--af-ink-2);
  font-weight: 500;
}

/* ---- 26f. Modale centrée (confirmation) ---------------------------- */
.af-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -46%);
  width: 440px;
  max-width: 92vw;
  background: var(--af-surface);
  border-radius: var(--af-r-xl);
  box-shadow: var(--af-shadow-pop);
  z-index: 42;
  opacity: 0;
  visibility: hidden;
  transition: opacity .16s ease, transform .16s ease, visibility .16s ease;
}
.af-modal--open { opacity: 1; visibility: visible; transform: translate(-50%, -50%); }
.af-modal__body { padding: 24px 24px 8px; }
.af-modal__icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--af-danger-soft);
  color: var(--af-danger);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
}
.af-modal__title {
  font-family: var(--af-font-serif);
  font-size: 20px;
  font-weight: 500;
  color: var(--af-ink);
  margin: 0 0 8px;
  line-height: 1.25;
}
.af-modal__text { font-size: 13.5px; color: var(--af-ink-2); line-height: 1.55; margin: 0; }
.af-modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 18px 24px 22px;
}

/* ---- 26g. Encart d'avertissement contextuel ----------------------- */
.af-callout {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--af-r-lg);
  font-size: 13px;
  line-height: 1.5;
  margin-top: 14px;
}
.af-callout svg { flex-shrink: 0; margin-top: 1px; }
.af-callout--warn { background: var(--af-warn-soft); color: var(--af-warn-ink); }
.af-callout--info { background: var(--af-info-soft); color: var(--af-info-ink); }
.af-callout strong { font-weight: 600; }

/* ---- 26h. Bouton plein danger (modale de suppression) -------------- */
.af-btn-danger-solid {
  background: var(--af-danger);
  color: var(--af-on-color);
  border: 0;
  padding: 9px 16px;
  border-radius: var(--af-r-lg);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.af-btn-danger-solid:hover { background: var(--af-danger-ink); }

@media (max-width: 560px) {
  .af-drawer { width: 100%; max-width: 100%; }
  .af-dl__row { grid-template-columns: 22px 96px 1fr; }
}

/* =========================================================================
   SECTION 27 — Déclinaison MOBILE (planning-mobile.html)
   Ajoutée le 31/05/2026. Composants préfixés .afm-* pour le shell mobile :
   barre de statut, en-tête, calendrier compact à points, agenda du jour,
   feuilles (bottom sheets), barre d'onglets basse, FAB.
   Conçus pour une largeur d'écran de 390px (cadre device).
   ========================================================================= */

.afm {
  width: 390px;
  height: 844px;
  background: var(--af-bg);
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  font-family: var(--af-font-sans);
  color: var(--af-ink);
}

/* ---- 27a. Barre de statut ----------------------------------------- */
.afm-status {
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 22px;
  font-size: 14px;
  font-weight: 600;
  color: var(--af-ink);
}
.afm-status__icons { display: flex; align-items: center; gap: 6px; }

/* ---- 27b. En-tête appli ------------------------------------------- */
.afm-head {
  flex-shrink: 0;
  padding: 6px 18px 12px;
  background: var(--af-surface);
  border-bottom: 1px solid var(--af-line);
}
.afm-head__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.afm-head__title {
  font-family: var(--af-font-serif);
  font-size: 24px;
  font-weight: 500;
  letter-spacing: -0.3px;
  margin: 0;
}
.afm-head__avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--af-brand);
  color: var(--af-on-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  flex-shrink: 0;
}
.afm-monthnav {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}
.afm-monthnav__btn {
  width: 30px;
  height: 30px;
  border-radius: var(--af-r-md);
  border: 1px solid var(--af-line);
  background: var(--af-surface);
  color: var(--af-ink-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.afm-monthnav__title {
  font-size: 15px;
  font-weight: 600;
  text-transform: capitalize;
  flex: 1;
}
.afm-modes {
  display: inline-flex;
  background: var(--af-bg);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  padding: 2px;
}
.afm-mode {
  padding: 5px 12px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--af-ink-3);
}
.afm-mode--active { background: var(--af-surface); color: var(--af-ink); box-shadow: var(--af-shadow-sm); }

/* ---- 27c. Corps défilant ------------------------------------------ */
.afm-scroll { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; }

/* ---- 27d. Calendrier compact (mois) ------------------------------- */
.afm-cal { padding: 10px 12px 4px; background: var(--af-surface); }
.afm-cal__dow-row,
.afm-cal__week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
.afm-cal__dow {
  text-align: center;
  font-family: var(--af-font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  padding: 4px 0 8px;
}
.afm-cal__cell {
  aspect-ratio: 1 / 1.05;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding-top: 5px;
  position: relative;
}
.afm-cal__num {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--af-ink);
}
.afm-cal__cell--out .afm-cal__num { color: var(--af-line); }
.afm-cal__cell--today .afm-cal__num { background: var(--af-brand); color: var(--af-on-color); font-weight: 600; }
.afm-cal__cell--sel .afm-cal__num { box-shadow: 0 0 0 1.5px var(--af-action); color: var(--af-action-hover); font-weight: 600; }
.afm-cal__cell--sel.afm-cal__cell--today .afm-cal__num { box-shadow: none; }
.afm-cal__dots { display: flex; gap: 3px; height: 6px; }
.afm-cal__dot { width: 6px; height: 6px; border-radius: 50%; }
.afm-cal__dot--1 { background: var(--af-cat-1); }
.afm-cal__dot--2 { background: var(--af-cat-2); }
.afm-cal__dot--3 { background: var(--af-cat-3); }
.afm-cal__dot--4 { background: var(--af-cat-4); }
.afm-cal__dot--5 { background: var(--af-cat-5); }

/* ---- 27e. Agenda du jour sélectionné ------------------------------ */
.afm-agenda { padding: 8px 16px 16px; }
.afm-agenda__date {
  position: sticky;
  top: 0;
  background: var(--af-bg);
  padding: 14px 2px 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--af-ink-2);
  text-transform: capitalize;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.afm-agenda__date small { font-weight: 500; color: var(--af-ink-3); font-size: 12px; }

.afm-course {
  display: flex;
  gap: 12px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  padding: 12px 14px;
  margin-bottom: 10px;
  position: relative;
}
.afm-course__stripe {
  position: absolute;
  left: 0; top: 10px; bottom: 10px;
  width: 4px;
  border-radius: 0 3px 3px 0;
}
.afm-course__stripe--1 { background: var(--af-cat-1); }
.afm-course__stripe--2 { background: var(--af-cat-2); }
.afm-course__stripe--3 { background: var(--af-cat-3); }
.afm-course__stripe--4 { background: var(--af-cat-4); }
.afm-course__stripe--5 { background: var(--af-cat-5); }
.afm-course__time {
  font-family: var(--af-font-mono);
  font-size: 11.5px;
  color: var(--af-ink-3);
  width: 46px;
  flex-shrink: 0;
  padding-left: 8px;
  padding-top: 1px;
  line-height: 1.5;
}
.afm-course__body { flex: 1; min-width: 0; }
.afm-course__title { font-size: 14.5px; font-weight: 600; margin: 0 0 2px; }
.afm-course__sub { font-size: 12.5px; color: var(--af-ink-3); margin: 0 0 8px; }
.afm-course__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.afm-course__chev { color: var(--af-ink-3); flex-shrink: 0; }
.afm-day-empty { text-align: center; color: var(--af-ink-3); font-size: 13px; padding: 30px 12px; }

/* ---- 27f. Barre d'onglets basse ----------------------------------- */
.afm-tabbar {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  border-top: 1px solid var(--af-line);
  background: var(--af-surface);
  padding-bottom: 18px; /* safe area */
}
.afm-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 0 4px;
  font-size: 10px;
  color: var(--af-ink-3);
  background: none;
  border: 0;
}
.afm-tab--active { color: var(--af-brand); }

/* ---- 27g. FAB ----------------------------------------------------- */
.afm-fab {
  position: absolute;
  right: 16px;
  bottom: 86px;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--af-action);
  color: var(--af-on-color);
  border: 0;
  box-shadow: var(--af-shadow-cta);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  z-index: 5;
}

/* ---- 27h. Bottom sheet (détail / formulaire) ---------------------- */
.afm-sheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 92%;
  background: var(--af-surface);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -10px 30px -12px rgba(0,0,0,0.25);
  display: flex;
  flex-direction: column;
  z-index: 10;
}
.afm-sheet__handle {
  width: 38px; height: 4px;
  background: var(--af-line);
  border-radius: 999px;
  margin: 8px auto 2px;
  flex-shrink: 0;
}
.afm-sheet__head {
  padding: 8px 18px 14px;
  border-bottom: 1px solid var(--af-line);
}
.afm-sheet__eyebrow {
  font-family: var(--af-font-mono);
  font-size: 10.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  margin: 0 0 3px;
}
.afm-sheet__title {
  font-family: var(--af-font-serif);
  font-size: 21px;
  font-weight: 500;
  margin: 0;
  line-height: 1.2;
}
.afm-sheet__body { padding: 16px 18px; overflow-y: auto; flex: 1; }
.afm-sheet__foot {
  display: flex;
  gap: 10px;
  padding: 12px 18px 22px;
  border-top: 1px solid var(--af-line);
  background: var(--af-surface-soft);
}
.afm-sheet__foot .af-btn-primary,
.afm-sheet__foot .af-btn-ghost { flex: 1; justify-content: center; }

/* Scrim interne au cadre device */
.afm-scrim {
  position: absolute;
  inset: 0;
  background: rgba(26,24,22,0.4);
  z-index: 9;
}

/* Réutilise .af-dl / .af-emarge-card dans la sheet, juste un peu d'air */
.afm-sheet__body .af-emarge-card { margin-top: 4px; }

/* Légende mobile compacte */
.afm-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding: 10px 16px 12px;
  font-size: 11.5px;
  color: var(--af-ink-2);
  background: var(--af-surface);
  border-bottom: 1px solid var(--af-line);
}
.afm-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.afm-legend__dot { width: 9px; height: 9px; border-radius: 3px; }

/* =========================================================================
   SECTION 28 — Cas limites & machine d'états (V3 — 31/05/2026)
   Complète le cycle de vie : état d'émargement « régularisé », conflit
   horaire, suppression bloquée, états statiques pour la doc.

   Machine d'états d'émargement (MVP) :
     none → prepared → open → closed_complete (done)
                            → closed_incomplete (incomplete) → regularized
   ========================================================================= */

/* ---- 28a. Émargement régularisé ----------------------------------- */
/* Vert (succès) car la feuille est complète, MAIS libellé distinct pour
   garder la trace métier : une feuille régularisée ≠ complète d'emblée. */
.af-emarge--regularized { background: var(--af-success-soft); color: var(--af-success-ink); }
.af-emarge-dot--regularized { background: var(--af-success); }

/* ---- 28b. Variantes d'icône de modale ----------------------------- */
.af-modal { padding: 0; }                 /* annule le padding hérité de la base */
.af-modal--start { text-align: left; }
.af-modal--wide { width: 480px; }
.af-modal__icon--warn  { background: var(--af-warn-soft);    color: var(--af-warn); }
.af-modal__icon--block { background: var(--af-surface-mute); color: var(--af-ink-2); }
.af-modal__foot--spread { justify-content: space-between; }
.af-modal__foot--stack { flex-direction: column; align-items: stretch; gap: 8px; }
.af-modal__foot--stack .af-btn-ghost,
.af-modal__foot--stack .af-btn-primary,
.af-modal__foot--stack .af-btn-secondary,
.af-modal__foot--stack .af-btn-danger-solid { justify-content: center; }

/* Affichage statique d'une modale (doc / galerie d'états) */
.af-modal--static {
  position: static;
  inset: auto;
  transform: none;
  opacity: 1;
  visibility: visible;
  width: 100%;
  max-width: 460px;
}

/* ---- 28c. Carte de conflit (créneau déjà occupé) ------------------ */
.af-conflict {
  display: flex;
  gap: 12px;
  align-items: stretch;
  background: var(--af-bg);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  padding: 12px 14px;
  margin-top: 14px;
  text-align: left;
}
.af-conflict__stripe { width: 4px; border-radius: 3px; flex-shrink: 0; background: var(--af-cat-1); }
.af-conflict__body { min-width: 0; }
.af-conflict__title { font-size: 14px; font-weight: 600; margin: 0; color: var(--af-ink); }
.af-conflict__meta {
  font-family: var(--af-font-mono);
  font-size: 11.5px;
  color: var(--af-ink-3);
  margin: 3px 0 0;
}
.af-conflict__tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  color: var(--af-warn-ink);
  margin-bottom: 2px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* ---- 28d. Toast de confirmation (réutilise .af-flash, positionné) -- */
.af-toast {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--af-ink);
  color: #F3F0EA;
  padding: 12px 16px 12px 14px;
  border-radius: var(--af-r-lg);
  box-shadow: var(--af-shadow-pop);
  font-size: 13.5px;
  z-index: 60;
  max-width: 440px;
}
.af-toast__icon {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--af-action);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.af-toast--static { position: static; transform: none; }

/* ---- 28e. Tuiles de galerie d'états (planning-edge-cases.html) ----- */
.afx { padding: 32px 28px 60px; max-width: 1100px; margin: 0 auto; }
.afx__intro { max-width: 760px; margin-bottom: 28px; }
.afx__machine {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-family: var(--af-font-mono);
  font-size: 12px;
  color: var(--af-ink-2);
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  padding: 14px 16px;
  margin-top: 16px;
}
.afx__node {
  padding: 4px 10px;
  border-radius: var(--af-r-pill);
  background: var(--af-surface-mute);
  color: var(--af-ink);
}
.afx__arrow { color: var(--af-ink-3); }
.afx__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
  gap: 22px;
}
.afx__tile {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.afx__cap {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--af-ink);
}
.afx__cap b {
  font-family: var(--af-font-mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--af-ink-3);
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: 999px;
  padding: 2px 8px;
}
.afx__cap-sub { font-size: 12.5px; color: var(--af-ink-3); font-weight: 400; margin-left: 2px; }
/* Plateau qui met en scène une modale (scrim figé) */
.afx__stage {
  background:
    repeating-linear-gradient(45deg, transparent 0 9px, rgba(26,24,22,0.025) 9px 10px),
    rgba(26,24,22,0.06);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 26px;
  display: flex;
  justify-content: center;
}

@media (max-width: 560px) {
  .af-modal--wide { width: 100%; }
}


/* =========================================================================
   SECTION 29 — Pages 404 (easter eggs) & Statesbook (revue interne)
   Rapatriées depuis l'ancien styles.css pour unifier en une seule feuille.
   Non essentielles à l'app ; conservées pour les pages d'erreur et la revue.
   ========================================================================= */

/* ---------- 18c. Page 404 -------------------------------------------- */
.af-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--af-bg);
}
.af-shell__top {
  display: flex;
  align-items: center;
  padding: 18px 32px;
  border-bottom: 1px solid var(--af-line);
  background: var(--af-surface);
}
.af-shell__top .af-brand { border: 0; padding: 0; }
.af-shell__top__right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.af-shell__main {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 48px 24px;
}

.af-404 {
  max-width: 760px;
  width: 100%;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}
.af-404__eyebrow {
  font-size: 12px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--af-danger);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.af-404__eyebrow::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--af-danger);
  box-shadow: 0 0 0 4px var(--af-danger-soft);
  animation: af-pulse 1.6s ease-in-out infinite;
}
@keyframes af-pulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--af-danger-soft); }
  50%      { box-shadow: 0 0 0 7px transparent; }
}

.af-404__title {
  font-family: var(--af-font-serif);
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 500;
  letter-spacing: -0.6px;
  margin: 0;
  color: var(--af-ink);
}
.af-404__title em { font-style: italic; color: var(--af-action); font-weight: 500; }

.af-404__sub {
  font-size: 15.5px;
  color: var(--af-ink-2);
  max-width: 520px;
  margin: 0;
  line-height: 1.55;
}

.af-404__diag {
  width: 100%;
  max-width: 560px;
  text-align: left;
  background: var(--af-ink);
  color: #E4E0D9;
  font-family: var(--af-font-mono);
  font-size: 12.5px;
  line-height: 1.7;
  padding: 16px 18px;
  border-radius: var(--af-r-lg);
  margin-top: 6px;
}
.af-404__diag-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #A8A096;
  margin-bottom: 8px;
}
.af-404__diag-head::before {
  content: '';
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--af-danger);
}
.af-404__diag-line { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.af-404__diag-key { color: #807A72; }
.af-404__diag-val { color: #E4E0D9; }
.af-404__diag-val--err { color: #F0B27A; }
.af-404__diag-val--ok  { color: #7FC8B5; }

.af-404__actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 4px;
}

.af-404__easter {
  margin-top: 18px;
  font-size: 12.5px;
  color: var(--af-ink-3);
}
.af-404__easter strong { color: var(--af-ink-2); font-weight: 500; }
.af-404__counter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px 3px 8px;
  border-radius: var(--af-r-pill);
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  font-family: var(--af-font-mono);
  font-size: 12px;
  color: var(--af-ink);
}

.af-404__switcher {
  font-size: 12.5px;
  color: var(--af-ink-3);
}
.af-404__switcher a {
  color: var(--af-action);
  font-weight: 500;
}
.af-404__switcher a:hover { text-decoration: underline; }

/* ---- 18c-0. Page 404 immersive : image hero + overlays HTML par-dessus ---- */
.af-404-immersive {
  margin: 0;
  background: #0A1424;
  color: #FFFFFF;
  font-family: var(--af-font-sans);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.af-immersive {
  position: relative;
  flex: 1;
  width: 100%;
  background-image: url('img/404-astronaut.png');
  background-size: cover;
  background-position: center;
  background-color: #0A1424;
  overflow: hidden;
  min-height: 100vh;
}

/* Top bar — par-dessus l'image, discret */
.af-immersive__top {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 32px;
  color: #FFFFFF;
}
.af-immersive__top .af-brand { border: 0; padding: 0; }
.af-immersive__top .af-brand__word,
.af-immersive__top .af-brand__mark { color: #FFFFFF; }
.af-immersive__top .af-404__switcher { margin: 0; color: rgba(255, 255, 255, 0.7); }
.af-immersive__top .af-404__switcher a { color: #FFFFFF; }

/* 404 géant en haut-gauche */
.af-immersive__digits {
  position: absolute;
  top: 8%;
  left: 5%;
  z-index: 4;
  font-family: 'Caveat', cursive, var(--af-font-serif);
  font-weight: 700;
  font-size: clamp(96px, 13vw, 200px);
  line-height: 0.85;
  margin: 0;
  letter-spacing: 4px;
  color: #FFFFFF;
  text-shadow: 6px 6px 0 #E84A2C, 0 0 30px rgba(0, 0, 0, 0.5);
}
.af-immersive__catch {
  /* Bulle de BD positionnée au-dessus de la tête de l'astronaute, pointant vers sa bouche */
  position: absolute;
  top: 14%;
  right: calc(28% + 200px);
  z-index: 4;
  display: inline-block;
  font-family: 'Caveat', cursive, var(--af-font-serif);
  font-weight: 700;
  font-size: clamp(24px, 2.6vw, 42px);
  line-height: 1.05;
  margin: 0;
  padding: 16px 26px 18px;
  color: #1A1816;
  background: #FFFFFF;
  border: 3px solid #1A1816;
  border-radius: 28px;
  box-shadow: 5px 5px 0 #1A1816;
  max-width: 28%;
  text-shadow: none;
  text-align: center;
}
/* Queue courbe SVG : sort de la bulle pour aller vers la bouche de l'astronaute */
.af-immersive__catch__tail {
  position: absolute;
  right: -260px;
  bottom: -170px;
  width: 260px;
  height: 170px;
  overflow: visible;
  pointer-events: none;
  z-index: 2;
}
/* Anciennes pointes en pseudo-éléments désactivées */
.af-immersive__catch::before,
.af-immersive__catch::after { content: none; display: none; }
.af-immersive__catch em {
  color: #C0392B;
  font-style: normal;
  display: inline-block;
  text-shadow: none;
}

/* Bloc bas : sous-titre + CTA. Posé sur la combinaison blanche, contrasté en sombre. */
.af-immersive__bottom {
  position: absolute;
  bottom: 4%;
  left: 50%;
  transform: translateX(-50%);
  width: 90%;
  max-width: 620px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  text-align: center;
}
.af-immersive__sub {
  font-family: 'Caveat', cursive, var(--af-font-serif);
  font-weight: 700;
  font-size: clamp(22px, 2.8vw, 40px);
  line-height: 1.2;
  color: #0A0A0A;
  margin: 0;
  /* Halo blanc pour rester lisible même sur les plis/ombres de la combinaison */
  text-shadow:
    0 0 12px rgba(255, 255, 255, 0.95),
    0 0 24px rgba(255, 255, 255, 0.85),
    0 0 4px rgba(255, 255, 255, 0.9);
  padding: 4px 10px;
}
.af-immersive__sub strong {
  color: #C0392B;
  font-weight: 700;
  display: inline-block;
  border-bottom: 3px solid #C0392B;
  padding-bottom: 1px;
  text-shadow:
    0 0 12px rgba(255, 255, 255, 0.95),
    0 0 4px rgba(255, 255, 255, 0.9);
}

/* ---- Panneau d'alerte style station spatiale ---- */
.af-alert {
  position: relative;
  width: 100%;
  max-width: 560px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent 50%),
    #14182B;
  border: 1.5px solid #C0392B;
  border-radius: 10px;
  padding: 14px 22px 16px;
  font-family: 'Geist Mono', ui-monospace, monospace;
  color: #E4E0D9;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.05),
    inset 0 0 30px rgba(192, 57, 43, 0.12),
    0 0 0 1px rgba(0, 0, 0, 0.4),
    0 0 28px rgba(192, 57, 43, 0.5),
    0 0 70px rgba(192, 57, 43, 0.18);
  text-align: left;
  animation: af-alert-glow 2.4s ease-in-out infinite;
}
@keyframes af-alert-glow {
  0%, 100% {
    box-shadow:
      inset 0 0 0 1px rgba(255, 255, 255, 0.05),
      inset 0 0 30px rgba(192, 57, 43, 0.12),
      0 0 0 1px rgba(0, 0, 0, 0.4),
      0 0 28px rgba(192, 57, 43, 0.5),
      0 0 70px rgba(192, 57, 43, 0.18);
  }
  50% {
    box-shadow:
      inset 0 0 0 1px rgba(255, 255, 255, 0.05),
      inset 0 0 30px rgba(192, 57, 43, 0.18),
      0 0 0 1px rgba(0, 0, 0, 0.4),
      0 0 36px rgba(192, 57, 43, 0.65),
      0 0 90px rgba(192, 57, 43, 0.28);
  }
}
/* Petits rivets métalliques aux 4 coins */
.af-alert::before,
.af-alert::after {
  content: '';
  position: absolute;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #BAB1A2 0%, #5A5550 60%, #2A2826 100%);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), inset 0 0 0 0.5px rgba(255, 255, 255, 0.2);
  z-index: 2;
}
.af-alert::before { top: 8px; left: 8px; }
.af-alert::after  { top: 8px; right: 8px; }

.af-alert__head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 10.5px;
  letter-spacing: 2.4px;
  font-weight: 700;
  text-transform: uppercase;
  color: #FF8A6B;
  border-bottom: 1px dashed rgba(255, 138, 107, 0.28);
  padding: 0 18px 9px;
  margin: 0 -10px 10px;
}
.af-alert__led {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #FF3826;
  box-shadow:
    0 0 0 1.5px rgba(255, 56, 38, 0.25),
    0 0 7px #FF3826,
    0 0 14px rgba(255, 56, 38, 0.65);
  animation: af-led-blink 1.1s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes af-led-blink {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.82); }
}
.af-alert__label { flex: 1; white-space: nowrap; }
.af-alert__code {
  font-size: 9.5px;
  color: rgba(228, 224, 217, 0.55);
  letter-spacing: 1.5px;
}
.af-alert__msg {
  font-family: 'Geist Mono', monospace;
  font-size: clamp(13.5px, 1.3vw, 16px);
  line-height: 1.55;
  color: #E4E0D9;
  margin: 0;
}
.af-alert__msg strong {
  color: #FF8A6B;
  font-weight: 700;
  background: rgba(255, 138, 107, 0.14);
  padding: 0 4px;
  border-radius: 3px;
  border-bottom: 0;
  text-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  .af-alert, .af-alert__led { animation: none; }
}
.af-immersive__cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 14px 30px;
  background: linear-gradient(180deg, #F26344 0%, #E84A2C 100%);
  color: #FFFFFF;
  border: 0;
  border-radius: var(--af-r-pill);
  font-family: var(--af-font-sans);
  font-size: clamp(13px, 1.3vw, 17px);
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  box-shadow:
    0 6px 0 #B23A22,
    0 14px 28px -8px rgba(184, 58, 34, 0.55),
    inset 0 2px 0 rgba(255, 255, 255, 0.25);
  cursor: pointer;
  white-space: nowrap;
  transition: transform .12s ease, filter .12s ease;
  text-decoration: none;
}
.af-immersive__cta:hover { filter: brightness(1.05); transform: translateY(-1px); }
.af-immersive__cta:active {
  transform: translateY(3px);
  box-shadow: 0 3px 0 #B23A22, 0 6px 14px -6px rgba(184, 58, 34, 0.5);
}
.af-immersive__cta-icon { font-size: 1.2em; line-height: 1; }

/* (Plus de bloc diagnostic — voir 404.html pour la décision éditoriale) */
.af-immersive__diag a { color: rgba(255, 255, 255, 0.85); text-decoration: underline; }

/* Lien Signaler la panne — bouton fantôme blanc */
.af-immersive__ghost {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 18px;
  background: rgba(255, 255, 255, 0.9);
  color: #1A1816;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: var(--af-r-pill);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color .12s ease;
}
.af-immersive__ghost:hover { background: #FFFFFF; }

.af-immersive__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}

/* Responsive : sur petits écrans, on recentre tout, on ajuste l'image */
@media (max-width: 720px) {
  .af-immersive { background-position: 70% center; }
  .af-immersive__digits { top: 4%; left: 4%; font-size: clamp(72px, 22vw, 130px); }
  .af-immersive__catch {
    top: auto; right: auto;
    left: 50%; transform: translateX(-50%);
    bottom: 28%;
    max-width: 80%;
    font-size: 22px;
  }
  .af-immersive__bottom { width: 92%; bottom: 5%; }
}

/* ---- 18c-1. Illustration "Peugeot 404 en panne" ------------------- */
.af-scene { width: 100%; max-width: 540px; position: relative; }
.af-scene > svg { width: 100%; height: auto; display: block; }
.af-scene svg.af-scene__triangle {
  position: absolute;
  bottom: 4%;
  right: 4%;
  width: 13%;
  height: auto;
  animation: af-wobble 2.4s ease-in-out infinite;
  transform-origin: bottom center;
}
@keyframes af-wobble {
  0%, 100% { transform: rotate(-3deg); }
  50%      { transform: rotate(3deg); }
}
.af-smoke__puff {
  animation: af-smoke-rise 3.4s ease-out infinite;
  transform-origin: center;
}
.af-smoke__puff--2 { animation-delay: 0.8s; }
.af-smoke__puff--3 { animation-delay: 1.6s; }
@keyframes af-smoke-rise {
  0%   { transform: translate(0, 0) scale(0.5); opacity: 0; }
  15%  { opacity: 0.85; }
  100% { transform: translate(-22px, -56px) scale(1.4); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .af-scene__triangle, .af-smoke__puff { animation: none; }
}

/* ---- 18c-2. Illustration "Transmission Apollo" (close-up astronaute) ---- */
.af-porthole {
  width: clamp(260px, 42vw, 400px);
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 28%, #1A2A3F 0%, #0A1424 65%, #03060F 100%);
  position: relative;
  overflow: hidden;
  box-shadow:
    inset 0 0 0 6px #2A2A2A,
    inset 0 0 0 12px #BAB1A2,
    inset 0 0 0 14px #2A2A2A,
    0 18px 40px -16px rgba(0, 0, 0, 0.35);
}
.af-portrait {
  position: absolute;
  inset: 14px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  background: radial-gradient(circle at 50% 40%, #25364D 0%, #0E1A2B 70%, #060B16 100%);
}
.af-portrait__svg {
  width: 90%;
  height: auto;
  display: block;
  margin-bottom: -3%;
}
.af-portrait__scanlines {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0 3px,
    rgba(0, 0, 0, 0.18) 3px 4px
  );
  pointer-events: none;
  mix-blend-mode: multiply;
}
.af-portrait__vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at center, transparent 55%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}
.af-portrait__live {
  position: absolute;
  top: 9%;
  left: 11%;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  background: rgba(192, 57, 43, 0.92);
  color: #fff;
  font-family: var(--af-font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  border-radius: 3px;
}
.af-portrait__live::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  animation: af-live-blink 1.2s ease-in-out infinite;
}
@keyframes af-live-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}
.af-portrait__timer {
  position: absolute;
  top: 10%;
  right: 11%;
  z-index: 4;
  font-family: var(--af-font-mono);
  font-size: 10.5px;
  color: rgba(230, 224, 214, 0.85);
  letter-spacing: 0.5px;
}

/* Jauge O₂ dans le hublot */
.af-o2 {
  position: absolute;
  left: 50%;
  bottom: 14%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: rgba(15, 18, 30, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--af-r-pill);
  color: #E4E0D9;
  font-family: var(--af-font-mono);
  font-size: 10.5px;
  font-weight: 500;
  backdrop-filter: blur(2px);
}
.af-o2__label { color: #8BB7C5; letter-spacing: 0.5px; }
.af-o2__bar {
  width: 56px;
  height: 5px;
  border-radius: var(--af-r-pill);
  background: rgba(255, 255, 255, 0.15);
  overflow: hidden;
}
.af-o2__fill {
  display: block;
  height: 100%;
  width: 12%;
  background: var(--af-danger);
  animation: af-o2-blink 1.4s ease-in-out infinite;
}
.af-o2__value { color: var(--af-danger); }
@keyframes af-o2-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .af-o2__fill { animation: none; }
}


/* ---- 21g. Statesbook (page interne de revue) --------------------- */
.af-statesbook { padding: 32px 40px; max-width: 1240px; margin: 0 auto; }
.af-statesbook__state {
  margin-bottom: 40px;
  padding-bottom: 40px;
  border-bottom: 1px dashed var(--af-line);
}
.af-statesbook__state:last-child { border-bottom: 0; }
.af-statesbook__label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  font-weight: 600;
  color: var(--af-ink-3);
  margin: 0 0 4px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.af-statesbook__label::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--af-line-2);
}
.af-statesbook__heading {
  font-family: var(--af-font-serif);
  font-size: 24px;
  font-weight: 500;
  margin: 4px 0 6px;
  letter-spacing: -0.3px;
}
.af-statesbook__caption {
  color: var(--af-ink-3);
  font-size: 13.5px;
  margin: 0 0 22px;
  max-width: 640px;
}


/* =========================================================================
   SECTION 30 — Feuille d'émargement (class-attendance.html)
   Ajoutée le 02/06/2026. Redessine l'écran "Émargement" d'un créneau :
   bandeau de synthèse + progression, filtres, table compacte 1 ligne/étudiant
   avec UNE action contextuelle (Régulariser / Réinitialiser) qui déplie un
   éditeur en ligne pour le motif (au lieu de champs tronqués permanents).
   ========================================================================= */

/* ---- 30a. Bandeau de synthèse ------------------------------------- */
.af-att-summary {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 28px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  padding: 20px 24px;
  margin-bottom: 16px;
}
.af-att-summary__count { display: flex; align-items: baseline; gap: 4px; }
.af-att-summary__big {
  font-family: var(--af-font-serif);
  font-size: 38px;
  font-weight: 500;
  line-height: 1;
  color: var(--af-ink);
  letter-spacing: -1px;
}
.af-att-summary__total { font-size: 19px; color: var(--af-ink-3); font-weight: 500; }
.af-att-summary__label {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--af-ink-3);
  margin-top: 6px;
}
.af-att-summary__mid { min-width: 0; }
.af-att-prog {
  height: 8px;
  background: var(--af-surface-mute);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 10px;
}
.af-att-prog__fill { height: 100%; border-radius: 999px; background: var(--af-warn); }
.af-att-breakdown { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.af-att-stat { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--af-ink-2); }
.af-att-stat__dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.af-att-stat__dot--present { background: var(--af-success); }
.af-att-stat__dot--absent  { background: var(--af-danger); }
.af-att-stat__dot--late    { background: var(--af-warn); }
.af-att-stat__dot--missing { background: var(--af-ink-3); }
.af-att-stat b { color: var(--af-ink); font-weight: 600; }
.af-att-summary__side { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }

/* ---- 30b. Barre d'actions / filtres ------------------------------- */
.af-att-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.af-att-bar__spacer { flex: 1; }
.af-att-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  padding: 8px 12px;
  color: var(--af-ink-3);
  min-width: 220px;
}
.af-att-search input { border: 0; background: transparent; outline: none; font-size: 13.5px; color: var(--af-ink); width: 100%; font-family: inherit; }

/* ---- 30c. Table émargement ---------------------------------------- */
/* Étudiant | Statut | Signature | Heure | Actions */
.af-row--att { grid-template-columns: 1.7fr 150px 150px 96px 210px; align-items: center; }
.af-row--att .af-row__actions { justify-content: flex-end; }

.af-att-who { display: inline-flex; align-items: center; gap: 12px; min-width: 0; }
.af-att-who__name { font-weight: 600; color: var(--af-ink); }
.af-att-who__name span { font-weight: 400; color: var(--af-ink-2); }

/* Vignette de signature */
.af-att-sig {
  height: 40px;
  width: 116px;
  border-radius: var(--af-r-sm);
  background: var(--af-surface-soft);
  border: 1px solid var(--af-line-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--af-ink);
}
.af-att-sig svg { width: 92px; height: 32px; }
.af-att-sig img { max-width: 92px; max-height: 32px; object-fit: contain; }
.af-att-sig--empty { border-style: dashed; color: var(--af-ink-3); font-size: 12px; }

.af-att-time { display: inline-flex; flex-direction: column; gap: 2px; font-family: var(--af-font-mono); font-size: 13px; color: var(--af-ink); }
.af-att-time__lock { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; color: var(--af-warn-ink); }
.af-att-time--empty { color: var(--af-ink-3); }

/* Action contextuelle compacte (réinit = danger ghost ; régul = secondary) */
.af-att-act { display: inline-flex; align-items: center; gap: 4px; }

/* ---- 30d. Éditeur en ligne (motif) -------------------------------- */
.af-att-edit {
  grid-column: 1 / -1;
  background: var(--af-bg);
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-md);
  padding: 14px 16px;
  margin-top: 10px;
  display: none; /* masqué par défaut, révélé via .af-row--editing */
  grid-template-columns: auto 1fr auto;
  align-items: end;
  gap: 14px;
}
.af-att-edit__title {
  grid-column: 1 / -1;
  font-size: 13px;
  font-weight: 600;
  color: var(--af-ink);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
}
.af-att-edit__field { display: flex; flex-direction: column; gap: 5px; }
.af-att-edit__field .af-label { margin: 0; }
.af-att-edit__field .af-select { min-width: 150px; }
.af-att-edit__field--grow { flex: 1; }
.af-att-edit__actions { display: flex; gap: 8px; }
/* La ligne dépliée (mise en avant) */
.af-row--att.af-row--editing { background: var(--af-surface-soft); }
.af-row--editing .af-att-edit { display: grid; }

@media (max-width: 1080px) {
  .af-row--att { grid-template-columns: 1.4fr 120px 90px 150px; }
  .af-row--att .af-att-sig, .af-row--att .af-att-col-sig { display: none; }
  .af-att-summary { grid-template-columns: auto 1fr; }
  .af-att-summary__side { grid-column: 1 / -1; flex-direction: row; align-items: center; justify-content: space-between; }
}
@media (max-width: 720px) {
  .af-att-edit { grid-template-columns: 1fr; align-items: stretch; }
  .af-att-edit__actions { justify-content: flex-end; }
}
/* ============================================================
   LOGIN — page de connexion. Hero de présentation (gauche)
   + panneau de connexion (droite). Reconstruit sur tokens --af-*.
   ============================================================ */
.af-login-page { margin:0; min-height:100vh; background:var(--af-bg); font-family:var(--af-font-sans); color:var(--af-ink); display:flex; align-items:center; justify-content:center; padding:24px; }
.af-login { width:100%; max-width:940px; display:grid; grid-template-columns:1.05fr 0.95fr; background:var(--af-surface); border:1px solid var(--af-line); border-radius:var(--af-r-xl); box-shadow:var(--af-shadow-pop); overflow:hidden; }

/* Hero (gauche) */
.af-login__hero { background:var(--af-brand-soft); color:var(--af-brand-ink); padding:40px 36px; display:flex; flex-direction:column; gap:16px; }
.af-login__brand { display:inline-flex; align-items:center; gap:10px; color:var(--af-brand-ink); }
.af-login__mark { display:inline-flex; }
.af-login__word { font-size:20px; font-weight:600; }
.af-login__word b { font-weight:700; }
.af-login__eyebrow { margin:8px 0 0; font-size:12px; letter-spacing:.08em; text-transform:uppercase; color:var(--af-ink-3); }
.af-login__title { margin:0; font-family:var(--af-font-serif); font-size:30px; line-height:1.15; font-weight:600; }
.af-login__intro { margin:0; color:var(--af-ink-2); font-size:14px; line-height:1.55; }
.af-login__features { display:flex; flex-wrap:wrap; gap:8px; margin-top:auto; }
.af-login__features span { font-size:12px; font-weight:500; padding:5px 11px; background:var(--af-surface); color:var(--af-ink-2); border:1px solid var(--af-line); border-radius:var(--af-r-pill); }

/* Panneau de connexion (droite) */
.af-login__panel { padding:36px 34px; display:flex; flex-direction:column; gap:18px; }
.af-login__lang { display:flex; justify-content:flex-end; gap:10px; font-size:13px; }
.af-login__lang-current { font-weight:600; color:var(--af-ink); }
.af-login__lang-link { color:var(--af-ink-3); text-decoration:none; }
.af-login__lang-link:hover { color:var(--af-action); text-decoration:underline; }
.af-login__panel-head { display:flex; flex-direction:column; gap:4px; }
.af-login__panel-kicker { margin:0; font-size:12px; letter-spacing:.08em; text-transform:uppercase; color:var(--af-action); }
.af-login__panel-title { margin:0; font-family:var(--af-font-serif); font-size:24px; font-weight:600; }
.af-login__panel-sub { margin:0; color:var(--af-ink-2); font-size:14px; }
.af-login__alert { display:flex; align-items:flex-start; gap:10px; background:var(--af-danger-soft); color:var(--af-danger-ink); border:1px solid var(--af-danger); border-radius:var(--af-r-md); padding:10px 12px; font-size:14px; }
.af-login__alert span { font-weight:700; }
.af-login__alert p { margin:0; }
.af-login__form { display:flex; flex-direction:column; gap:14px; }
.af-login__input { width:100%; }
.af-login__submit { margin-top:4px; width:100%; display:inline-flex; align-items:center; justify-content:center; gap:8px; }
.af-login__note { margin:0; font-size:12px; color:var(--af-ink-3); }

/* Responsive : empilement */
@media (max-width:760px) {
  .af-login { grid-template-columns:1fr; max-width:460px; }
  .af-login__hero { padding:28px 26px; }
  .af-login__features { margin-top:8px; }
}

/* =========================================================================
   CLEANUP v149 — éléments replacés après la base
   -------------------------------------------------------------------------
   - les correctifs anciennement collés avant les tokens ont été déplacés
   - le doublon exact .af-account-grid a été supprimé
   - les surcharges intentionnelles restent en fin de fichier
   ========================================================================= */

/* ---- Page « Mon compte / Ma signature » ---- */
.af-account-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 900px) { .af-account-grid { grid-template-columns: 1fr; } }

/* ---- Alertes émargement — compléments visuels conservés ---- */
/* --- Topbar : pastille d'alerte globale ------------------------------- */
.af-top__right .af-att-alert-badge {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center;
  gap: 8px !important;
  min-height: 32px;
  padding: 6px 10px !important;
  border-radius: var(--af-r-pill);
  background: var(--af-danger-soft);
  border: 1px solid rgba(192, 57, 43, 0.28);
  color: var(--af-danger-ink);
  font-size: 12.5px;
  line-height: 1;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  flex: 0 0 auto;
}
.af-top__right .af-att-alert-badge:hover {
  background: #fff4f4;
  border-color: rgba(192, 57, 43, 0.42);
  color: var(--af-danger-ink);
}
.af-top__right .af-att-alert-badge svg {
  flex: 0 0 14px;
  width: 14px;
  height: 14px;
}
.af-top__right .af-att-alert-badge__count {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  border-radius: var(--af-r-pill);
  background: var(--af-danger);
  color: var(--af-on-color);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 18px;
}
.af-top__right .af-att-alert-badge__label {
  display: inline-flex !important;
  align-items: center;
}

/* --- Page dédiée : respiration générale -------------------------------- */
.af-att-alerts-page {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.af-att-alerts-page .af-titlebar {
  margin-bottom: 4px;
}

/* --- Bandeau résumé ---------------------------------------------------- */
.af-att-alert-summary {
  margin-bottom: 0 !important;
  align-items: center;
}
.af-att-alert-summary .af-summary__main {
  flex: 0 0 auto;
}
.af-att-alert-summary__kpis {
  display: flex !important;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 0;
  flex: 1 1 440px;
  min-width: 280px;
}
.af-att-alert-kpi {
  min-width: 118px;
  padding: 0 22px;
  border-left: 1px solid rgba(192, 57, 43, 0.18);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}
.af-summary--warn .af-att-alert-kpi {
  border-left-color: rgba(184, 134, 11, 0.22);
}
.af-att-alert-kpi strong {
  font-family: var(--af-font-serif);
  font-size: 23px;
  line-height: 1;
  font-weight: 500;
  color: var(--af-ink);
}
.af-att-alert-kpi span {
  font-size: 13px;
  color: var(--af-ink-2);
  white-space: nowrap;
}
.af-att-alert-summary .af-summary__actions {
  margin-left: auto;
}

/* --- Filtres : grille desktop plus compacte ---------------------------- */
.af-att-alert-filters {
  padding: 22px 24px !important;
}
.af-att-alert-filters__grid {
  display: grid !important;
  grid-template-columns: repeat(4, minmax(170px, 1fr));
  gap: 18px 20px !important;
  align-items: end;
}
.af-att-alert-filters__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.af-att-alert-filters .af-field {
  min-width: 0;
}
.af-att-alert-filters .af-select {
  width: 100%;
}

/* --- Table : correction des chevauchements de colonnes ------------------ */
.af-att-alert-table .af-row--attendance-alerts {
  grid-template-columns:
    minmax(105px, 0.75fr)
    minmax(260px, 2fr)
    minmax(105px, 0.75fr)
    minmax(130px, 0.85fr)
    minmax(150px, 0.9fr)
    minmax(120px, 0.75fr)
    minmax(130px, 0.75fr) !important;
  gap: 16px !important;
  align-items: center;
}
.af-alert-severity {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-weight: 600;
  white-space: nowrap;
}
.af-alert-severity__dot {
  width: 9px;
  height: 9px;
  border-radius: var(--af-r-pill);
  flex: 0 0 9px;
}
.af-alert-severity--critical { color: var(--af-danger-ink); }
.af-alert-severity--critical .af-alert-severity__dot { background: var(--af-danger); }
.af-alert-severity--warning { color: var(--af-warn-ink); }
.af-alert-severity--warning .af-alert-severity__dot { background: var(--af-warn); }

.af-att-alert-course,
.af-att-alert-time {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.af-att-alert-course strong,
.af-att-alert-time strong {
  display: block;
  max-width: 100%;
  color: var(--af-ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-att-alert-course span,
.af-att-alert-course small,
.af-att-alert-time span,
.af-att-alert-muted {
  color: var(--af-ink-2);
  font-size: 13px;
}
.af-att-alert-course small {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-att-alert-table .af-row__actions .af-btn-secondary {
  justify-content: center;
  min-width: 112px;
  white-space: nowrap;
}
.af-att-alert-empty {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
}

/* --- Responsive -------------------------------------------------------- */
@media (max-width: 1180px) {
  .af-att-alert-filters__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .af-att-alert-table .af-row--attendance-alerts {
    grid-template-columns:
      minmax(100px, 0.8fr)
      minmax(240px, 2fr)
      minmax(125px, 0.9fr)
      minmax(145px, 1fr)
      minmax(120px, 0.8fr)
      minmax(126px, 0.8fr) !important;
  }
  .af-att-alert-table .af-row--attendance-alerts > span:nth-child(3) {
    display: none;
  }
}

@media (max-width: 900px) {
  .af-top__right .af-att-alert-badge__label {
    display: none !important;
  }
  .af-att-alert-summary__kpis {
    flex-basis: 100%;
  }
  .af-att-alert-summary .af-summary__actions {
    margin-left: 0;
  }
}

@media (max-width: 760px) {
  .af-att-alert-filters__grid {
    grid-template-columns: 1fr;
  }
  .af-att-alert-kpi {
    min-width: 50%;
    padding: 10px 14px;
    border-left: 0;
    border-top: 1px solid rgba(192, 57, 43, 0.14);
  }
  .af-att-alert-table .af-row--attendance-alerts {
    grid-template-columns: 1fr !important;
    gap: 8px !important;
    align-items: start;
  }
  .af-att-alert-table .af-row--attendance-alerts.af-row--head {
    display: none;
  }
  .af-att-alert-table .af-row--attendance-alerts > span:nth-child(3) {
    display: inline-flex;
  }
  .af-att-alert-table .af-row__actions {
    justify-content: flex-start;
  }
}
/* =====================================================================
   alterForge — Correctif layout alertes émargement / absences v135
   À coller TOUT EN BAS de public_html/css/common.css
   Objectif : stabiliser le bandeau résumé après ajout du KPI
   "absences à statuer" et corriger l'affichage topbar/table.
   ===================================================================== */

/* --- Topbar : sécurise l'affichage de la pastille --------------------- */
.af-top .af-att-alert-badge,
.af-top__right .af-att-alert-badge {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center;
  gap: 7px !important;
  min-height: 32px;
  padding: 6px 10px !important;
  border-radius: var(--af-r-pill);
  background: var(--af-danger-soft);
  border: 1px solid rgba(192, 57, 43, 0.28);
  color: var(--af-danger-ink, var(--af-danger));
  font-size: 12.5px;
  line-height: 1;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  flex: 0 0 auto;
}
.af-top .af-att-alert-badge:hover,
.af-top__right .af-att-alert-badge:hover {
  background: #fff4f4;
  border-color: rgba(192, 57, 43, 0.42);
  color: var(--af-danger-ink, var(--af-danger));
}
.af-top .af-att-alert-badge svg,
.af-top__right .af-att-alert-badge svg {
  flex: 0 0 14px;
  width: 14px;
  height: 14px;
}
.af-top .af-att-alert-badge__count,
.af-top__right .af-att-alert-badge__count {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  border-radius: var(--af-r-pill);
  background: var(--af-danger);
  color: var(--af-on-color, #fff);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 18px;
}
.af-top .af-att-alert-badge__label,
.af-top__right .af-att-alert-badge__label {
  display: inline-flex !important;
  align-items: center;
}

/* --- Bandeau résumé : passage en grille robuste ----------------------- */
.af-att-alert-summary.af-summary,
.af-summary.af-att-alert-summary {
  display: grid !important;
  grid-template-columns: minmax(255px, 0.95fr) minmax(0, 2.1fr) auto;
  column-gap: 24px;
  row-gap: 16px;
  align-items: center;
  padding: 20px 28px !important;
}

.af-att-alert-summary .af-summary__main {
  min-width: 0;
  width: 100%;
  padding-right: 24px;
  border-right: 1px solid rgba(192, 57, 43, 0.18);
}
.af-summary--warn.af-att-alert-summary .af-summary__main {
  border-right-color: rgba(184, 134, 11, 0.20);
}
.af-att-alert-summary .af-summary__big {
  line-height: 1;
}
.af-att-alert-summary .af-summary__text {
  min-width: 0;
}
.af-att-alert-summary .af-summary__title,
.af-att-alert-summary .af-summary__breakdown {
  max-width: 100%;
}

.af-att-alert-summary__kpis {
  display: grid !important;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0 !important;
  flex: none !important;
  flex-basis: auto !important;
  width: 100%;
  min-width: 0;
}
.af-att-alert-kpi {
  min-width: 0 !important;
  padding: 0 14px !important;
  border-left: 1px solid rgba(192, 57, 43, 0.14);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
}
.af-summary--warn .af-att-alert-kpi {
  border-left-color: rgba(184, 134, 11, 0.20);
}
.af-att-alert-kpi:first-child {
  border-left: 0;
}
.af-att-alert-kpi strong {
  display: block;
  font-family: var(--af-font-serif);
  font-size: 24px;
  line-height: 1;
  font-weight: 500;
  color: var(--af-ink);
}
.af-att-alert-kpi span {
  display: block;
  color: var(--af-ink-2);
  font-size: 13px;
  line-height: 1.25;
  white-space: normal !important;
  overflow-wrap: anywhere;
}
.af-att-alert-kpi--absence strong {
  color: var(--af-warn);
}
.af-att-alert-kpi--absence span {
  color: var(--af-warn-ink, var(--af-warn));
}
.af-att-alert-summary .af-summary__actions {
  margin-left: 0 !important;
  justify-self: end;
  align-self: center;
  min-width: max-content;
}
.af-att-alert-summary .af-summary__actions .af-btn-ghost {
  white-space: nowrap;
}

/* --- Table alertes : évite les collisions entre badge et rappel -------- */
.af-att-alert-table .af-row--attendance-alerts {
  grid-template-columns:
    minmax(110px, 0.75fr)
    minmax(280px, 2fr)
    minmax(110px, 0.75fr)
    minmax(135px, 0.85fr)
    minmax(150px, 0.9fr)
    minmax(125px, 0.8fr)
    minmax(130px, 0.75fr) !important;
  gap: 18px !important;
  align-items: center;
}
.af-att-alert-table .af-row--attendance-alerts > span {
  min-width: 0;
}
.af-att-alert-table .af-pill {
  max-width: 100%;
  white-space: nowrap;
}
.af-att-alert-table .af-att-alert-muted {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-att-alert-table .af-row__actions {
  justify-content: flex-end;
}
.af-att-alert-table .af-row__actions .af-btn-secondary {
  min-width: 112px;
  justify-content: center;
  white-space: normal;
  text-align: center;
  line-height: 1.25;
}

/* --- Responsive résumé ------------------------------------------------- */
@media (max-width: 1240px) {
  .af-att-alert-summary.af-summary,
  .af-summary.af-att-alert-summary {
    grid-template-columns: 1fr;
  }
  .af-att-alert-summary .af-summary__main {
    padding-right: 0;
    border-right: 0;
  }
  .af-att-alert-summary .af-summary__actions {
    justify-self: start;
  }
}

@media (max-width: 900px) {
  .af-top .af-att-alert-badge__label,
  .af-top__right .af-att-alert-badge__label {
    display: none !important;
  }
  .af-att-alert-summary__kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .af-att-alert-kpi {
    padding: 10px 14px !important;
    border-left: 0;
    border-top: 1px solid rgba(192, 57, 43, 0.14);
  }
}

@media (max-width: 560px) {
  .af-att-alert-summary.af-summary,
  .af-summary.af-att-alert-summary {
    padding: 18px !important;
  }
  .af-att-alert-summary__kpis {
    grid-template-columns: 1fr;
  }
}
/* ==========================================================
   AlterForge — correctif page QR étudiants (class_qr.php)
   Version CSS : v136
   À coller tout en bas de public_html/css/common.css
   Objectif : restaurer la grille de cartes QR après pertes CSS.
   ========================================================== */

.af-qr-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--af-line);
  background: var(--af-surface);
}

.af-qr-bar__right {
  display: flex;
  align-items: center;
  gap: 14px;
}

.af-qr-head,
.af-student-qr-print-head {
  max-width: 980px;
  margin: 0 auto;
  padding: 34px 24px 8px;
  text-align: center;
}

.af-qr-head h1,
.af-student-qr-print-head h1 {
  margin: 0 0 10px;
  font-family: var(--af-font-serif);
  font-size: clamp(30px, 3vw, 44px);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--af-ink);
}

.af-qr-head p,
.af-student-qr-print-head p {
  margin: 0;
  color: var(--af-ink-2);
}

.af-student-qr-grid {
  width: min(1180px, calc(100% - 48px));
  margin: 28px auto 64px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px;
  align-items: stretch;
}

.af-student-qr-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  background: var(--af-surface);
  box-shadow: var(--af-shadow-sm);
  page-break-inside: avoid;
  break-inside: avoid;
}

.af-student-qr-card__top {
  padding: 20px 20px 14px;
  text-align: center;
  border-bottom: 1px solid var(--af-line);
  background: var(--af-surface-soft);
}

.af-student-qr-card__top h2 {
  margin: 0 0 8px;
  font-family: var(--af-font-sans);
  font-size: 18px;
  line-height: 1.25;
  font-weight: 700;
  color: var(--af-ink);
}

.af-student-qr-card__top p {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--af-ink-2);
  font-size: 13.5px;
  line-height: 1.35;
}

.af-student-qr-card__img {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 246px;
  padding: 20px;
  background: var(--af-surface);
}

.af-student-qr-card__img canvas,
.af-student-qr-card__img img {
  display: block;
  width: 220px !important;
  height: 220px !important;
  max-width: 100%;
}

.af-student-qr-card__scan {
  margin: 0;
  padding: 0 20px 20px;
  text-align: center;
  color: var(--af-ink-3);
  font-size: 13.5px;
  line-height: 1.4;
}

@media (max-width: 720px) {
  .af-qr-bar {
    flex-direction: column;
    align-items: stretch;
    padding: 12px 16px;
  }

  .af-qr-bar__right {
    justify-content: space-between;
  }

  .af-student-qr-grid {
    width: min(100% - 24px, 420px);
    grid-template-columns: 1fr;
    gap: 18px;
    margin-top: 20px;
  }
}

@page {
  size: A4 portrait;
  margin: 12mm;
}

@media print {
  body {
    background: #fff !important;
  }

  .af-qr-bar {
    display: none !important;
  }

  .af-qr-head,
  .af-student-qr-print-head {
    max-width: none;
    padding: 0 0 8mm;
  }

  .af-qr-head h1,
  .af-student-qr-print-head h1 {
    font-size: 24pt;
    margin-bottom: 4mm;
  }

  .af-student-qr-grid {
    width: 100%;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8mm;
  }

  .af-student-qr-card {
    box-shadow: none !important;
    border: 1px solid #ddd;
    border-radius: 8px;
  }

  .af-student-qr-card__top {
    padding: 8mm 6mm 5mm;
  }

  .af-student-qr-card__top h2 {
    font-size: 13pt;
  }

  .af-student-qr-card__top p,
  .af-student-qr-card__scan {
    font-size: 9.5pt;
  }

  .af-student-qr-card__img {
    min-height: auto;
    padding: 6mm;
  }

  .af-student-qr-card__img canvas,
  .af-student-qr-card__img img {
    width: 42mm !important;
    height: 42mm !important;
  }
}

/* =========================================================================
   FIX v138 — Restauration mise en page page Générateurs / modules.php
   À coller tout en bas de public_html/css/common.css
   -------------------------------------------------------------------------
   Contexte : la page admin/modules.php utilise les classes af-feature-*.
   Ces classes ne sont plus stylées dans common.css, ce qui remet les cartes
   en flux vertical brut. Ce bloc restaure la grille responsive sans toucher
   au PHP ni aux autres pages.
   ========================================================================= */

.af-feature-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(220px, 1fr));
  gap: 18px;
  width: 100%;
  margin: 18px 0 24px;
  align-items: stretch;
}

.af-feature-card {
  position: relative;
  min-width: 0;
  min-height: 238px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  box-shadow: var(--af-shadow-sm);
  overflow: hidden;
}

.af-feature-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--af-action), transparent 58%);
  opacity: .9;
}

.af-feature-card__icon {
  width: 42px;
  height: 42px;
  border-radius: var(--af-r-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  background: var(--af-action-soft);
  color: var(--af-action-hover);
  border: 1px solid rgba(13, 148, 136, .18);
  font-size: 21px;
  line-height: 1;
}

.af-feature-card__title {
  margin: 2px 0 0;
  font-family: var(--af-font-serif);
  font-size: 23px;
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -.25px;
  color: var(--af-ink);
}

.af-feature-card__text {
  margin: 0;
  color: var(--af-ink-2);
  font-size: 13.5px;
  line-height: 1.55;
  flex: 1 1 auto;
}

.af-feature-card__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.af-feature-card__actions .af-btn-primary,
.af-feature-card__actions .af-btn-secondary,
.af-feature-card__actions .af-btn-ghost {
  white-space: nowrap;
}

.af-feature-card--disabled {
  background: var(--af-surface-soft);
}

.af-feature-card--disabled::before {
  background: var(--af-line);
}

.af-feature-card--disabled .af-feature-card__icon {
  background: var(--af-neutral-soft);
  color: var(--af-neutral-ink);
  border-color: var(--af-line);
}

.af-feature-card--disabled .af-feature-card__text {
  color: var(--af-ink-3);
}

/* La page Générateurs contient un bandeau règle sous la grille : on évite
   qu'il reste collé à la grille ou qu'il se compacte trop sur grand écran. */
.af-feature-grid + .af-summary {
  width: 100%;
  margin-top: 10px;
}

@media (max-width: 1500px) {
  .af-feature-grid {
    grid-template-columns: repeat(3, minmax(220px, 1fr));
  }
}

@media (max-width: 1180px) {
  .af-feature-grid {
    grid-template-columns: repeat(2, minmax(220px, 1fr));
  }
}

@media (max-width: 720px) {
  .af-feature-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .af-feature-card {
    min-height: 0;
    padding: 18px;
  }

  .af-feature-card__actions {
    align-items: stretch;
  }

  .af-feature-card__actions .af-btn-primary,
  .af-feature-card__actions .af-btn-secondary,
  .af-feature-card__actions .af-btn-ghost {
    justify-content: center;
  }
}
/* =========================================================================
   FIX v141 — Fiche étudiant / assiduité (student_attendance.php)
   -------------------------------------------------------------------------
   Rapproche la page de suivi individuel du design class-assiduite.html :
   en-tête synthèse, ventilation des heures, cartes d'absence, barre de
   justification dédiée. À appender en bas de public_html/css/common.css.
   ========================================================================= */

.af-assi-card {
  margin-bottom: 18px;
}

.af-assi-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.af-assi-head__ident {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.af-assi-head__name {
  font-family: var(--af-font-serif);
  font-size: 24px;
  font-weight: 500;
  letter-spacing: -0.2px;
  color: var(--af-ink);
  margin: 0;
}

.af-assi-head__meta {
  margin: 0;
  font-size: 13.5px;
  color: var(--af-ink-3);
}

.af-assi-head__meta a {
  color: var(--af-action-hover);
  text-decoration: none;
}

.af-assi-head__meta a:hover {
  text-decoration: underline;
}

.af-assi-head__meta code {
  font-family: var(--af-font-mono);
  font-size: 12.5px;
  color: var(--af-ink-2);
  background: transparent;
  border: 0;
  padding: 0;
}

.af-assi-head__sep {
  margin: 0 8px;
  color: var(--af-ink-3);
}

.af-assi-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.af-assi-hours {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0;
  background: var(--af-surface-soft);
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-lg);
  overflow: hidden;
  width: fit-content;
  max-width: 100%;
}

.af-assi-hour {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 9px 18px;
  min-width: 96px;
}

.af-assi-hour + .af-assi-hour {
  border-left: 1px solid var(--af-line-2);
}

.af-assi-hour__k {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--af-ink-3);
}

.af-assi-hour__v {
  font-family: var(--af-font-serif);
  font-size: 20px;
  font-weight: 500;
  color: var(--af-ink);
  line-height: 1.1;
}

.af-assi-hour--todo {
  background: var(--af-warn-soft);
}

.af-assi-hour--todo .af-assi-hour__v {
  color: var(--af-warn-ink);
}

.af-assi-hour--ok .af-assi-hour__v {
  color: var(--af-success);
}

.af-assi-hour--no .af-assi-hour__v {
  color: var(--af-danger);
}

.af-assi-detail {
  margin-bottom: 32px;
}

.af-assi-detail__help {
  margin: -2px 0 16px;
  max-width: none;
}

.af-absences {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.af-absence {
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface);
  overflow: hidden;
}

.af-absence--todo {
  border-left: 3px solid var(--af-warn);
}

.af-absence--ok {
  border-left: 3px solid var(--af-success);
}

.af-absence--no {
  border-left: 3px solid var(--af-danger);
}

.af-absence--late {
  border-left: 3px solid var(--af-warn);
}

.af-absence__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 16px;
}

.af-absence__info {
  min-width: 0;
}

.af-absence__when {
  margin: 0;
  font-family: var(--af-font-mono);
  font-size: 12.5px;
  color: var(--af-ink-2);
  font-weight: 500;
}

.af-absence__course {
  margin: 3px 0 0;
  font-size: 14px;
  color: var(--af-ink);
  line-height: 1.4;
}

.af-absence__course span {
  color: var(--af-ink-3);
}

.af-absence__note {
  margin: 7px 0 0;
  color: var(--af-info-ink);
  font-size: 12.5px;
}

.af-absence__tags {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.af-absence__dur {
  font-size: 12.5px;
  color: var(--af-ink-3);
  font-family: var(--af-font-mono);
  white-space: nowrap;
}

.af-justify {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  border-top: 1px solid var(--af-line-2);
  background: var(--af-surface-soft);
}

.af-justify--readonly {
  color: var(--af-ink-3);
}

.af-justify__label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--af-ink-3);
  flex-shrink: 0;
}

.af-decide {
  display: inline-flex;
  background: var(--af-bg);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  padding: 3px;
  gap: 2px;
}

.af-decide label {
  position: relative;
  display: inline-flex;
  margin: 0;
}

.af-decide input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 1px;
  height: 1px;
}

.af-decide span {
  border: 0;
  background: transparent;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--af-ink-2);
  padding: 6px 13px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.af-decide span:hover {
  color: var(--af-ink);
}

.af-decide input:checked + span {
  background: var(--af-surface);
  box-shadow: var(--af-shadow-sm);
}

.af-decide input[value="justified"]:checked + span {
  color: var(--af-success);
}

.af-decide input[value="unjustified"]:checked + span {
  color: var(--af-danger);
}

.af-decide input[value=""]:checked + span {
  color: var(--af-warn-ink);
}

.af-decide input:focus-visible + span {
  outline: 2px solid var(--af-action);
  outline-offset: 2px;
}

.af-justify__spacer {
  flex: 1;
  min-width: 0;
}

.af-attach {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 12px;
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-md);
  background: var(--af-surface);
  cursor: pointer;
  font-size: 13px;
  color: var(--af-ink-2);
  transition: border-color .12s ease, color .12s ease;
}

.af-attach:hover {
  border-color: var(--af-action);
  color: var(--af-action-hover);
}

.af-attach svg {
  color: var(--af-ink-3);
  flex-shrink: 0;
}

.af-attach:hover svg {
  color: var(--af-action);
}

.af-attach input {
  display: none;
}

.af-attached {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px 7px 12px;
  border: 1px solid color-mix(in srgb, var(--af-success) 30%, var(--af-line));
  border-radius: var(--af-r-md);
  background: var(--af-success-soft);
  font-size: 13px;
  color: var(--af-success-ink);
  max-width: 320px;
}

.af-attached a {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.af-attached a:hover .af-attached__name {
  text-decoration: underline;
}

.af-attached__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--af-font-mono);
  font-size: 12px;
}

.af-attached__remove {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--af-success-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--af-r-sm);
}

.af-attached__remove:hover {
  background: color-mix(in srgb, var(--af-success) 16%, transparent);
}

.af-justify__done {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--af-ink-3);
}

.af-justify__done svg {
  color: var(--af-success);
}

.af-assi-empty {
  margin-top: 14px;
}

@media (max-width: 860px) {
  .af-absence__head {
    flex-direction: column;
  }

  .af-absence__tags {
    align-self: flex-start;
  }

  .af-justify {
    gap: 10px;
  }

  .af-justify__spacer {
    flex-basis: 100%;
    height: 0;
  }

  .af-decide {
    width: 100%;
  }

  .af-decide label {
    flex: 1;
  }

  .af-decide span {
    flex: 1;
    justify-content: center;
  }
}

@media (max-width: 560px) {
  .af-assi-hours {
    width: 100%;
  }

  .af-assi-hour {
    min-width: 50%;
    flex: 1 1 50%;
  }

  .af-assi-hour + .af-assi-hour {
    border-left: 0;
  }

  .af-assi-hour:nth-child(even) {
    border-left: 1px solid var(--af-line-2);
  }

  .af-attach,
  .af-attached,
  .af-justify .af-btn-primary {
    width: 100%;
    justify-content: center;
  }
}
.af-profile-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.af-profile-item {
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--af-border);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
}

.af-profile-label {
  display: block;
  margin-bottom: 4px;
  font-size: 12px;
  color: var(--af-ink-3);
}

.af-profile-item strong {
  display: block;
  color: var(--af-ink);
  overflow-wrap: anywhere;
}

.af-pill-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (max-width: 1080px) {
  .af-profile-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .af-profile-grid {
    grid-template-columns: 1fr;
  }
}
/* v145.1 — Import Skodoc : table de prévisualisation large */
.af-table-wrap {
  width: 100%;
  overflow-x: auto;
}

.af-native-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 1180px;
  font-size: 13px;
}

.af-native-table th,
.af-native-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--af-border);
  text-align: left;
  vertical-align: top;
}

.af-native-table th {
  background: var(--af-surface-soft);
  color: var(--af-ink-2);
  font-weight: 600;
  white-space: nowrap;
}

.af-native-table td {
  color: var(--af-ink);
}

.af-native-table code,
.af-code {
  font-family: var(--af-font-mono);
}

.af-pill-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}
/* v146 — édition contrôlée fiche étudiant */
.af-edit-box {
  margin-top: 14px;
  border: 1px solid var(--af-border);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
  padding: 0;
}

.af-edit-box > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  cursor: pointer;
  padding: 12px 14px;
  font-weight: 600;
  color: var(--af-action-hover);
  list-style: none;
}

.af-edit-box > summary::-webkit-details-marker {
  display: none;
}

.af-edit-box > summary::after {
  content: "+";
  font-family: var(--af-font-mono);
  font-size: 14px;
  color: var(--af-ink-3);
}

.af-edit-box[open] > summary::after {
  content: "–";
}

.af-edit-form {
  padding: 0 14px 14px;
}

.af-edit-form .af-form-actions {
  margin-top: 12px;
}
/* v147 — Import référentiel modules ScoDoc */
.af-row--modules-import{
  grid-template-columns:70px 70px 140px 100px minmax(220px,1fr) 90px 150px minmax(180px,0.9fr);
  gap:10px;
}
@media (max-width: 1180px){
  .af-row--modules-import{grid-template-columns:64px 70px 120px 90px 1fr 90px;}
  .af-row--modules-import > span:nth-child(7),
  .af-row--modules-import > span:nth-child(8){display:none;}
}
@media (max-width: 720px){
  .af-row--modules-import{grid-template-columns:64px 80px 1fr;}
  .af-row--modules-import > span:nth-child(2),
  .af-row--modules-import > span:nth-child(4),
  .af-row--modules-import > span:nth-child(6),
  .af-row--modules-import > span:nth-child(7),
  .af-row--modules-import > span:nth-child(8){display:none;}
}


/* ---------------------------------------------------------------------
   v148.1 — Confirmation de suppression hors conteneurs scrollables
   La page Matières/Modules utilise .af-table avec overflow ; le popover
   rendu dans la ligne pouvait donc être coupé. Le JS rend maintenant le
   popover dans <body> avec .af-confirm--fixed.
   --------------------------------------------------------------------- */
.af-confirm--fixed {
  position: fixed;
  z-index: 10000;
  right: auto;
  bottom: auto;
  max-width: calc(100vw - 20px);
}

.af-confirm--fixed .af-confirm__actions {
  flex-wrap: nowrap;
}

@media (max-width: 640px) {
  .af-confirm--fixed {
    width: min(280px, calc(100vw - 20px));
  }
}
/* v148.1c — Confirmation native pour suppressions Matières / Modules.
   Objectif : la corbeille reste cliquable même si le popover JS global échoue. */
.af-confirm-native {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  position: relative;
  max-width: min(320px, 80vw);
}

.af-confirm-native > summary {
  list-style: none;
}

.af-confirm-native > summary::-webkit-details-marker {
  display: none;
}

.af-confirm-native[open] > summary {
  background: var(--af-danger-soft);
  border-color: var(--af-danger-soft);
  color: var(--af-danger);
}

.af-confirm-native__panel {
  margin-top: 8px;
  width: min(280px, 72vw);
  padding: 14px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface);
  box-shadow: var(--af-shadow-pop);
  text-align: left;
  z-index: 5;
}

.af-confirm-native__form {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.af-confirm-native__hint {
  margin: 8px 0 0;
  font-size: 11.5px;
  color: var(--af-ink-3);
}

.af-row__actions .af-confirm-native {
  margin-left: auto;
}

/* =========================================================================
   CLEANUP v149 — socle responsive large écran
   Reprise du correctif v137, replacé en fin de fichier pour ne plus être
   écrasé par les tokens et les règles de base.
   ========================================================================= */
/* =========================================================================
   alterForge — correctif responsive socle admin v137
   -------------------------------------------------------------------------
   Objectif : utiliser toute la largeur disponible sur desktop / grand écran,
   sans refaire la version mobile et sans écraser common.css.

   À coller tout en bas de public_html/css/common.css.
   Puis incrémenter ASSET_VERSION à 137 dans public_html/lib/db.php.
   ========================================================================= */

/* 1) Le shell admin ne doit plus limiter artificiellement le contenu à 1240px.
   Les pages de pilotage, listes, banques, matières, librairie et alertes doivent
   exploiter la largeur disponible après la sidebar. */
:root {
  --af-content-max: none;
  --af-page-gutter-x: clamp(20px, 2.1vw, 44px);
  --af-page-gutter-y: clamp(24px, 2vw, 32px);
}

.af-col {
  min-width: 0;
  width: 100%;
}

.af-main {
  width: 100%;
  max-width: none !important;
  padding: var(--af-page-gutter-y) var(--af-page-gutter-x) 56px;
}

/* 2) Les grands blocs métier doivent suivre la largeur du main.
   On ne touche pas aux composants volontairement étroits comme .af-form simple,
   .af-sub ou les blocs de lecture. */
.af-titlebar,
.af-stats,
.af-tabs,
.af-summary,
.af-section--card,
.af-table,
.af-empty,
.af-flash {
  width: 100%;
  max-width: none;
}

/* 3) Les stats doivent s'adapter au nombre de cartes et à la largeur réelle.
   Cela évite les bandes trop resserrées ou les cartes bloquées en 4 colonnes. */
.af-stats {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

/* 4) Les formulaires larges restent lisibles et utilisent mieux l'espace. */
.af-form--wide {
  width: 100%;
  max-width: none;
}

.af-form-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.af-form-inline,
.af-form-inline--wide,
.af-inline-form {
  max-width: none;
}

.af-form-inline--wide .af-input--grow,
.af-form-inline .af-input--grow {
  min-width: 0;
  flex: 1 1 320px;
}

/* 5) Les tables ne doivent pas casser le layout : elles prennent la largeur
   disponible, mais peuvent scroller horizontalement si une variante possède
   beaucoup de colonnes. */
.af-table {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.af-row {
  min-width: 0;
}

.af-row > * {
  min-width: 0;
}

.af-row__name,
.af-muted {
  overflow-wrap: anywhere;
}

.af-row__actions,
.af-titlebar__actions,
.af-summary__actions {
  flex-wrap: wrap;
}

/* 6) Sur écran large, on garde une respiration correcte sans recréer une
   colonne vide fixe à droite. */
@media (min-width: 1600px) {
  :root {
    --af-page-gutter-x: clamp(36px, 3vw, 64px);
  }
}

/* 7) Responsive intermédiaire : pas une vraie version mobile, mais un layout
   qui se replie proprement sur laptop/tablette. */
@media (max-width: 1280px) {
  :root {
    --af-page-gutter-x: 28px;
    --af-page-gutter-y: 24px;
  }

  .af-section__head,
  .af-titlebar,
  .af-summary {
    gap: 16px;
  }
}

@media (max-width: 1080px) {
  :root {
    --af-page-gutter-x: 24px;
  }

  .af-top {
    flex-wrap: wrap;
    padding-left: var(--af-page-gutter-x);
    padding-right: var(--af-page-gutter-x);
  }

  .af-search {
    flex: 1 1 320px;
  }

  .af-form-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 760px) {
  :root {
    --af-page-gutter-x: 18px;
    --af-page-gutter-y: 20px;
  }

  .af-main {
    padding-bottom: 40px;
  }

  .af-titlebar,
  .af-section__head,
  .af-summary {
    flex-direction: column;
    align-items: stretch;
  }

  .af-titlebar__actions,
  .af-section__head .af-btn-primary,
  .af-section__head .af-btn-secondary,
  .af-summary__actions {
    justify-content: flex-start;
  }

  .af-search {
    order: 2;
    flex-basis: 100%;
  }

  .af-top__right {
    margin-left: 0;
    flex-wrap: wrap;
    justify-content: flex-start;
  }
}
/* =========================================================================
   v150.2 — Matières / Modules : lisibilité table référentiel
   À ajouter en bas de css/common.css après les patchs v150/v150.1.
   Puis incrémenter ASSET_VERSION.
   ========================================================================= */

/* La table garde 6 colonnes, mais la répartition donne plus de place
   au référentiel et à l'intitulé de matière. Le type technique
   res / sae / bonus reste en base mais n'est plus affiché. */
.af-row--modules-catalog-scoped {
  grid-template-columns:
    minmax(150px, .85fr)
    minmax(300px, 1.55fr)
    72px
    minmax(92px, .55fr)
    minmax(420px, 2.35fr)
    52px !important;
  gap: 18px !important;
  align-items: center;
}

.af-row--modules-catalog-scoped.af-row--head {
  align-items: center;
}

/* Le type technique de module ne doit pas polluer l'affichage utilisateur.
   Exemples masqués : res, sae, bonus, ue, malus. */
.af-module-ref small,
.af-module-type,
.af-module-kind {
  display: none !important;
}

.af-module-inst strong,
.af-module-ref strong {
  font-weight: 700;
}

.af-module-ref strong {
  max-width: 100%;
}

.af-module-subject {
  gap: 4px;
}

.af-module-subject strong {
  white-space: normal;
  line-height: 1.28;
  max-width: 52rem;
}

.af-module-subject small {
  max-width: 100%;
  overflow-wrap: anywhere;
}

.af-row--modules-catalog-scoped .af-code {
  width: fit-content;
}

.af-row--modules-catalog-scoped .af-row__actions {
  justify-content: center;
}

@media (max-width: 1380px) {
  .af-row--modules-catalog-scoped {
    grid-template-columns:
      minmax(145px, .85fr)
      minmax(260px, 1.35fr)
      68px
      minmax(86px, .55fr)
      minmax(340px, 2.1fr)
      52px !important;
    gap: 14px !important;
  }
}

@media (max-width: 1180px) {
  .af-row--modules-catalog-scoped {
    grid-template-columns:
      minmax(145px, .9fr)
      68px
      minmax(86px, .6fr)
      minmax(320px, 2fr)
      52px !important;
  }

  .af-row--modules-catalog-scoped > span:nth-child(2) {
    display: none;
  }
}

@media (max-width: 760px) {
  .af-row--modules-catalog-scoped {
    grid-template-columns: 68px minmax(0, 1fr) 46px !important;
    gap: 10px !important;
  }

  .af-module-subject strong {
    max-width: none;
  }
}
/* =========================================================================
   v151 — Matières / Modules : volumes horaires maquette + planning
   À ajouter en bas de css/common.css, après les patchs v150.
   Puis incrémenter ASSET_VERSION à 154.
   ========================================================================= */

.af-row--modules-catalog-scoped {
  grid-template-columns:
    minmax(150px, .8fr)
    minmax(230px, 1.2fr)
    66px
    minmax(82px, .48fr)
    minmax(170px, .95fr)
    minmax(360px, 2.1fr)
    52px !important;
  gap: 16px !important;
  align-items: center;
}

.af-module-hours {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  font-size: 12.5px;
  color: var(--af-ink-3);
  line-height: 1.25;
}

.af-module-hours strong {
  color: var(--af-ink);
  font-size: 13px;
  font-weight: 700;
}

.af-module-hours small {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.af-module-hours--remaining strong {
  color: var(--af-action-hover);
}

.af-module-hours--done strong {
  color: var(--af-success);
}

.af-module-hours--over strong,
.af-module-hours__over {
  color: var(--af-danger-ink) !important;
}

.af-module-hours-hint {
  margin-top: 8px;
  padding: 10px 12px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-md);
  background: var(--af-surface-soft);
  color: var(--af-ink-2);
  font-size: 12.5px;
  line-height: 1.4;
}

.af-module-hours-hint strong {
  color: var(--af-ink);
  font-weight: 700;
}

.af-module-hours-hint__line {
  display: block;
}

.af-module-hours-hint--over {
  background: var(--af-danger-soft);
  border-color: color-mix(in srgb, var(--af-danger) 28%, var(--af-line));
  color: var(--af-danger-ink);
}

.af-module-hours-hint--ok {
  background: var(--af-success-soft);
  border-color: color-mix(in srgb, var(--af-success) 24%, var(--af-line));
}

@media (max-width: 1420px) {
  .af-row--modules-catalog-scoped {
    grid-template-columns:
      minmax(140px, .75fr)
      minmax(210px, 1fr)
      64px
      minmax(76px, .45fr)
      minmax(160px, .9fr)
      minmax(300px, 1.8fr)
      52px !important;
    gap: 13px !important;
  }
}

@media (max-width: 1180px) {
  .af-row--modules-catalog-scoped {
    grid-template-columns:
      minmax(138px, .85fr)
      64px
      minmax(148px, .9fr)
      minmax(280px, 1.8fr)
      52px !important;
  }

  .af-row--modules-catalog-scoped > span:nth-child(2),
  .af-row--modules-catalog-scoped > span:nth-child(4) {
    display: none;
  }
}

@media (max-width: 760px) {
  .af-row--modules-catalog-scoped {
    grid-template-columns: 64px minmax(0, 1fr) 46px !important;
    gap: 10px !important;
  }

  .af-row--modules-catalog-scoped > span:nth-child(1),
  .af-row--modules-catalog-scoped > span:nth-child(2),
  .af-row--modules-catalog-scoped > span:nth-child(4),
  .af-row--modules-catalog-scoped > span:nth-child(5) {
    display: none;
  }
}
/* =========================================================================
   v151.1 — Édition des matières / modules
   -------------------------------------------------------------------------
   Formulaire d'édition du référentiel. Les volumes calculés depuis le planning
   restent affichés en lecture seule.
   ========================================================================= */

.af-module-edit-section {
  border-color: color-mix(in srgb, var(--af-action) 22%, var(--af-line));
}

.af-form-grid--modules-edit {
  grid-template-columns: repeat(4, minmax(160px, 1fr));
}

.af-module-readonly-metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(180px, 1fr));
  gap: 10px;
  margin: 18px 0 4px;
}

.af-module-readonly-metric {
  background: var(--af-surface-soft);
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-lg);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.af-module-readonly-metric span {
  font-family: var(--af-font-mono);
  font-size: 11px;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--af-ink-3);
}

.af-module-readonly-metric strong {
  font-family: var(--af-font-serif);
  font-size: 22px;
  line-height: 1.1;
  font-weight: 500;
  color: var(--af-ink);
}

.af-module-readonly-metric small {
  color: var(--af-ink-3);
  font-size: 12.5px;
  line-height: 1.35;
}

.af-row--modules-catalog-scoped .af-row__actions {
  gap: 8px;
  flex-wrap: nowrap;
}

@media (max-width: 1180px) {
  .af-form-grid--modules-edit {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .af-module-readonly-metrics {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .af-form-grid--modules-edit {
    grid-template-columns: 1fr;
  }

  .af-row--modules-catalog-scoped .af-row__actions {
    flex-wrap: wrap;
    justify-content: flex-start;
  }
}
/* =========================================================================
   v152 — Référentiels pédagogiques
   ========================================================================= */
.af-ref-map {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.af-ref-map span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--af-r-pill);
  background: var(--af-surface-soft);
  border: 1px solid var(--af-line);
  color: var(--af-ink-2);
  font-size: 13px;
  font-weight: 600;
}
.af-ref-map span + span::before {
  content: '→';
  color: var(--af-ink-3);
  margin-right: 2px;
}
.af-ref-form {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 12px;
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
}
.af-ref-form .af-field {
  min-width: 160px;
}
.af-ref-form__grow {
  flex: 1 1 260px;
}
.af-ref-check {
  min-height: 42px;
  align-items: center;
}
.af-ref-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.af-ref-list--compact {
  max-width: 760px;
}
.af-ref-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-lg);
  background: var(--af-surface);
}
.af-ref-row__form {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) minmax(90px, .55fr) minmax(220px, 1.4fr) auto auto;
  gap: 8px;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
}
.af-ref-row__form--program {
  grid-template-columns: minmax(160px, 1fr) minmax(160px, 1fr) minmax(76px, .45fr) minmax(100px, .6fr) minmax(220px, 1.3fr) auto auto;
}
.af-ref-row__form--year {
  grid-template-columns: minmax(120px, .8fr) 150px 150px auto minmax(120px, .6fr) auto;
}
.af-ref-row__form--semester {
  grid-template-columns: minmax(80px, .45fr) minmax(180px, 1.2fr) 90px auto auto;
}
.af-ref-row__toggle {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.af-ref-row .af-input,
.af-ref-row .af-select {
  min-width: 0;
}
.af-module-ref small,
.af-module-subject small {
  display: block;
  margin-top: 3px;
  color: var(--af-ink-3);
  font-size: 12px;
  line-height: 1.25;
}
@media (max-width: 1180px) {
  .af-ref-row,
  .af-ref-row__form,
  .af-ref-row__form--program,
  .af-ref-row__form--year,
  .af-ref-row__form--semester {
    display: flex;
    flex-wrap: wrap;
  }
  .af-ref-row__form > *,
  .af-ref-row__toggle {
    flex: 1 1 180px;
  }
  .af-ref-row__form .af-btn-secondary,
  .af-ref-row__toggle .af-btn-ghost {
    justify-content: center;
  }
}
@media (max-width: 720px) {
  .af-ref-form {
    align-items: stretch;
  }
  .af-ref-form .af-field,
  .af-ref-form .af-btn-primary,
  .af-ref-row__form > *,
  .af-ref-row__toggle {
    flex-basis: 100%;
  }
}
/* =========================================================================
   v152.4 — Actions de suppression des référentiels pédagogiques
   ========================================================================= */
.af-ref-row__delete {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.af-ref-row__delete > summary {
  list-style: none;
  cursor: pointer;
}
.af-ref-row__delete > summary::-webkit-details-marker {
  display: none;
}
.af-ref-delete-summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 34px;
  padding: 0 12px;
  border-radius: var(--af-r-md);
  border: 1px solid var(--af-danger-soft);
  background: var(--af-danger-soft);
  color: var(--af-danger);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}
.af-ref-delete-summary:hover {
  border-color: var(--af-danger);
}
.af-ref-delete-box {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 30;
  width: min(320px, 80vw);
  padding: 12px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface);
  box-shadow: var(--af-shadow-pop);
}
.af-ref-delete-box .af-help {
  margin: 0 0 10px;
}
.af-ref-delete-box .af-btn-danger {
  width: 100%;
  justify-content: center;
}
@media (max-width: 1180px) {
  .af-ref-row__delete {
    flex: 1 1 180px;
  }
  .af-ref-delete-summary {
    width: 100%;
  }
}
@media (max-width: 720px) {
  .af-ref-row__delete {
    flex-basis: 100%;
  }
}
/* =========================================================================
   v152.7 — Finition Matières / Modules
   -------------------------------------------------------------------------
   - suppression visible en texte, avec confirmation native <details>
   - badge warning pour les volumes non renseignés
   - libellés et actions plus lisibles dans les tables de référentiel
   ========================================================================= */

.af-volume-missing-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  width: fit-content;
  padding: 4px 9px;
  border-radius: var(--af-r-pill);
  background: var(--af-warn-soft);
  color: var(--af-warn-ink);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.25;
  white-space: nowrap;
}

.af-volume-missing-badge > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: var(--af-r-pill);
  background: var(--af-warn);
  color: var(--af-on-color);
  font-family: var(--af-font-mono);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.af-row__actions .af-inline-delete {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.af-inline-delete__summary {
  list-style: none;
  color: var(--af-danger);
}

.af-inline-delete__summary::-webkit-details-marker {
  display: none;
}

.af-inline-delete__summary:hover {
  color: var(--af-danger-ink);
  border-color: color-mix(in srgb, var(--af-danger) 32%, var(--af-line));
  background: var(--af-danger-soft);
}

.af-inline-delete[open] .af-inline-delete__summary {
  color: var(--af-danger-ink);
  background: var(--af-danger-soft);
  border-color: color-mix(in srgb, var(--af-danger) 32%, var(--af-line));
}

.af-inline-delete__panel {
  position: absolute;
  z-index: 35;
  right: 0;
  top: calc(100% + 8px);
  width: min(280px, 70vw);
  padding: 12px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface);
  box-shadow: var(--af-shadow-pop);
}

.af-inline-delete__panel p {
  margin: 0 0 10px;
  color: var(--af-ink-2);
  font-size: 12.5px;
  line-height: 1.4;
}

.af-inline-delete__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.af-row--modules-catalog-scoped .af-row__actions {
  gap: 8px;
}

@media (max-width: 760px) {
  .af-inline-delete__panel {
    position: static;
    width: 100%;
    margin-top: 8px;
  }
}
/* =========================================================================
   v152.8 — Matières : alignement design livré
   -------------------------------------------------------------------------
   - barre de filtres compacte / dépliable
   - bouton Ajouter en haut à droite
   - drawer latéral ajout / édition
   - table Référence / Intitulé / Sem. / Périmètre / Volume / Actions
   ========================================================================= */

.af-subject-titlebar {
  align-items: flex-start;
  margin-bottom: 18px;
}

.af-subject-add-btn {
  margin-top: 8px;
  white-space: nowrap;
}

.af-subject-filterbar {
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-xl);
  margin-bottom: 18px;
  overflow: hidden;
}

.af-subject-filterbar__form {
  display: flex;
  flex-direction: column;
}

.af-subject-filterbar__summary {
  display: grid;
  grid-template-columns: minmax(220px, auto) minmax(260px, 340px) 1fr;
  align-items: center;
  gap: 14px;
  padding: 12px 18px;
}

.af-subject-filterbar__toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--af-ink-2);
  font-size: 13.5px;
  padding: 5px 0;
  cursor: pointer;
  text-align: left;
}

.af-subject-filterbar__toggle strong {
  color: var(--af-ink);
  font-weight: 700;
}

.af-subject-filterbar__toggle span {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--af-ink-3);
}

.af-subject-filterbar__chev {
  transition: transform .16s ease;
  flex: 0 0 auto;
}

.af-subject-filterbar--collapsed .af-subject-filterbar__chev {
  transform: rotate(-90deg);
}

.af-subject-search {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 8px 13px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-bg);
  color: var(--af-ink-3);
}

.af-subject-search input {
  min-width: 0;
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--af-ink);
  font-size: 13.5px;
}

.af-subject-count {
  justify-self: end;
  color: var(--af-ink-2);
  font-size: 13.5px;
  white-space: nowrap;
}

.af-subject-filterbar__panel {
  padding: 0 18px 18px;
  border-top: 1px solid var(--af-line-2);
}

.af-subject-filterbar--collapsed .af-subject-filterbar__panel {
  display: none;
}

.af-subject-filters-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(180px, 1fr));
  gap: 14px 16px;
  padding-top: 14px;
}

.af-subject-filterbar__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 16px;
}

.af-subject-table {
  border-radius: var(--af-r-xl);
}

.af-row--subject-designer {
  grid-template-columns: 150px minmax(300px, 1fr) 74px 120px 150px 176px;
  gap: 16px;
  align-items: center;
}

.af-row--subject-designer.af-row--head {
  color: var(--af-ink-3);
}

.af-subject-ref,
.af-subject-main,
.af-module-hours {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.af-subject-ref strong {
  font-family: var(--af-font-mono);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--af-ink-2);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.af-subject-ref small,
.af-subject-main small,
.af-module-hours small {
  color: var(--af-ink-3);
  font-size: 12px;
  line-height: 1.25;
}

.af-subject-line {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

.af-subject-line strong {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 15px;
  color: var(--af-ink);
}

.af-subject-main .af-code {
  flex: 0 0 auto;
  border: 0;
  background: var(--af-info-soft);
  color: var(--af-info-ink);
  font-weight: 700;
}

.af-module-hours strong {
  font-weight: 500;
  color: var(--af-ink);
}

.af-volume-missing-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  width: fit-content;
  padding: 4px 9px;
  border-radius: var(--af-r-pill);
  background: var(--af-warn-soft);
  color: var(--af-warn-ink);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.25;
  white-space: nowrap;
}

.af-volume-missing-badge > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: var(--af-r-pill);
  background: var(--af-warn);
  color: var(--af-on-color);
  font-family: var(--af-font-mono);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.af-subject-actions {
  gap: 10px;
}

.af-subject-delete-link {
  opacity: .86;
}

.af-row__actions .af-inline-delete {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.af-inline-delete__summary {
  list-style: none;
}

.af-inline-delete__summary::-webkit-details-marker {
  display: none;
}

.af-inline-delete__panel {
  position: absolute;
  z-index: 35;
  right: 0;
  top: calc(100% + 8px);
  width: min(280px, 70vw);
  padding: 12px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface);
  box-shadow: var(--af-shadow-pop);
}

.af-inline-delete__panel p {
  margin: 0 0 10px;
  color: var(--af-ink-2);
  font-size: 12.5px;
  line-height: 1.4;
}

.af-inline-delete__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.af-subject-drawer {
  width: 430px;
}

.af-subject-drawer .af-drawer__head {
  padding-top: 26px;
}

.af-subject-drawer__form {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}

.af-subject-drawer__legend {
  margin: 26px 0 12px;
  padding-top: 20px;
  border-top: 1px solid var(--af-line-2);
  color: var(--af-ink-2);
  font-size: 13px;
  font-weight: 600;
}

.af-subject-drawer__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 16px;
}

.af-subject-drawer__grid .af-help {
  line-height: 1.45;
}

.af-subject-drawer .af-module-readonly-metrics {
  margin-top: 20px;
}

@media (max-width: 1160px) {
  .af-subject-filters-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-row--subject-designer { grid-template-columns: 130px minmax(250px, 1fr) 68px 110px 130px 150px; }
}

@media (max-width: 860px) {
  .af-subject-filterbar__summary { grid-template-columns: 1fr; }
  .af-subject-count { justify-self: start; }
  .af-row--subject-designer { grid-template-columns: 1fr; gap: 8px; align-items: start; }
  .af-row--subject-designer.af-row--head { display: none; }
  .af-subject-actions { justify-content: flex-start; }
}

@media (max-width: 560px) {
  .af-subject-titlebar { flex-direction: column; align-items: stretch; }
  .af-subject-add-btn { justify-content: center; }
  .af-subject-filters-grid { grid-template-columns: 1fr; }
  .af-subject-drawer { width: 100%; max-width: 100%; }
  .af-subject-drawer__grid { grid-template-columns: 1fr; }
  .af-inline-delete__panel { position: static; width: 100%; margin-top: 8px; }
}
/* =========================================================================
   v154 — Classes : lien profil étudiant depuis la liste des étudiants
   -------------------------------------------------------------------------
   Rend le nom de l'étudiant cliquable vers la fiche profil / assiduité.
   ========================================================================= */
.af-student-name-link {
  color: inherit;
  text-decoration: none;
  border-radius: var(--af-r-sm);
}

.af-student-name-link:hover {
  color: var(--af-action-hover);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.af-student-name-link:focus-visible {
  outline: 2px solid var(--af-action);
  outline-offset: 3px;
}
/* =========================================================================
   v152.9 — Classes : correction responsive liste des étudiants
   -------------------------------------------------------------------------
   Objectif : empêcher la grille étudiants de se replier sur 4 colonnes à
   partir de 1080px, ce qui empile les actions QR/lien/suppression sous le
   groupe TP. La table reste lisible en tablette et bascule en cartes sur
   mobile.
   ========================================================================= */

/* Grille desktop/tablette : 7 colonnes réelles, alignées avec le markup. */
.af-table .af-row.af-row--students {
  grid-template-columns:
    42px
    minmax(190px, 1.35fr)
    minmax(170px, 1fr)
    minmax(105px, .65fr)
    minmax(76px, .45fr)
    minmax(72px, .40fr)
    minmax(170px, auto);
  gap: 12px;
}

.af-table .af-row.af-row--students > * {
  min-width: 0;
}

.af-table .af-row.af-row--students .af-row__updated {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.af-row__actions--student-access {
  display: inline-flex;
  justify-content: flex-end;
  align-items: center;
  gap: 5px;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.af-row__actions--student-access .af-icon-btn {
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
}

/* Le breakpoint global .af-row à 1080px cassait les lignes étudiants.
   On le neutralise uniquement pour cette table. */
@media (max-width: 1080px) {
  .af-table .af-row.af-row--students {
    grid-template-columns:
      38px
      minmax(175px, 1.25fr)
      minmax(150px, .95fr)
      minmax(95px, .58fr)
      minmax(68px, .42fr)
      minmax(62px, .36fr)
      minmax(158px, auto) !important;
    min-width: 860px;
  }

  .af-table .af-row.af-row--students .af-row__updated {
    display: block !important;
  }

  .af-table .af-row.af-row--students .af-row__actions {
    display: inline-flex !important;
  }

  .af-table[aria-label] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Mobile : une ligne étudiant devient une carte lisible.
   Les intitulés sont ajoutés en CSS pour éviter de modifier le PHP. */
@media (max-width: 720px) {
  .af-table:has(.af-row--students) {
    border: 0;
    background: transparent;
    overflow: visible;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .af-table .af-row.af-row--students.af-row--head {
    display: none;
  }

  .af-table article.af-row.af-row--students {
    min-width: 0;
    display: grid;
    grid-template-columns: 38px minmax(0, 1fr) auto;
    grid-template-areas:
      "avatar name sign"
      "avatar email sign"
      "avatar number actions"
      "group group actions";
    gap: 6px 10px;
    padding: 14px;
    border: 1px solid var(--af-line);
    border-radius: var(--af-r-lg);
    background: var(--af-surface);
  }

  .af-table article.af-row.af-row--students + article.af-row.af-row--students {
    border-top: 1px solid var(--af-line);
  }

  .af-table article.af-row.af-row--students > :nth-child(1) {
    grid-area: avatar;
    align-self: start;
  }

  .af-table article.af-row.af-row--students > :nth-child(2) {
    grid-area: name;
    font-size: 14.5px;
    line-height: 1.25;
  }

  .af-table article.af-row.af-row--students > :nth-child(3) {
    grid-area: email;
    color: var(--af-ink-3);
    font-size: 12.5px;
  }

  .af-table article.af-row.af-row--students > :nth-child(4) {
    grid-area: number;
    display: inline-flex !important;
    align-items: center;
    gap: 6px;
    color: var(--af-ink-2);
    font-size: 12.5px;
  }

  .af-table article.af-row.af-row--students > :nth-child(4)::before {
    content: "ID étudiant";
    color: var(--af-ink-3);
    font-size: 11.5px;
    font-weight: 500;
  }

  .af-table article.af-row.af-row--students > :nth-child(5) {
    grid-area: group;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
  }

  .af-table article.af-row.af-row--students > :nth-child(5)::before {
    content: "Groupe TP";
    color: var(--af-ink-3);
    font-size: 11.5px;
    font-weight: 500;
  }

  .af-table article.af-row.af-row--students > :nth-child(6) {
    grid-area: sign;
    justify-self: end;
  }

  .af-table article.af-row.af-row--students > :nth-child(7) {
    grid-area: actions;
    justify-self: end;
    align-self: end;
    flex-wrap: wrap;
    max-width: 104px;
    gap: 4px;
  }

  .af-row__actions--student-access .af-icon-btn {
    width: 28px;
    height: 28px;
    flex-basis: 28px;
  }
}

@media (max-width: 420px) {
  .af-table article.af-row.af-row--students {
    grid-template-columns: 34px minmax(0, 1fr);
    grid-template-areas:
      "avatar name"
      "avatar email"
      "avatar number"
      "group group"
      "sign sign"
      "actions actions";
  }

  .af-table article.af-row.af-row--students > :nth-child(6),
  .af-table article.af-row.af-row--students > :nth-child(7) {
    justify-self: start;
  }

  .af-table article.af-row.af-row--students > :nth-child(7) {
    max-width: none;
    justify-content: flex-start;
  }
}
/* =========================================================================
   v163 — Correctif mobile global AlterForge
   -------------------------------------------------------------------------
   Objectif : stabiliser l'affichage iPhone / mobile sans toucher au PHP.
   - Comptes : transformation de la table en cartes lisibles.
   - Classes : transformation de la liste des classes en cartes dès tablette.
   - Shell mobile : topbar, titre, formulaires et cartes moins larges.
   - Matières : petites sécurités anti-débordement sur les lignes mobiles.
   ========================================================================= */

/* Sécurité globale : évite les débordements horizontaux causés par des grilles
   héritées ou des libellés longs. */
html,
body {
  max-width: 100%;
  overflow-x: hidden;
}

.af-main,
.af-col,
.af-table,
.af-card,
.af-section,
.af-section--card,
.af-row,
.af-field,
.af-input,
.af-select,
.af-textarea {
  min-width: 0;
}

.af-row > * {
  min-width: 0;
}

/* -------------------------------------------------------------------------
   Shell mobile : topbar + contenu
   ------------------------------------------------------------------------- */
@media (max-width: 720px) {
  .af-main {
    width: 100%;
    max-width: 100%;
    padding: 18px 14px 82px;
    overflow-x: hidden;
  }

  .af-top {
    padding: 8px 14px;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }

  .af-top .af-search {
    order: 20;
    flex: 1 1 100%;
    min-width: 0;
    width: 100%;
  }

  .af-top__right {
    margin-left: 0;
    flex: 1 1 auto;
    min-width: 0;
    gap: 7px;
    flex-wrap: wrap;
    justify-content: flex-start;
  }

  .af-user {
    min-width: 0;
    max-width: 160px;
    padding-right: 8px;
  }

  .af-user__name {
    min-width: 0;
  }

  .af-user__name strong,
  .af-user__name span {
    max-width: 104px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .af-h1 {
    font-size: 30px;
    line-height: 1.08;
  }

  .af-h2,
  .af-section__title {
    line-height: 1.15;
  }

  .af-sub {
    max-width: 100%;
  }

  .af-titlebar,
  .af-section__header,
  .af-detail-header__actions,
  .af-form-actions {
    gap: 10px;
  }

  .af-card,
  .af-section--card,
  .af-detail-header {
    padding: 18px 16px;
  }

  .af-tabs-page {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 18px;
  }

  .af-tab-page {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .af-form-grid,
  .af-form-grid--modules-edit,
  .af-subject-drawer__grid {
    grid-template-columns: 1fr !important;
  }

  .af-form-inline,
  .af-att-alert-filters__actions {
    align-items: stretch;
  }

  .af-form-inline > *,
  .af-form-actions > .af-btn-primary,
  .af-form-actions > .af-btn-secondary,
  .af-form-actions > .af-btn-ghost {
    max-width: 100%;
  }
}

/* -------------------------------------------------------------------------
   Page Comptes / utilisateurs : table -> cartes mobile
   Markup : admin/users.php, .af-row--users
   ------------------------------------------------------------------------- */
.af-row--users {
  grid-template-columns:
    minmax(190px, 1.25fr)
    minmax(220px, 1.15fr)
    minmax(110px, .7fr)
    minmax(160px, 1fr)
    minmax(90px, .55fr)
    minmax(112px, .55fr);
  gap: 14px;
  align-items: center;
}

.af-row--users .af-row__name {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.af-row--users .af-row__name > span:last-child {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.af-row--users .af-row__name strong,
.af-row--users .af-row__updated {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.af-row--users > span:nth-child(4) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

@media (max-width: 1080px) {
  /* Neutralise le breakpoint générique .af-row qui masque .af-row__updated. */
  .af-row--users .af-row__updated {
    display: block !important;
  }
}

@media (max-width: 760px) {
  .af-table:has(.af-row--users) {
    border: 0;
    background: transparent;
    overflow: visible;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .af-row--users.af-row--head {
    display: none !important;
  }

  .af-table article.af-row.af-row--users {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "account"
      "email"
      "role"
      "rights"
      "status"
      "actions";
    gap: 8px;
    padding: 14px;
    border: 1px solid var(--af-line);
    border-radius: var(--af-r-lg);
    background: var(--af-surface);
  }

  .af-table article.af-row.af-row--users + article.af-row.af-row--users {
    border-top: 1px solid var(--af-line);
  }

  .af-row--users > span:nth-child(1) {
    grid-area: account;
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr);
    column-gap: 10px;
    align-items: start;
  }

  .af-row--users > span:nth-child(1) .af-avatar-sm {
    grid-column: 1;
    grid-row: 1 / span 2;
  }

  .af-row--users > span:nth-child(1) > span:last-child {
    grid-column: 2;
  }

  .af-row--users > span:nth-child(2) {
    grid-area: email;
    display: block !important;
    color: var(--af-ink-3);
    font-size: 12.5px;
    overflow-wrap: anywhere;
    white-space: normal;
  }

  .af-row--users > span:nth-child(3) {
    grid-area: role;
  }

  .af-row--users > span:nth-child(4) {
    grid-area: rights;
  }

  .af-row--users > span:nth-child(5) {
    grid-area: status;
  }

  .af-row--users > span:nth-child(6) {
    grid-area: actions;
    justify-content: flex-start;
  }

  .af-row--users > span:nth-child(3)::before,
  .af-row--users > span:nth-child(4)::before,
  .af-row--users > span:nth-child(5)::before {
    display: inline-flex;
    min-width: 58px;
    margin-right: 8px;
    color: var(--af-ink-3);
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
  }

  .af-row--users > span:nth-child(3)::before { content: "Rôle"; }
  .af-row--users > span:nth-child(4)::before { content: "Droits"; }
  .af-row--users > span:nth-child(5)::before { content: "Statut"; }

  .af-row--users .af-pill {
    max-width: 100%;
    white-space: normal;
    line-height: 1.25;
  }

  .af-row--users .af-btn-secondary {
    justify-content: center;
  }
}

/* -------------------------------------------------------------------------
   Page Classes : liste des classes -> cartes tablette/mobile
   Markup : admin/classes.php, .af-row--classes
   ------------------------------------------------------------------------- */
.af-row--classes .af-row__name {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: normal;
}

.af-row--classes .af-row__name small {
  display: inline-block;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: normal;
}

@media (max-width: 900px) {
  .af-table:has(.af-row--classes) {
    border: 0;
    background: transparent;
    overflow: visible;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .af-row--classes.af-row--head {
    display: none !important;
  }

  .af-table article.af-row.af-row--classes {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
    padding: 16px 14px;
    border: 1px solid var(--af-line);
    border-radius: var(--af-r-lg);
    background: var(--af-surface);
  }

  .af-table article.af-row.af-row--classes + article.af-row.af-row--classes {
    border-top: 1px solid var(--af-line);
  }

  .af-row--classes > span:nth-child(1) {
    font-size: 15px;
    line-height: 1.35;
  }

  .af-row--classes > span:nth-child(2) {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: fit-content;
    padding: 4px 9px;
    border-radius: var(--af-r-pill);
    background: var(--af-info-soft);
    color: var(--af-info-ink);
    font-size: 12.5px;
    font-weight: 600;
  }

  .af-row--classes > span:nth-child(2)::after {
    content: "étudiant(s)";
    color: var(--af-info-ink);
    font-weight: 500;
  }

  .af-row--classes .af-row__actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 8px;
    position: static !important;
  }

  .af-row--classes .af-btn-secondary {
    justify-content: center;
  }
}

@media (max-width: 420px) {
  .af-row--classes .af-row__actions > .af-btn-secondary {
    flex: 1 1 auto;
  }
}

/* -------------------------------------------------------------------------
   Matières / modules : sécurités mobiles complémentaires
   ------------------------------------------------------------------------- */
@media (max-width: 760px) {
  .af-subject-line,
  .af-subject-main,
  .af-subject-ref,
  .af-module-hours {
    min-width: 0;
  }

  .af-subject-line {
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 6px;
  }

  .af-subject-line strong {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .af-subject-actions,
  .af-row--subject-designer .af-row__actions {
    justify-content: flex-start;
    flex-wrap: wrap;
  }

  .af-volume-missing-badge {
    white-space: normal;
    max-width: 100%;
  }
}

/* -------------------------------------------------------------------------
   Petits écrans : boutons et champs évitent les débordements.
   ------------------------------------------------------------------------- */
@media (max-width: 420px) {
  .af-btn-primary,
  .af-btn-secondary,
  .af-btn-ghost,
  .af-btn-danger {
    max-width: 100%;
  }

  .af-search input,
  .af-input,
  .af-select,
  .af-textarea {
    font-size: 16px; /* évite le zoom automatique iOS au focus */
  }
}
/* =========================================================================
   v164 — Correctif topbar mobile AlterForge
   -------------------------------------------------------------------------
   Objectif : réduire la hauteur de la barre supérieure sur iPhone/mobile.
   - Ligne 1 : menu à gauche, alertes/langue/compte/déconnexion à droite.
   - Ligne 2 : recherche pleine largeur.
   - Compte compact : avatar uniquement.
   - Déconnexion compacte : icône texte CSS, sans changer le HTML.
   ========================================================================= */

@media (max-width: 720px) {
  .af-top {
    display: grid !important;
    grid-template-columns: 38px minmax(0, 1fr);
    grid-template-areas:
      "menu meta"
      "search search";
    align-items: center;
    gap: 8px 10px;
    padding: 8px 14px 10px !important;
  }

  .af-top .af-burger {
    grid-area: menu;
    width: 38px;
    height: 38px;
    margin: 0;
    display: inline-flex !important;
    flex: 0 0 38px;
  }

  .af-top__right {
    grid-area: meta;
    display: flex !important;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: nowrap !important;
    gap: 6px;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    margin-left: 0 !important;
  }

  .af-top .af-search {
    grid-area: search;
    order: initial !important;
    flex: none !important;
    width: 100%;
    min-width: 0;
    padding: 7px 10px;
    min-height: 36px;
    border-radius: var(--af-r-md);
  }

  .af-top .af-search input {
    min-width: 0;
    width: 100%;
  }

  .af-top .af-kbd {
    display: none !important;
  }

  /* Badge alertes : on garde icône + compteur, pas le libellé. */
  .af-top .af-att-alert-badge,
  .af-top__right .af-att-alert-badge {
    flex: 0 0 auto;
    min-width: 48px;
    max-width: 58px;
    height: 34px;
    padding: 6px 8px !important;
    gap: 5px !important;
    overflow: hidden;
  }

  .af-top .af-att-alert-badge__label,
  .af-top__right .af-att-alert-badge__label {
    display: none !important;
  }

  /* Sélecteur FR · EN généré sans classe par lang_switcher(). */
  .af-top__right > strong,
  .af-top__right > a[href*="lang="] {
    flex: 0 0 auto;
    font-size: 12px !important;
    line-height: 1;
    white-space: nowrap;
  }

  /* Compte : avatar seul sur mobile. */
  .af-top .af-user {
    flex: 0 0 38px;
    width: 38px;
    height: 38px;
    max-width: 38px;
    min-width: 38px;
    padding: 0 !important;
    justify-content: center;
    border-radius: var(--af-r-pill);
  }

  .af-top .af-user .af-avatar {
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    font-size: 11px;
  }

  .af-top .af-user__name {
    display: none !important;
  }

  /* Déconnexion : bouton compact pour éviter une ligne dédiée. */
  .af-top__right > .af-btn-ghost[href*="logout.php"] {
    flex: 0 0 38px;
    width: 38px;
    height: 34px;
    min-width: 38px;
    max-width: 38px;
    padding: 0 !important;
    justify-content: center;
    font-size: 0 !important;
    line-height: 1;
    overflow: hidden;
  }

  .af-top__right > .af-btn-ghost[href*="logout.php"]::before {
    content: "↪";
    font-size: 16px;
    line-height: 1;
    color: var(--af-ink-2);
  }
}

@media (max-width: 420px) {
  .af-top {
    grid-template-columns: 34px minmax(0, 1fr);
    gap: 7px 8px;
    padding: 8px 12px 10px !important;
  }

  .af-top .af-burger {
    width: 34px;
    height: 34px;
    flex-basis: 34px;
  }

  .af-top__right {
    gap: 5px;
  }

  .af-top .af-att-alert-badge,
  .af-top__right .af-att-alert-badge {
    min-width: 44px;
    max-width: 52px;
    height: 32px;
    padding-left: 7px !important;
    padding-right: 7px !important;
  }

  .af-top .af-user {
    flex-basis: 34px;
    width: 34px;
    height: 34px;
    min-width: 34px;
    max-width: 34px;
  }

  .af-top .af-user .af-avatar {
    width: 28px;
    height: 28px;
    flex-basis: 28px;
  }

  .af-top__right > .af-btn-ghost[href*="logout.php"] {
    flex-basis: 34px;
    width: 34px;
    min-width: 34px;
    max-width: 34px;
    height: 32px;
  }

  .af-top__right > strong,
  .af-top__right > a[href*="lang="] {
    font-size: 11.5px !important;
  }
}
/* =========================================================================
   v165 — Groupes pédagogiques
   Gestion des audiences transversales : LVA/LVB, options, projets.
   À appender en bas de css/common.css.
   ========================================================================= */

.af-pg-titlebar .af-titlebar__actions,
.af-pg-detail__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.af-pg-filter-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px 18px;
  align-items: end;
}
.af-pg-filter-grid__search { grid-column: span 2; }
.af-pg-filter-grid__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.af-pg-form {
  display: grid;
  grid-template-columns: 1.4fr 150px 160px 120px repeat(2, minmax(160px, 1fr));
  gap: 14px 16px;
  align-items: end;
  max-width: none;
}
.af-pg-form__label { grid-column: span 2; }
.af-pg-form__full { grid-column: 1 / -1; }
.af-pg-form__actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.af-pg-form--edit {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding-top: 12px;
}
.af-pg-form--edit .af-pg-form__label { grid-column: span 2; }

.af-pg-layout {
  display: grid;
  grid-template-columns: minmax(320px, 0.95fr) minmax(0, 1.55fr);
  gap: 18px;
  align-items: start;
}
.af-pg-list,
.af-pg-detail { min-width: 0; }

.af-pg-group-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.af-pg-group-card {
  display: grid;
  gap: 7px;
  padding: 13px 14px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  transition: border-color .12s ease, background-color .12s ease, box-shadow .12s ease;
}
.af-pg-group-card:hover {
  border-color: var(--af-action);
  background: var(--af-surface-soft);
}
.af-pg-group-card--active {
  border-color: color-mix(in srgb, var(--af-action) 46%, var(--af-line));
  background: var(--af-action-soft);
  box-shadow: inset 3px 0 0 var(--af-action);
}
.af-pg-group-card strong {
  color: var(--af-ink);
  font-size: 14.5px;
  line-height: 1.25;
}
.af-pg-card-foot {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

.af-pg-members-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 22px;
}
.af-pg-member-list,
.af-pg-candidate-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.af-pg-member {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid var(--af-line-2);
}
.af-pg-member:first-child { border-top: 0; }
.af-pg-member__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.af-pg-member__body strong {
  color: var(--af-ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-pg-member__body span,
.af-pg-member__body small {
  color: var(--af-ink-3);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-pg-member__action {
  display: flex;
  justify-content: flex-end;
}
.af-pg-member--candidate {
  background: var(--af-surface-soft);
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-md);
  padding: 10px;
}
.af-pg-candidate-search {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  margin-bottom: 12px;
}

@media (max-width: 1180px) {
  .af-pg-filter-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-pg-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-pg-form__label { grid-column: span 1; }
  .af-pg-layout { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .af-pg-titlebar .af-titlebar__actions,
  .af-pg-detail__actions {
    width: 100%;
    justify-content: flex-start;
  }
  .af-pg-filter-grid,
  .af-pg-form,
  .af-pg-form--edit,
  .af-pg-members-grid {
    grid-template-columns: 1fr;
  }
  .af-pg-filter-grid__search,
  .af-pg-form__label,
  .af-pg-form--edit .af-pg-form__label {
    grid-column: auto;
  }
  .af-pg-filter-grid__actions,
  .af-pg-form__actions {
    justify-content: stretch;
  }
  .af-pg-filter-grid__actions > *,
  .af-pg-form__actions > * {
    flex: 1 1 auto;
    justify-content: center;
  }
  .af-pg-member {
    grid-template-columns: 28px minmax(0, 1fr);
  }
  .af-pg-member__action {
    grid-column: 2;
    justify-content: flex-start;
  }
  .af-pg-candidate-search {
    grid-template-columns: 1fr;
  }
}
/* =========================================================================
   v166 — Composition fine des groupes pédagogiques
   À appender après common_v165_pedagogical_groups.css.
   ========================================================================= */

.af-pg-composition {
  margin-top: 18px;
  padding: 16px 0 0;
  border-top: 1px solid var(--af-line-2);
}
.af-pg-composition__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.af-pg-composition .af-card__title { margin-bottom: 4px; }
.af-pg-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(96px, 1fr));
  gap: 0;
  overflow: hidden;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
}
.af-pg-kpis span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 9px 12px;
  border-left: 1px solid var(--af-line-2);
  color: var(--af-ink-3);
  font-size: 12px;
  line-height: 1.2;
}
.af-pg-kpis span:first-child { border-left: 0; }
.af-pg-kpis strong {
  font-family: var(--af-font-serif);
  font-size: 22px;
  line-height: 1;
  color: var(--af-ink);
  font-weight: 500;
}
.af-pg-members-grid--composition {
  gap: 24px;
}
.af-pg-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.af-pg-panel-head .af-card__title { margin-bottom: 2px; }
.af-pg-member-list--selectable,
.af-pg-candidate-list--selectable { margin-top: 10px; }
.af-pg-member-list--selectable .af-pg-member,
.af-pg-candidate-list--selectable .af-pg-member {
  grid-template-columns: 22px 28px minmax(0, 1fr) auto;
}
.af-pg-member__check {
  justify-content: center;
  gap: 0;
}
.af-pg-member__check input {
  width: 16px;
  height: 16px;
}
.af-pg-member--warn {
  background: var(--af-warn-soft);
  border-radius: var(--af-r-md);
  padding-left: 8px;
  padding-right: 8px;
}
.af-pg-warning {
  color: var(--af-warn-ink) !important;
  font-weight: 600;
}
.af-pg-bulkbar {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px dashed var(--af-line-2);
}
.af-pg-candidate-search--advanced {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 12px;
  align-items: end;
  margin-bottom: 12px;
}
.af-pg-candidate-search__q { grid-column: span 2; }
.af-pg-candidate-search__actions {
  display: flex;
  justify-content: flex-end;
}
.af-pg-add-filtered {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 12px;
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
}
.af-pg-add-filtered .af-help {
  margin: 0;
}
.af-pg-add-one,
.af-pg-remove-one {
  white-space: nowrap;
}
.af-pg-candidate-list--selectable .af-pg-member--candidate:first-child {
  border-top: 1px solid var(--af-line-2);
}

@media (max-width: 1180px) {
  .af-pg-candidate-search--advanced {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .af-pg-candidate-search__q { grid-column: span 1; }
  .af-pg-candidate-search__actions { justify-content: flex-start; }
}

@media (max-width: 760px) {
  .af-pg-composition__head { align-items: stretch; }
  .af-pg-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-pg-kpis span:nth-child(odd) { border-left: 0; }
  .af-pg-kpis span:nth-child(n+3) { border-top: 1px solid var(--af-line-2); }
  .af-pg-candidate-search--advanced { grid-template-columns: 1fr; }
  .af-pg-member-list--selectable .af-pg-member,
  .af-pg-candidate-list--selectable .af-pg-member {
    grid-template-columns: 22px 28px minmax(0, 1fr);
  }
  .af-pg-add-one,
  .af-pg-remove-one {
    grid-column: 3;
    justify-self: flex-start;
  }
  .af-pg-bulkbar { justify-content: stretch; }
  .af-pg-bulkbar > * { flex: 1 1 auto; justify-content: center; }
}

@media (max-width: 480px) {
  .af-pg-kpis { grid-template-columns: 1fr; }
  .af-pg-kpis span { border-left: 0; border-top: 1px solid var(--af-line-2); }
  .af-pg-kpis span:first-child { border-top: 0; }
}
/* =========================================================================
   v165 — Groupes pédagogiques
   Gestion des audiences transversales : LVA/LVB, options, projets.
   À appender en bas de css/common.css.
   ========================================================================= */

.af-pg-titlebar .af-titlebar__actions,
.af-pg-detail__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.af-pg-filter-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px 18px;
  align-items: end;
}
.af-pg-filter-grid__search { grid-column: span 2; }
.af-pg-filter-grid__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.af-pg-form {
  display: grid;
  grid-template-columns: 1.4fr 150px 160px 120px repeat(2, minmax(160px, 1fr));
  gap: 14px 16px;
  align-items: end;
  max-width: none;
}
.af-pg-form__label { grid-column: span 2; }
.af-pg-form__full { grid-column: 1 / -1; }
.af-pg-form__actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.af-pg-form--edit {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding-top: 12px;
}
.af-pg-form--edit .af-pg-form__label { grid-column: span 2; }

.af-pg-layout {
  display: grid;
  grid-template-columns: minmax(320px, 0.95fr) minmax(0, 1.55fr);
  gap: 18px;
  align-items: start;
}
.af-pg-list,
.af-pg-detail { min-width: 0; }

.af-pg-group-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.af-pg-group-card {
  display: grid;
  gap: 7px;
  padding: 13px 14px;
  background: var(--af-surface);
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  transition: border-color .12s ease, background-color .12s ease, box-shadow .12s ease;
}
.af-pg-group-card:hover {
  border-color: var(--af-action);
  background: var(--af-surface-soft);
}
.af-pg-group-card--active {
  border-color: color-mix(in srgb, var(--af-action) 46%, var(--af-line));
  background: var(--af-action-soft);
  box-shadow: inset 3px 0 0 var(--af-action);
}
.af-pg-group-card strong {
  color: var(--af-ink);
  font-size: 14.5px;
  line-height: 1.25;
}
.af-pg-card-foot {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

.af-pg-members-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 22px;
}
.af-pg-member-list,
.af-pg-candidate-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.af-pg-member {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid var(--af-line-2);
}
.af-pg-member:first-child { border-top: 0; }
.af-pg-member__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.af-pg-member__body strong {
  color: var(--af-ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-pg-member__body span,
.af-pg-member__body small {
  color: var(--af-ink-3);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.af-pg-member__action {
  display: flex;
  justify-content: flex-end;
}
.af-pg-member--candidate {
  background: var(--af-surface-soft);
  border: 1px solid var(--af-line-2);
  border-radius: var(--af-r-md);
  padding: 10px;
}
.af-pg-candidate-search {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  margin-bottom: 12px;
}

@media (max-width: 1180px) {
  .af-pg-filter-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-pg-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-pg-form__label { grid-column: span 1; }
  .af-pg-layout { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .af-pg-titlebar .af-titlebar__actions,
  .af-pg-detail__actions {
    width: 100%;
    justify-content: flex-start;
  }
  .af-pg-filter-grid,
  .af-pg-form,
  .af-pg-form--edit,
  .af-pg-members-grid {
    grid-template-columns: 1fr;
  }
  .af-pg-filter-grid__search,
  .af-pg-form__label,
  .af-pg-form--edit .af-pg-form__label {
    grid-column: auto;
  }
  .af-pg-filter-grid__actions,
  .af-pg-form__actions {
    justify-content: stretch;
  }
  .af-pg-filter-grid__actions > *,
  .af-pg-form__actions > * {
    flex: 1 1 auto;
    justify-content: center;
  }
  .af-pg-member {
    grid-template-columns: 28px minmax(0, 1fr);
  }
  .af-pg-member__action {
    grid-column: 2;
    justify-content: flex-start;
  }
  .af-pg-candidate-search {
    grid-template-columns: 1fr;
  }
}
/* =========================================================================
   v166 — Composition fine des groupes pédagogiques
   À appender après common_v165_pedagogical_groups.css.
   ========================================================================= */

.af-pg-composition {
  margin-top: 18px;
  padding: 16px 0 0;
  border-top: 1px solid var(--af-line-2);
}
.af-pg-composition__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.af-pg-composition .af-card__title { margin-bottom: 4px; }
.af-pg-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(96px, 1fr));
  gap: 0;
  overflow: hidden;
  border: 1px solid var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
}
.af-pg-kpis span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 9px 12px;
  border-left: 1px solid var(--af-line-2);
  color: var(--af-ink-3);
  font-size: 12px;
  line-height: 1.2;
}
.af-pg-kpis span:first-child { border-left: 0; }
.af-pg-kpis strong {
  font-family: var(--af-font-serif);
  font-size: 22px;
  line-height: 1;
  color: var(--af-ink);
  font-weight: 500;
}
.af-pg-members-grid--composition {
  gap: 24px;
}
.af-pg-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.af-pg-panel-head .af-card__title { margin-bottom: 2px; }
.af-pg-member-list--selectable,
.af-pg-candidate-list--selectable { margin-top: 10px; }
.af-pg-member-list--selectable .af-pg-member,
.af-pg-candidate-list--selectable .af-pg-member {
  grid-template-columns: 22px 28px minmax(0, 1fr) auto;
}
.af-pg-member__check {
  justify-content: center;
  gap: 0;
}
.af-pg-member__check input {
  width: 16px;
  height: 16px;
}
.af-pg-member--warn {
  background: var(--af-warn-soft);
  border-radius: var(--af-r-md);
  padding-left: 8px;
  padding-right: 8px;
}
.af-pg-warning {
  color: var(--af-warn-ink) !important;
  font-weight: 600;
}
.af-pg-bulkbar {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px dashed var(--af-line-2);
}
.af-pg-candidate-search--advanced {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 12px;
  align-items: end;
  margin-bottom: 12px;
}
.af-pg-candidate-search__q { grid-column: span 2; }
.af-pg-candidate-search__actions {
  display: flex;
  justify-content: flex-end;
}
.af-pg-add-filtered {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 12px;
  border: 1px dashed var(--af-line);
  border-radius: var(--af-r-lg);
  background: var(--af-surface-soft);
}
.af-pg-add-filtered .af-help {
  margin: 0;
}
.af-pg-add-one,
.af-pg-remove-one {
  white-space: nowrap;
}
.af-pg-candidate-list--selectable .af-pg-member--candidate:first-child {
  border-top: 1px solid var(--af-line-2);
}

@media (max-width: 1180px) {
  .af-pg-candidate-search--advanced {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .af-pg-candidate-search__q { grid-column: span 1; }
  .af-pg-candidate-search__actions { justify-content: flex-start; }
}

@media (max-width: 760px) {
  .af-pg-composition__head { align-items: stretch; }
  .af-pg-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .af-pg-kpis span:nth-child(odd) { border-left: 0; }
  .af-pg-kpis span:nth-child(n+3) { border-top: 1px solid var(--af-line-2); }
  .af-pg-candidate-search--advanced { grid-template-columns: 1fr; }
  .af-pg-member-list--selectable .af-pg-member,
  .af-pg-candidate-list--selectable .af-pg-member {
    grid-template-columns: 22px 28px minmax(0, 1fr);
  }
  .af-pg-add-one,
  .af-pg-remove-one {
    grid-column: 3;
    justify-self: flex-start;
  }
  .af-pg-bulkbar { justify-content: stretch; }
  .af-pg-bulkbar > * { flex: 1 1 auto; justify-content: center; }
}

@media (max-width: 480px) {
  .af-pg-kpis { grid-template-columns: 1fr; }
  .af-pg-kpis span { border-left: 0; border-top: 1px solid var(--af-line-2); }
  .af-pg-kpis span:first-child { border-top: 0; }
}
/* v166.7 — Groupes pédagogiques : filtres LVA/LVB + repères langue lisibles sur les cartes étudiants */
.af-pg-candidate-search--advanced {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
}

.af-pg-candidate-search__q {
  grid-column: span 2;
}

.af-pg-student-langs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
  margin-bottom: 5px;
}

.af-pg-student-badges--context {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 0;
}

.af-pg-student-badge--language {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 24px;
  padding: 3px 8px 3px 6px;
  border-width: 1px;
  border-style: solid;
  border-radius: 999px;
  font-weight: 800;
  line-height: 1.1;
  white-space: nowrap;
}

.af-pg-student-badge--language::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 999px;
  flex: 0 0 auto;
  background: currentColor;
  opacity: .95;
}

.af-pg-lang-prefix {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  padding: 1px 5px;
  border-radius: 999px;
  background: rgba(255,255,255,.55);
  font-size: .68rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.af-pg-student-badge--language strong {
  font: inherit;
  font-weight: 850;
}

.af-pg-student-badge--language small {
  font: inherit;
  font-size: .72rem;
  font-weight: 850;
  opacity: .72;
}

/* Accent latéral : un coup d'œil suffit pour repérer la LVB dominante de la fiche. */
.af-pg-card-lvb {
  border-left-width: 5px;
  border-left-style: solid;
}

.af-pg-card-lvb--en { border-left-color: #0f5f95; }
.af-pg-card-lvb--es { border-left-color: #a04700; }
.af-pg-card-lvb--de { border-left-color: #6b3fb0; }
.af-pg-card-lvb--zh { border-left-color: #b42318; }
.af-pg-card-lvb--fle { border-left-color: #00796b; }

/* Couleurs distinctes par langue. Le texte reste affiché : on ne dépend jamais uniquement de la couleur. */
.af-pg-lang--en {
  color: #0f5f95;
  background: #e8f4ff;
  border-color: #b8dcfa;
}

.af-pg-lang--es {
  color: #a04700;
  background: #fff0d9;
  border-color: #f6c77d;
}

.af-pg-lang--de {
  color: #6b3fb0;
  background: #f0e8ff;
  border-color: #d3c0fb;
}

.af-pg-lang--zh {
  color: #b42318;
  background: #ffe8e5;
  border-color: #ffb8b0;
}

.af-pg-lang--fle {
  color: #00796b;
  background: #e2f7f2;
  border-color: #aee4d8;
}

.af-pg-lang--none {
  color: var(--af-text-muted, #6f675d);
  background: var(--af-surface-soft, #faf7f0);
  border-color: var(--af-border, #e7dfd4);
}

.af-pg-student-badge--lvb {
  box-shadow: inset 0 -2px 0 rgba(0,0,0,.06);
}

@media (max-width: 980px) {
  .af-pg-candidate-search--advanced {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .af-pg-candidate-search__q {
    grid-column: span 1;
  }
}

@media (max-width: 760px) {
  .af-pg-candidate-search--advanced {
    grid-template-columns: 1fr;
  }
  .af-pg-student-langs {
    gap: 4px;
  }
  .af-pg-student-badge--language small {
    display: none;
  }
}
