/* ============================================================================
 * repetiteur.css — LA FEUILLE DE L'ESPACE RÉPÉTITEUR.
 *
 * ⚠ UN FICHIER, PAS UN <style> RECOPIÉ DANS QUATORZE PAGES. C'est la leçon de
 *   live.css, tirée le 2026-08-15 : « 38 Ko l'unité, 376 Ko retéléchargés au fil
 *   d'une navigation, sur des liaisons que ce module qualifie lui-même d'ultra
 *   économie ». Un <style> en ligne n'a pas d'URL, donc pas de cache. Les pages
 *   déclarent  $stu_css_fichiers[] = 'assets/css/repetiteur.css';  et le shell
 *   la sert allégée et versionnée par filemtime.
 *
 * ⚠ AUCUNE COULEUR EN DUR, SAUF LES SÉMANTIQUES. Tout emprunte les jetons du
 *   shell — --ink, --ink2, --ink3, --line, --line2, --surf, --surf2, --blue,
 *   --bl, --bl-025, --green, --amber, --danger. Le rôle « rep » redéfinit --blue
 *   et ses dérivés (stu_role_css) : la teinte du module suit donc le profil sans
 *   qu'une seule règle soit dupliquée. Les états de séance et de devoir, eux, ONT
 *   une sémantique de couleur, et la trahir rendrait un planning illisible.
 *
 * ⚠ TOUT TABLEAU LARGE VIT DANS UN .tbl-wrap (overflow-x:auto) : le corps de la
 *   page ne défile JAMAIS horizontalement. Règle du projet, vérifiée par les
 *   bancs d'affichage mobile.
 * ============================================================================ */

/* ── LE RYTHME VERTICAL DU MODULE ────────────────────────────────────────────
 * 🔴 IL N'EXISTAIT PAS. Le shell donne son rythme à `.sec > .panel + .panel`,
 *    mais les pages du répétiteur empilent des `.sec` dans un `.cc` — que cette
 *    règle ne couvre pas. Chaque page posait donc ses écarts À LA MAIN, en
 *    `style="margin-top:18px"` ici, `22px` là, et rien ailleurs : d'où des
 *    sections tassées, et un rythme différent d'un écran à l'autre.
 *    Signalé le 2026-09-04.
 *
 * ⚠ `* + *` PLUTÔT QU'UNE LISTE DE CLASSES : le jour où une page pose un bloc
 *   d'un type qu'on n'avait pas prévu, il hérite du même écart. Une liste
 *   nommée aurait oublié le suivant — c'est le défaut « N-1 sites sur N ».
 *
 * ⚠ UNE PAGE QUI A TRANCHÉ SON ÉCART GARDE LE SIEN : `[class*="rp-mt"]` est
 *   exclu, comme le shell exclut `lv-mt`.
 *
 * ══ REPRIS LE 2026-09-05 : 26 px ENTRE LES BLOCS, ET **ZÉRO** SOUS LE BANDEAU ══
 * 🔴 MESURÉ, PAS ESTIMÉ. En rendant les dix-sept écrans à 1440 px et en lisant
 *    `getBoundingClientRect()`, l'écart entre le bas du `.hero` et le haut du
 *    premier bloc du `.cc` valait :
 *
 *      repetiteur.php  ·  -parents  ·  -profil  ·  -disponibilites
 *      -alie  ·  -opportunites  ·  -activite  ·  -revisions        →  **0 px**
 *      -eleves · -seances · -planning · -devoirs · -progression    →   26 px
 *      -eleve · -seance · -revenus                                 →   28 px
 *
 *    Huit écrans sur dix-sept collaient donc leur premier bloc au bandeau, bord
 *    à bord — c'est la capture envoyée par le propriétaire : le vert du bandeau,
 *    puis le blanc, sans rien entre les deux. Ce n'était pas un écart trop
 *    court, c'était l'absence d'écart. La règle `.cc > * + *` ne pouvait pas le
 *    voir : elle décrit un intervalle ENTRE DEUX BLOCS, et le premier n'en a
 *    pas avant lui. Et deux règles posées la veille — `.rp-note:first-child` et
 *    `.rp-tabs:first-child` à `margin-top:0` — le clouaient explicitement.
 *
 * ⚠ 32 px, ET C'EST UN NOMBRE DÉJÀ ARGUMENTÉ DANS CE DÉPÔT, pas un de plus.
 *   `shell.css` le pose pour `.cc-air`, la portée des espaces commercial et
 *   modération : « ces écrans empilent des cartes de données denses (tableaux,
 *   matrices, séries), et le rythme du shell y lit serré ». L'espace répétiteur
 *   empile exactement les mêmes ; il prend donc la même valeur, et le même
 *   repli à 22 px sur téléphone, où l'espace vertical se paie.
 *
 * ⚠ ON N'AJOUTE PAS `cc-air` AUX DIX-SEPT PAGES. Ce serait dix-sept occasions
 *   d'en oublier une — le défaut « N-1 sites sur N », relevé neuf fois ici. La
 *   feuille du module est servie par `inclusions/rep_page.php` pour TOUTES les
 *   pages du rôle : une page ne peut pas ne pas l'avoir. Et `.cc-air` porte des
 *   sélecteurs (0,2,2) qui écraseraient les exclusions du module
 *   (`[class*="rp-mt"]`, `[hidden]`), soigneusement posées à (0,2,0).
 *
 * ⚠ `:first-child` COMPTE COMME UNE CLASSE : `.cc > :first-child` pèse (0,2,0),
 *   assez pour l'emporter sur `.cc .rp-outils{margin:26px 0 12px}` et sur
 *   `.cc .rp-note{margin:12px 0}` — mais à égalité, donc l'ordre du fichier
 *   tranche. C'est pourquoi le dernier mot est en FIN DE FEUILLE, où il l'était
 *   déjà pour les mêmes classes. */
/* ⚠ 28 px EST LE STANDARD DE L'APPLICATION, et cette feuille sert AUSSI des
 *   écrans hors du rôle : `chercher-un-repetiteur.php`, `gestion-repetiteurs.php`,
 *   `ma-demande-de-tutorat.php` et les hôtes du fragment de `rep_famille.php`.
 *   Le rythme resserré à 18 px voulu pour l'espace répétiteur vit donc dans
 *   `assets/css/repetiteur-rythme.css`, que SEUL `inclusions/rep_page.php`
 *   déclare — et qui répète ces sélecteurs à l'identique, pour que l'ordre
 *   de chargement tranche sans toucher à une seule spécificité. */
.cc > * + *{margin-top:28px}
.cc > *[class*="rp-mt"] + *,
.cc > * + *[class*="rp-mt"]{margin-top:0}
/* Les blocs cachés ne doivent pas laisser leur écart derrière eux : un panneau
   `hidden` qui garde sa marge creuse un trou que personne ne s'explique. */
.cc > [hidden]{margin-top:0}
/* Le titre d'une section respire au-dessus de son contenu, pas seulement en
   dessous : c'était l'autre moitié de la sensation de tassement.
   ⚠ 16 px, LA MÊME VALEUR QUE `.rp-bloc > .rp-sub` : un titre suivi d'un
     sous-titre et un titre suivi d'un tableau ouvrent le même intervalle. */
.cc .sec > h2:first-child,
.cc .sec > h3:first-child{margin-top:0;margin-bottom:16px}

/* ── LA PAGINATION : CELLE DU SHELL, PAS UNE SECONDE ─────────────────────────
 * 🔴 LE MODULE AVAIT SA PROPRE BARRE (`.rp-pager` : deux chevrons et « 1–5 sur
 *    20 »), quand les cent cinquante autres écrans de Studirium portent celle du
 *    shell (`.pager` : état, numéros de page, « Par page »). Même geste, deux
 *    apparences. Demande du propriétaire, 2026-09-05 : un seul modèle.
 *    Les règles de `.rp-pager`, `.rp-pg-b` et `.rp-pg-e` sont donc RETIRÉES —
 *    les garder aurait laissé un style prêt à ressusciter le doublon.
 *    Le travail est délégué à `stuPaginer()` / `stuCartes()` : voir rep-ui.js.
 *
 * ⚠ IL RESTE UNE CHOSE À DIRE ICI : le pager du shell se pose APRÈS le
 *   conteneur paginé, et le rythme du module (`.cc > * + *`) ne le vise pas —
 *   il n'est pas enfant direct du `.cc` quand la liste vit dans une section. */
.cc .pager{margin-top:14px}

/* ── LE CONTENEUR BLANC DU MODULE (.rp-bloc) ─────────────────────────────────
 * 🔴 LE TABLEAU DE BORD POSAIT SES TUILES À NU SUR LE FOND DE PAGE. Chaque
 *    chiffre était une petite carte isolée, et rien ne disait qu'ils formaient
 *    un ensemble : l'écran se lisait comme une collection d'objets, pas comme
 *    une page. Les autres écrans du module (le répertoire des élèves) posaient
 *    déjà leurs cartes DANS une surface blanche — c'est ce rythme-là qui manquait.
 *    Refonte demandée le 2026-09-04.
 *
 * ⚠ IL PORTE LE FOND, LE TRAIT ET LE RESPIRE — pas l'ombre. Une ombre sur un
 *   grand aplat le fait flotter ; elle reste aux cartes, qui sont des objets.
 *
 * ⚠ ET IL NE S'IMBRIQUE PAS : un `.rp-bloc` dans un `.rp-bloc` empilerait deux
 *   fonds blancs et deux traits, ce qui se voit tout de suite. La règle
 *   descendante l'annule. */
.cc .rp-bloc{background:var(--surf);border:1px solid var(--line);border-radius:18px;
  padding:24px 26px}
.cc .rp-bloc .rp-bloc{background:none;border:0;border-radius:0;padding:0}
.cc .rp-bloc > h3:first-child{margin:0 0 4px;font-size:1rem;font-weight:800;color:var(--ink);
  letter-spacing:-.02em}
.cc .rp-bloc > .rp-sub{margin:0 0 16px}
/* Une grille de blocs garde le même écart que le rythme vertical : deux valeurs
   différentes pour le même intervalle se remarquent sans qu'on sache pourquoi. */
.cc .rp-blocs{display:grid;gap:28px 26px;grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
@media (max-width:640px){.cc .rp-bloc{padding:18px 16px;border-radius:15px}}

/* ── ET `.sec` PORTE LE MÊME FOND — TOUT LE MODULE, 2026-09-05 ───────────────
 *
 * 🔴 SEIZE ÉCRANS SUR DIX-SEPT POSAIENT LEUR CONTENU À NU. `.rp-bloc` a été
 *    écrit le 2026-09-04 pour le tableau de bord, et il a réglé le problème —
 *    sur cette page-là seulement. Partout ailleurs, le module empile des `.sec`,
 *    et `.sec` ne vaut QUE `margin-top:28px` dans `shell.css` : ni fond, ni
 *    trait, ni respire. Les formulaires, les tableaux et les listes flottaient
 *    directement sur le fond de page. Demandé par le propriétaire, mesuré à
 *    l'écran sur `repetiteur-profil.php`.
 *
 * ⚠ MÊMES VALEURS QUE `.rp-bloc`, À LA VIRGULE PRÈS — et c'est le point. Deux
 *   conteneurs blancs qui ne s'accordent pas (un rayon de 18, l'autre de 20 ; un
 *   fond `--surf`, l'autre `--cardg`) se remarquent dès qu'ils voisinent sur la
 *   même page, sans qu'on sache dire pourquoi. On ne crée pas une troisième
 *   surface : on donne à `.sec` celle que le module a déjà choisie.
 *
 * ⚠ ON NE TOUCHE PAS À `.sec` DU SHELL. La règle est préfixée `.cc` ET vit dans
 *   la feuille du module, que seules les pages du répétiteur chargent : les
 *   trois cents autres écrans du dépôt gardent leur `.sec` transparent.
 *
 * ⚠ ET L'IMBRICATION EST ANNULÉE, comme pour `.rp-bloc`. Six pages posent des
 *   `.sec` à deux niveaux d'indentation (dans une `.rp-grid2`, ou l'un dans
 *   l'autre) : sans cette ligne, deux fonds blancs et deux traits se
 *   superposeraient — et cela se voit tout de suite.
 *
 * ⚠ PAS D'OMBRE, pour la même raison que `.rp-bloc` : une ombre sur un grand
 *   aplat le fait flotter. Elle reste aux CARTES, qui sont des objets. */
.cc .sec{background:var(--surf);border:1px solid var(--line);border-radius:18px;
  padding:24px 26px}
.cc .sec .sec,
.cc .rp-bloc .sec,
.cc .sec .rp-bloc{background:none;border:0;border-radius:0;padding:0}
@media (max-width:640px){.cc .sec{padding:18px 16px;border-radius:15px}}

/* ── UN GROUPE DE SECTIONS LIÉES (`.rp-groupe`, 2026-09-05) ──────────────────
 * 🔴 CE QUE LE PROPRIÉTAIRE A VU : « Rapport de suivi » empilait, dans UN SEUL
 *    conteneur blanc, l'identité de l'élève, quatre tuiles, puis trois tableaux
 *    séparés par de simples `<h4>` — « Progression par compétence », « Séances
 *    récentes », « Devoirs ». Trois sujets distincts sans rien pour les séparer
 *    qu'un titre plus petit : l'œil ne sait pas où l'un finit.
 *    Demande du 2026-09-05 : « chaque section dans son conteneur ».
 *
 * ⚠ CE N'EST PAS UNE NOUVELLE CARTE, C'EST UN CONTENANT SANS APPARENCE. Le
 *   groupe ne porte ni fond, ni trait, ni respire — il ne sert qu'à dire « ces
 *   sections-ci vont ensemble », et à les imprimer d'un bloc (`#rpRapport`).
 *   Lui donner un fond aurait produit un conteneur DANS un conteneur, ce que
 *   `.cc .sec .sec` annule justement trois lignes plus haut.
 *
 * ⚠ 18 px À L'INTÉRIEUR, 32 px À L'EXTÉRIEUR, ET L'ÉCART EST LE MESSAGE. Le
 *   rythme du module (32 px) sépare des sujets sans rapport ; à l'intérieur d'un
 *   rapport, les sections sont les chapitres d'un même document. 18 px est la
 *   valeur que `shell.css` donne déjà à deux panneaux voisins d'une rubrique —
 *   ce n'est pas un nombre de plus. C'est aussi ce qui répond au « moins
 *   d'écarts » demandé : on découpe SANS étirer la page.
 *
 * ⚠ IL BAT `.sec{margin-top:28px}` DU SHELL par spécificité (0,2,0 contre
 *   0,1,0) — sans quoi les sections d'un groupe garderaient 28 px, c'est-à-dire
 *   ni le rythme du module ni celui du groupe. */
/* ⚠ LA MARGE DU PREMIER ENFANT S ECHAPPAIT. `.rp-groupe` n a ni bordure ni
 *   remplissage en haut : la marge haute de sa premiere section franchissait
 *   donc sa boite et s ajoutait a la sienne — 28 px mesures la ou la regle en
 *   annoncait 12, sur `repetiteur-documents` et `repetiteur-progression`.
 *   La clouer ici arrete l echappement sans toucher au rythme. */
.cc .rp-groupe > :first-child{margin-top:0}
.cc .rp-groupe > * + *{margin-top:18px}
/* Un groupe n'est jamais une carte : la règle d'annulation vaut aussi pour lui,
   au cas où l'un se trouverait dans une section. */
.cc .sec .rp-groupe,
.cc .rp-bloc .rp-groupe{background:none;border:0;border-radius:0;padding:0}

/* ⚠ UNE SECTION QUI NE PORTE QU'UN ÉTAT VIDE N'A PAS BESOIN DE DOUBLE MARGE :
 *   `.rp-vide` respire déjà de 36 px. On lui retire le padding vertical du
 *   conteneur plutôt que d'obtenir 60 px de blanc autour d'une phrase. */
.cc .sec > .rp-vide:first-child:last-child{padding:18px 12px}

/* Les tuiles d'indicateurs, DANS le bloc : elles perdent leur fond propre, qui
   ferait carte-dans-carte, et gardent leur trait pour rester distinctes. */
/* Hors bloc, les tuiles gardent le rythme du module plutôt que les 18 px du
   shell : c'est le même intervalle que partout ailleurs dans l'espace. */
.cc > .kpis{margin-top:28px}
.cc .rp-bloc .kpis{margin:0}
.cc .rp-bloc .kpi{background:var(--surf2);box-shadow:none}

/* ── Cartes et grilles communes ─────────────────────────────────────────── */
.cc .rp-grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
.cc .rp-grid2{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
/* ── UNE COLONNE DE SECTIONS DANS UNE GRILLE (`repetiteur-profil.php`) ─────
 * 🔴 `.rp-grid2` PEUT RECEVOIR DEUX SORTES D'ENFANTS, et c'est ce qui rendait
 *    cette page dépareillée. Ailleurs dans le rôle ses enfants SONT les blocs
 *    (`.sec`, `.rp-card`) : la grille les étire, une ligne = une hauteur.
 *    Sur le profil, chaque enfant est un CONTENEUR DE COLONNE sans classe qui
 *    empile quatre sections en flux — la grille étire alors les conteneurs,
 *    pas les sections, et la colonne la plus courte s'arrêtait 59 px avant
 *    l'autre (mesuré le 2026-09-05).
 *
 * ⚠ `div:not([class])` VISE EXACTEMENT CES CONTENEURS-LÀ. Un `> div` nu aurait
 *   aussi attrapé les `.rp-card` de `repetiteur-eleves.php`, qui sont des blocs
 *   et non des colonnes : la règle aurait débordé sur des pages qu'elle n'a
 *   rien à corriger.
 *
 * ⚠ LE RYTHME INTERNE EST CELUI DU RÔLE (18 px). Ces sections-ci ne sont PAS
 *   enfants directes de `.cc` : `.cc > * + *` ne les atteint pas, et elles
 *   gardaient donc les 28 px de `.sec` du shell — d'où deux rythmes sur la
 *   même page, l'un resserré, l'autre non.
 *
 * 🔴 ET LA DERNIÈRE SECTION S'ÉTIRE : c'est elle qui fait finir les deux
 *    colonnes à la même hauteur. Décision du propriétaire (2026-09-05) : on
 *    garde les deux colonnes — à gauche ce qui se déclare et qu'un seul bouton
 *    enregistre, à droite ce qui se constate — et l'on aligne les BAS, sans
 *    apparier les blocs deux à deux (ce qui aurait mêlé déclaré et constaté
 *    dans l'ordre de lecture sur téléphone). */
.cc .rp-grid2 > div:not([class]){display:flex;flex-direction:column}
.cc .rp-grid2 > div:not([class]) > .sec{margin-top:18px}
.cc .rp-grid2 > div:not([class]) > .sec:first-child{margin-top:0}
.cc .rp-grid2 > div:not([class]) > .sec:last-child{flex:1 1 auto}
.cc .rp-card{background:var(--cardg,var(--surf));border:1px solid var(--line);border-radius:16px;
  padding:18px 20px;display:flex;flex-direction:column;gap:9px;position:relative;
  transition:border-color .14s,box-shadow .14s}
@media (hover:hover){.cc .rp-card:hover{border-color:var(--bl2);box-shadow:var(--sh)}}
.cc .rp-card h3{margin:0;font-size:1rem;font-weight:800;color:var(--ink);letter-spacing:-.02em}
.cc .rp-card .rp-sub{font-size:.82rem;color:var(--ink3);line-height:1.5}

/* ── Ligne d'élève ──────────────────────────────────────────────────────── */
.cc .rp-el{display:flex;align-items:flex-start;gap:12px}
.cc .rp-ava{width:42px;height:42px;border-radius:12px;flex:0 0 42px;display:grid;place-items:center;
  background:var(--bl);color:var(--blue-7);font-weight:900;font-size:.95rem;letter-spacing:-.02em}
.cc .rp-el-n{font-weight:800;color:var(--ink);font-size:.95rem;line-height:1.3}
.cc .rp-el-c{font-size:.8rem;color:var(--ink3);margin-top:2px}
.cc .rp-el-m{font-size:.78rem;color:var(--ink2);margin-top:4px}

/* ── Pastilles d'état ───────────────────────────────────────────────────── */
.cc .rp-pill{display:inline-flex;align-items:center;gap:5px;font-size:.7rem;font-weight:800;
  border-radius:999px;padding:3px 10px;letter-spacing:.02em;white-space:nowrap}
.cc .rp-pill i{font-size:.85em}
/* Les huit états d'une séance. Programmée et confirmée sont froides (rien n'est
   joué), réalisée est verte (c'est fait), les trois formes d'échec sont
   distinguées : annulée est neutre, l'absence est ambre, le report est bleu. */
.cc .rp-pill.programmee{background:var(--surf2);color:var(--ink2);border:1px solid var(--line)}
/* ⚠ `.info` PARTAGE LA RÈGLE, ELLE NE LA RECOPIE PAS : « vérifié » et
   « confirmée » disent la même chose au lecteur — un état froid, acquis mais
   pas terminal. Deux déclarations identiques auraient dérivé ; c'est la leçon
   des dix copies de `.stu-al` relevées dans shell.css. */
.cc .rp-pill.confirmee,.cc .rp-pill.info{background:var(--bl-025);color:var(--blue-7);border:1px solid var(--bl2)}
.cc .rp-pill.realisee,.cc .rp-pill.ok{background:var(--green-l);color:var(--green);border:1px solid rgba(22,160,106,.25)}
.cc .rp-pill.annulee{background:var(--surf2);color:var(--ink3);border:1px solid var(--line);text-decoration:line-through}
.cc .rp-pill.reportee{background:var(--bl-025);color:var(--info);border:1px solid var(--bl2)}
.cc .rp-pill.absence_eleve,.cc .rp-pill.absence_repetiteur{background:var(--amber-l);color:var(--warn-ink,#8a6116);border:1px solid rgba(234,160,58,.3)}
.cc .rp-pill.attribue{background:var(--surf2);color:var(--ink2);border:1px solid var(--line)}
.cc .rp-pill.remis{background:var(--bl-025);color:var(--blue-7);border:1px solid var(--bl2)}
.cc .rp-pill.corrige{background:var(--green-l);color:var(--green);border:1px solid rgba(22,160,106,.25)}
.cc .rp-pill.retard{background:var(--tint-rg3,#fdecea);color:var(--danger);border:1px solid #f3c9c4}
.cc .rp-pill.actif{background:var(--green-l);color:var(--green)}
.cc .rp-pill.en_attente{background:var(--amber-l);color:var(--warn-ink,#8a6116)}
.cc .rp-pill.archive,.cc .rp-pill.refuse,.cc .rp-pill.clos{background:var(--surf2);color:var(--ink3)}
.cc .rp-pill.prive{background:var(--bl);color:var(--blue-7)}
/* ⚠ LES PASTILLES FROIDES, EN THÈME SOMBRE. Même défaut et même correctif que
   le menu latéral (voir la note de `assets/css/menu-lateral.css`) : `--blue-7`
   porte du blanc, il ne se lit pas SUR une teinte de rôle assombrie — mesuré à
   3,17:1 sur `--bl-025` et 2,83:1 sur `--bl`, contre 5,26 et 4,69 pour
   `--stu-role-k`, le jeton fait pour ça. `--info` suit la même famille et
   tombe pareil. Déclencheur unique `[data-theme="dark"]`, comme partout. */
:root[data-theme="dark"] .cc .rp-pill.confirmee,
:root[data-theme="dark"] .cc .rp-pill.info,
:root[data-theme="dark"] .cc .rp-pill.reportee,
:root[data-theme="dark"] .cc .rp-pill.remis,
:root[data-theme="dark"] .cc .rp-pill.prive{color:var(--stu-role-k)}

/* ── Barres de progression ──────────────────────────────────────────────── */
.cc .rp-bar{height:8px;border-radius:999px;background:var(--surf2);overflow:hidden;position:relative}
.cc .rp-bar i{display:block;height:100%;border-radius:999px;background:var(--blue);transition:width .3s}
.cc .rp-bar.faible i{background:var(--danger)}
.cc .rp-bar.moyen i{background:var(--amber)}
.cc .rp-bar.bon i{background:var(--green)}
.cc .rp-delta{font-size:.74rem;font-weight:800;font-variant-numeric:tabular-nums}
.cc .rp-delta.up{color:var(--green)} .cc .rp-delta.down{color:var(--danger)}
.cc .rp-delta.flat{color:var(--ink3)}

/* ── Planning : la grille de semaine ────────────────────────────────────── */
.cc .rp-sem{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;margin-top:16px}
.cc .rp-jour{background:var(--surf2);border:1px solid var(--line);border-radius:12px;
  padding:8px;min-height:110px;display:flex;flex-direction:column;gap:6px}
.cc .rp-jour.auj{border-color:var(--blue);background:var(--bl-025)}
.cc .rp-jour-h{font-size:.7rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink3);display:flex;justify-content:space-between;align-items:baseline}
.cc .rp-jour-h b{font-size:1rem;color:var(--ink);font-weight:900}
/* ── LA CARTE D'UNE SÉANCE ───────────────────────────────────────────────────
 * 🔴 ELLE ENTASSAIT TOUT EN UNE PHRASE (corrigé le 2026-09-05). L'heure en gras,
 *    puis « Mathématiques Fonctions affines : problèmes » d'un seul tenant :
 *    matière et objet collés, rien pour dire où finit l'un. Et l'ÉTAT ne se
 *    lisait que dans l'opacité — une séance annulée n'était qu'une séance pâle,
 *    ce qui n'est pas une information, c'est un doute.
 *
 * ⚠ QUATRE NIVEAUX, ET L'ORDRE EST CELUI DU REGARD : l'heure (le repère), la
 *   matière (ce que c'est), l'objet (le détail), puis ce qui qualifie. Chacun a
 *   sa taille et son encre ; aucun n'a besoin d'être lu pour trouver le suivant.
 *
 * ⚠ SEUL L'OBJET SE FAIT COUPER, à deux lignes. C'est le seul texte libre — la
 *   matière, elle, tient sur une ligne et se termine par des points de suspension
 *   plutôt que de pousser la colonne. Une carte de calendrier a la largeur d'un
 *   septième d'écran : ce qui ne se borne pas déborde. */
.cc .rp-se{display:flex;flex-direction:column;gap:2px;background:var(--surf);
  border:1px solid var(--line);border-left:3px solid var(--blue);border-radius:9px;
  padding:7px 9px;font-size:.74rem;line-height:1.3;color:var(--ink2);text-decoration:none;
  transition:border-color .14s,box-shadow .14s}
@media (hover:hover){.cc .rp-se:hover{border-color:var(--blue);box-shadow:var(--sh)}}
.cc .rp-se-h{font-size:.8rem;font-weight:900;color:var(--ink);font-variant-numeric:tabular-nums;
  letter-spacing:-.01em}
/* L'heure de fin accompagne celle de début, elle ne la concurrence pas. */
.cc .rp-se-f{font-weight:600;color:var(--ink3);margin-inline-start:3px;font-size:.72rem}
.cc .rp-se-m{font-weight:800;color:var(--ink);font-size:.76rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cc .rp-se-o{color:var(--ink3);font-size:.72rem;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cc .rp-se-p{display:flex;flex-wrap:wrap;gap:4px;margin-top:3px}
/* ⚠ L'ÉTAT EST UNE PASTILLE, PAS UNE OPACITÉ. Elle reprend les teintes que
     `.rp-pill` emploie déjà pour les mêmes mots ailleurs dans le module : la
     couleur ne doit pas vouloir dire deux choses selon l'écran. */
.cc .rp-se-e,.cc .rp-se-n{font-size:.66rem;font-weight:800;border-radius:999px;
  padding:1px 7px;border:1px solid var(--line);color:var(--ink3);background:var(--surf2);
  display:inline-flex;align-items:center;gap:4px}
.cc .rp-se-e{border-color:var(--line2,var(--line));color:var(--ink2)}
.cc .rp-se.realisee{border-left-color:var(--green)}
.cc .rp-se.realisee .rp-se-e{background:var(--green-l);border-color:rgba(22,160,106,.25);color:var(--green)}
/* ⚠ L'ANNULÉE RESTE LISIBLE. Elle valait 0,6 d'opacité — le texte y passait sous
     le contraste minimal, et l'on ne pouvait plus lire CE QUI avait été annulé.
     Le trait gris et la pastille suffisent à le dire. */
.cc .rp-se.annulee,.cc .rp-se.reportee{border-left-color:var(--ink3)}
.cc .rp-se.annulee .rp-se-h,.cc .rp-se.reportee .rp-se-h{text-decoration:line-through;
  text-decoration-thickness:1px;color:var(--ink3)}
.cc .rp-se.absence_eleve,.cc .rp-se.absence_repetiteur{border-left-color:var(--amber)}
.cc .rp-se.absence_eleve .rp-se-e,.cc .rp-se.absence_repetiteur .rp-se-e{
  background:var(--amber-l);border-color:rgba(234,160,58,.3);color:var(--warn-ink,#8a6116)}

/* ── LA BANDE DE DISPONIBILITÉ DU JOUR ───────────────────────────────────────
 * ⚠ ELLE N'EST PAS UNE SÉANCE, et ne doit pas en avoir l'air : pas de fond
 *   blanc, pas de trait de couleur. C'est le CADRE dans lequel les cartes se
 *   posent — d'où sa place en tête de colonne, et son encre effacée. */
.cc .rp-jour-d{display:flex;flex-wrap:wrap;align-items:center;gap:4px;
  font-size:.67rem;color:var(--ink3);font-variant-numeric:tabular-nums}
.cc .rp-jour-d i{font-size:.72rem}
.cc .rp-jour-d span{border:1px dashed var(--line2,var(--line));border-radius:999px;padding:0 6px}
/* ⚠ SUR TÉLÉPHONE, SEPT COLONNES SONT ILLISIBLES : on repasse en liste, un jour
   par ligne, plutôt que de laisser la grille déborder. */
@media (max-width:900px){
  .cc .rp-sem{grid-template-columns:1fr}
  .cc .rp-jour{min-height:0}
  .cc .rp-jour:empty{display:none}
}

/* ── Onglets de la fiche élève ──────────────────────────────────────────── */
.cc .rp-tabs{display:flex;gap:4px;background:var(--surf2);border:1px solid var(--line);
  border-radius:12px;padding:3px;overflow-x:auto;margin:18px 0 0}
.cc .rp-tab{border:0;background:transparent;font:inherit;font-size:.84rem;font-weight:700;
  color:var(--ink3);padding:9px 14px;border-radius:9px;cursor:pointer;white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px;transition:.14s}
.cc .rp-tab.on{background:var(--surf);color:var(--blue-7);box-shadow:var(--sh)}
.cc .rp-tab i{color:var(--stu-or-k,#b35c36)}
/* ⚠ LE MÊME ÉCART QUE LE RYTHME DU MODULE. Ce panneau portait 18 px quand tout
 *   le reste en a 26 : deux valeurs pour le même intervalle, sur des écrans
 *   voisins, se remarquent sans qu'on sache pourquoi. Et cette règle-ci l'emporte
 *   sur `.cc > * + *` (deux classes contre une), donc l'aligner ici est le seul
 *   endroit qui vaille. */
.cc .rp-pan{display:none;margin-top:28px}
.cc .rp-pan.on{display:block}

/* ── Formulaires ──────────────────────────────────────────────────────────
 * 🔴 TROIS COLONNES COMPTÉES, ET NON `auto-fit` (2026-09-05, demande du
 *    propriétaire). `repeat(auto-fit, minmax(220px, 1fr))` laissait le
 *    navigateur en poser cinq ou six sur un grand écran : les champs
 *    devenaient des cases étroites, l'étiquette d'un champ se cassait en deux
 *    lignes pendant que sa voisine tenait sur une, et l'œil ne retrouvait plus
 *    le champ suivant au même endroit d'un écran à l'autre.
 *
 * ⚠ UN FORMULAIRE N'EST PAS UNE GRILLE DE CARTES. Les cartes se réagencent
 *   librement — leur ordre ne porte pas de sens ; les champs d'un formulaire se
 *   lisent dans un ordre, et se remplissent au clavier. Les deux méritent donc
 *   des règles différentes, et c'est bien la même valeur (3) qui a été retenue
 *   au même moment pour `.mk-form` du marché : voir inclusions/marche_css.php.
 *
 * ⚠ `minmax(0,1fr)` : avec `1fr`, un `<select>` à longue option impose sa
 *   largeur minimale à la colonne et fait déborder la grille. */
.cc .rp-form{display:grid;gap:16px;grid-template-columns:repeat(3,minmax(0,1fr))}
@media(max-width:900px){.cc .rp-form{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.cc .rp-form{grid-template-columns:minmax(0,1fr)}}
.cc .rp-form .large{grid-column:1/-1}
/* Deux colonnes sur trois, pour un champ qui a besoin de place sans prendre
   toute la ligne ; il retombe avec la grille, sinon il déborderait. */
.cc .rp-form .demi{grid-column:span 2}
@media(max-width:620px){.cc .rp-form .demi{grid-column:1/-1}}
.cc .ed-fld{display:flex;flex-direction:column;gap:6px}
.cc .ed-fld>span{font-size:.72rem;font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--ink3)}
/* ⚠ LA BARRE D'OUTILS PARTAGE CETTE RÈGLE (2026-09-05). Elle avait la sienne,
 *   qui ne visait que `input` : les trois écrans dont la barre porte un
 *   `<select>` d'élève affichaient le menu déroulant NU du système. Deux
 *   définitions du même champ finissent toujours par diverger — ici, l'une
 *   avait un cas de moins que l'autre. Une seule règle, deux emplacements.
 *
 * ⚠ ET `.rp-champ` LA PARTAGE AUSSI, POUR LA MÊME RAISON (2026-09-05, soir).
 *   Toutes les règles ci-dessus exigent un CONTENANT — `.ed-fld`, `.rp-q`. Dans
 *   une cellule de tableau il n'y en a aucun : les trois champs de « Pendant la
 *   séance » (présence, compréhension, remarque) sortaient donc BRUTS du
 *   système, au milieu d'une interface dessinée. Troisième site du même défaut.
 *   `.rp-champ` nomme le champ LUI-MÊME : il n'a plus besoin d'enveloppe, et le
 *   prochain champ posé dans un tableau n'aura qu'à porter ce nom. */
.cc .ed-fld input,.cc .ed-fld select,.cc .ed-fld textarea,
.cc .rp-outils .rp-q input,.cc .rp-outils .rp-q select,
.cc .rp-outils > select,.cc .rp-champ{
  border:1px solid var(--line);border-radius:10px;background:var(--surf);color:var(--ink);
  font:inherit;font-size:.9rem;padding:10px 12px;width:100%;box-sizing:border-box}
.cc .ed-fld textarea{min-height:96px;resize:vertical;line-height:1.5}
.cc .ed-fld input:focus,.cc .ed-fld select:focus,.cc .ed-fld textarea:focus,
.cc .rp-outils .rp-q input:focus,.cc .rp-outils .rp-q select:focus,
.cc .rp-outils > select:focus,.cc .rp-champ:focus{
  outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
.cc .rp-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px;align-items:center}

/* ══ « PENDANT LA SÉANCE » — LA LIGNE DE SAISIE PAR ÉLÈVE ═════════════════════
 *
 * Un tableau dont chaque cellule est un champ n'est plus tout à fait un
 * tableau : c'est un formulaire en lignes. Il en faut le rythme — des colonnes
 * de largeur STABLE, pour que l'œil retrouve la présence au même endroit d'une
 * ligne à l'autre — et l'aération d'un formulaire, pas celle d'une liste.
 *
 * ⚠ LES LARGEURS SONT POSÉES SUR `th`, PAS SUR `td`. Une largeur de cellule ne
 *   vaut que pour sa ligne ; posée sur l'en-tête, elle vaut pour la colonne. Et
 *   le nom de l'élève garde `width:auto` : c'est lui qui absorbe le reste.
 *
 * ⚠ ET CHAQUE LARGEUR EST DOUBLÉE D'UN `min-width`. En `table-layout:auto`,
 *   `width` n'est qu'un VŒU : sur un téléphone — police plus grande, colonne
 *   plus étroite — le navigateur a donné 135 px aux 170 demandés et « Présent »
 *   s'est affiché « Prése⌄ ». Le minimum, lui, s'impose : le tableau grandit
 *   au-delà du cadre, et `.tbl-wrap` le fait défiler, ce qui est exactement ce
 *   qu'il est là pour faire. Un champ tronqué, lui, ne défile pas. */
.cc table.rp-part{table-layout:auto}
.cc table.rp-part td{padding:10px 14px}
.cc table.rp-part th:nth-child(2),.cc table.rp-part td:nth-child(2){width:170px;min-width:158px}
.cc table.rp-part th:nth-child(3),.cc table.rp-part td:nth-child(3){width:130px;min-width:112px}
.cc table.rp-part th:nth-child(4){width:34%;min-width:200px}
.cc table.rp-part .rp-act1{width:1%;white-space:nowrap;text-align:end}
/* Dans une ligne, le champ respire un peu moins que dans un formulaire :
   sinon cinq élèves font un écran de deux mètres. */
.cc table.rp-part .rp-champ{padding:8px 11px;font-size:.86rem}

/* ⚠ LE « % » EST DANS LE CADRE, PAS DERRIÈRE. Il était posé en texte nu APRÈS
 *   l'`<input>` : sa distance au nombre changeait avec la largeur de la
 *   colonne, et l'on ne savait plus s'il appartenait à la valeur ou à la
 *   colonne suivante. `aria-hidden` sur le signe : le champ porte déjà
 *   « Compréhension en pourcentage » comme nom accessible, un lecteur d'écran
 *   qui lirait les deux dirait « pourcentage » deux fois. */
.cc .rp-unite{position:relative;display:block}
.cc .rp-unite>b{position:absolute;inset-inline-end:11px;top:50%;transform:translateY(-50%);
  font-size:.78rem;font-weight:700;color:var(--ink3);pointer-events:none}
.cc .rp-unite .rp-champ{padding-inline-end:28px;text-align:end;
  font-variant-numeric:tabular-nums}

/* ⚠ LA PRÉSENCE SE VOIT AVANT DE SE LIRE. Cinq lignes de « Présent » et
 *   « Absent » en encre noire ne se distinguent qu'en les lisant une à une —
 *   or c'est l'information qu'on vient chercher d'un coup d'œil. Le champ prend
 *   la teinte de son état, avec les jetons déjà employés par `.rp-pill` pour
 *   dire exactement la même chose ailleurs : vert présent, ambre en retard,
 *   rouge absent. `data-v` est posé par le serveur et tenu à jour par le
 *   JavaScript à chaque changement — sans quoi la couleur mentirait dès la
 *   première sélection.
 *
 * ⚠ C'EST LE FOND QUI PORTE LA COULEUR, PAS LE TEXTE. Trois teintes, une seule
 *   encre : `--ink` tient plus de 12:1 sur chacune, dans les deux thèmes, parce
 *   que les tons `-l` et `--ink` basculent ensemble. Une encre colorée aurait
 *   demandé trois calibrages, refaits à chaque changement de palette.
 *
 *   ⓘ C'est en mesurant ces trois règles qu'on a trouvé le défaut GÉNÉRAL de
 *     déclencheur de thème corrigé le même jour dans `assets/css/shell.css` :
 *     les teintes suivaient `prefers-color-scheme`, les surfaces et l'encre non.
 *     `--ink` sur `--bl-025` valait alors **1,07:1** sur tout écran de
 *     l'application, pour qui n'avait jamais touché le bouton ◐.
 *
 *   ⓘ Les pastilles `.rp-pill` plus haut tiennent l'autre convention (encre
 *     colorée sur teinte, ~3:1). Non touché ici : ce serait toucher toutes les
 *     pastilles de l'espace, ce qui n'est pas le sujet de ce chantier. */
.cc .rp-part .pPres[data-v="present"]{background:var(--green-l);color:var(--ink);
  border-color:rgba(22,160,106,.45);font-weight:700}
.cc .rp-part .pPres[data-v="retard"]{background:var(--amber-l);color:var(--ink);
  border-color:rgba(234,160,58,.5);font-weight:700}
.cc .rp-part .pPres[data-v="absent"],.cc .rp-part .pPres[data-v="excuse"]{
  background:var(--tint-rg3,#fdecea);color:var(--ink);border-color:#e8b3ad;font-weight:700}

/* La ligne qui vient d'être enregistrée le dit une seconde, là où l'on
   regarde — et non seulement dans le message sous le tableau. */
.cc .rp-part tr.rp-ok>td{background:var(--green-l)}
.cc .rp-part tr.rp-ok>td:first-child{box-shadow:inset 3px 0 0 var(--green)}
.cc .rp-part tr>td{transition:background .5s ease,box-shadow .5s ease}

/* ══ L'ÉTAT COURANT DE LA SÉANCE ═════════════════════════════════════════════
 *
 * 🔴 IL N'ÉTAIT QUE `disabled`, donc PÂLI. Un bouton pâle ne dit pas « vous y
 *    êtes », il dit « ceci ne fonctionne pas » — c'est ce que montrait la
 *    capture, où « Absence du répétiteur » avait l'air en panne. On lui rend
 *    donc son opacité pleine, une teinte de rôle, un cadre net et un curseur
 *    normal ; il reste `disabled`, parce que reposter l'état qu'on a déjà
 *    n'aurait aucun effet.
 *
 * ⚠ `!important` SUR L'OPACITÉ ET LE CURSEUR SEULEMENT. C'est la règle générale
 *   `[disabled]` du shell qu'on contredit ici, et sur ces deux propriétés
 *   uniquement — le reste du bouton garde le style de sa classe.
 *
 * ⚠ LE FOND N'EST **PAS** `--bl-025`, ET C'EST MESURÉ. Une teinte de rôle
 *   derrière le libellé était le réflexe ; mais aucun membre de `--blue-*` ne
 *   s'y lit dans les deux thèmes — ils sont calibrés pour PORTER du blanc, et
 *   donnent 6,76:1 en clair contre 2,37:1 en sombre. Il aurait fallu
 *   `--stu-role-k` et une seconde règle sous `[data-theme="dark"]`, comme les
 *   pastilles plus haut.
 *
 *   `--surf` + `--ink` évite cette dette : 15,7:1 des deux côtés, sans règle
 *   conditionnelle. Le cadre — doublé d'une ombre interne, soit deux pixels
 *   nets — et le pictogramme portent la couleur du rôle, ce qui suffit à dire
 *   « retenu » et ne dépend d'aucun accord de jetons. */
.cc .rp-actions .sStat.actif{opacity:1 !important;cursor:default !important;
  background:var(--surf);border-color:var(--blue);color:var(--ink);font-weight:800;
  box-shadow:inset 0 0 0 1px var(--blue)}
.cc .rp-actions .sStat.actif i{color:var(--blue)}

/* ── Notes et messages ──────────────────────────────────────────────────── */
.cc .rp-note{border-radius:12px;padding:12px 14px;font-size:.87rem;font-weight:650;line-height:1.5;
  display:flex;gap:9px;align-items:flex-start;margin:12px 0}
.cc .rp-note i{margin-top:2px;flex:0 0 auto}
.cc .rp-note.info{background:var(--bl-025);border:1px solid var(--bl2);color:var(--blue-7)}
.cc .rp-note.ok{background:var(--green-l);border:1px solid rgba(22,160,106,.25);color:var(--green)}
.cc .rp-note.ko{background:var(--tint-rg3,#fdecea);border:1px solid #f3c9c4;color:var(--danger)}
.cc .rp-note.warn{background:var(--amber-l);border:1px solid rgba(234,160,58,.3);color:var(--warn-ink,#8a6116)}
.cc .rp-vide{color:var(--ink3);text-align:center;padding:36px 16px;font-size:.9rem;line-height:1.6}
.cc .rp-vide i{display:block;font-size:2rem;margin-bottom:10px;opacity:.5}

/* ── Alertes ALIE du tableau de bord ────────────────────────────────────── */
.cc .rp-alertes{display:flex;flex-direction:column;gap:8px}
.cc .rp-al{display:flex;gap:11px;align-items:flex-start;background:var(--surf2);
  border:1px solid var(--line);border-inline-start:3px solid var(--amber);
  border-radius:10px;padding:11px 13px;font-size:.86rem;line-height:1.45}
.cc .rp-al.baisse{border-inline-start-color:var(--danger)}
.cc .rp-al.devoir{border-inline-start-color:var(--amber)}
.cc .rp-al.absence{border-inline-start-color:var(--info)}
.cc .rp-al b{color:var(--ink)}
.cc .rp-al a{color:var(--blue-7);font-weight:700;text-decoration:none;white-space:nowrap}

/* ── Barre d'outils (recherche + filtres), alignée sur .stu-vues du shell ──
 *
 * 🔴 REPRISE LE 2026-09-05 — « dans un meilleur style, avec moins d'écarts ».
 *    La capture montrait trois défauts d'un coup, et un seul se voyait au
 *    premier regard :
 *      ① LE `<select>` N'ÉTAIT PAS STYLÉ. La règle ne visait que `input` — un
 *        champ de recherche. Les trois écrans qui choisissent un ÉLÈVE
 *        (documents, progression, alie) affichaient donc le menu déroulant NU
 *        du système d'exploitation, au milieu d'une interface dessinée. Défaut
 *        « N-1 sites sur N », neuf fois relevé ici : on a stylé la moitié des
 *        champs possibles et cru avoir fini.
 *      ② `.rp-q{flex:1 1 220px}` ÉTIRAIT LE CONTENANT du champ sur toute la
 *        largeur libre. Le champ, lui, restait petit : d'où le bouton
 *        « Imprimer le rapport » projeté à l'autre bout de l'écran, à 900 px de
 *        ce qu'il commande. On BORNE la largeur (`0 1 320px`) au lieu de la
 *        laisser grandir.
 *      ③ L'ÉCART SOUS LA BARRE VALAIT 32 px, PAS 12. Le `margin-bottom:12px`
 *        ci-dessous était écrasé par `.cc > .rp-outils + *{margin-top:32px}` en
 *        fin de feuille (les marges adjacentes prennent la PLUS GRANDE). La
 *        barre flottait donc entre deux grands blancs, détachée de la liste
 *        qu'elle filtre.
 *
 * ⚠ ET LES CHAMPS PARTAGENT LA RÈGLE DE `.ed-fld` plutôt que d'en avoir une
 *   copie : deux définitions du même champ finissent toujours par diverger —
 *   c'est ce qui vient de se passer avec `select`. */
.cc .rp-outils{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 12px}
/* 🔴 LE CHAMP DE RECHERCHE PREND LE RESTE DE LA LONGUEUR (2026-09-06, demande du
 *    propriétaire). Il était borné à 320 px, et la barre s'arrêtait donc avant
 *    son bord : mesuré sur « Mes élèves » — onglets 505 + champ 320 + bouton 176
 *    sur 1 115 px de large, soit **93 px de vide** après le bouton. Une barre
 *    d'outils qui ne va pas jusqu'au bout se lit comme un alignement raté.
 *
 * ⚠ LA BORNE AVAIT UNE RAISON, ET ELLE N'EST PLUS VALABLE. Elle a été posée le
 *   2026-09-05 parce que `.rp-q{flex:1 1 220px}` étirait le CONTENANT sans que
 *   le champ suive : le bouton partait à l'autre bout, à 900 px de ce qu'il
 *   commande, devant un champ resté petit. Le vrai défaut était là — et il est
 *   corrigé depuis, par le `width:100%` que le champ tient de `.ed-fld`. Le
 *   contenant peut donc grandir : le champ grandit avec lui.
 *
 * ⚠ LE `<select>` GARDE SA BORNE, LUI. Il ne cherche rien : il choisit un élève
 *   dans une liste courte, et l'étirer sur huit cents pixels ne montrerait pas un
 *   nom de plus. Trois écrans l'emploient (documents, progression, alie) ; les
 *   élargir n'a pas été demandé, et ce serait une décision d'un autre ordre.
 *
 * ⚠ `min-width:180px` RESTE LE PLANCHER : sous cette largeur le champ passe à la
 *   ligne plutôt que de se réduire à un carré illisible. */
.cc .rp-outils .rp-q{flex:1 1 320px;min-width:180px}
.cc .rp-outils > select{flex:0 1 320px;min-width:180px}
/* Le style des champs est celui de `.ed-fld`, plus haut : une seule règle. */

/* ── Revenus ────────────────────────────────────────────────────────────── */
.cc .rp-mnt{font-variant-numeric:tabular-nums;font-weight:800;color:var(--ink)}
.cc .rp-serie{display:flex;align-items:flex-end;gap:6px;height:140px;margin-top:16px;
  padding:0 2px;overflow-x:auto}
.cc .rp-serie>div{flex:1 0 26px;display:flex;flex-direction:column;justify-content:flex-end;
  align-items:center;gap:6px;min-width:26px}
.cc .rp-serie .b{width:100%;background:var(--blue);border-radius:6px 6px 0 0;min-height:2px;
  transition:height .3s}
.cc .rp-serie .l{font-size:.62rem;color:var(--ink3);font-weight:700;white-space:nowrap;
  writing-mode:vertical-rl;transform:rotate(180deg)}

/* ── Disponibilités ─────────────────────────────────────────────────────── */
.cc .rp-dispo{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.cc .rp-dj{background:var(--surf2);border:1px solid var(--line);border-radius:12px;padding:12px}
.cc .rp-dj h4{margin:0 0 8px;font-size:.76rem;font-weight:800;text-transform:uppercase;
  letter-spacing:.06em;color:var(--ink3)}
.cc .rp-cr{display:flex;align-items:center;gap:6px;font-size:.82rem;color:var(--ink2);
  background:var(--surf);border:1px solid var(--line);border-radius:8px;padding:6px 9px;margin-bottom:6px}
.cc .rp-cr button{margin-inline-start:auto;border:0;background:transparent;color:var(--ink3);
  cursor:pointer;font-size:.9rem;line-height:1;padding:2px}
@media (hover:hover){.cc .rp-cr button:hover{color:var(--danger)}}

/* ── Chat ALIE (repris du gabarit des assistants, sans jQuery) ───────────── */
.cc .rp-chat{border:1px solid var(--line);border-radius:16px;background:var(--surf);
  display:flex;flex-direction:column;height:min(62vh,560px);overflow:hidden}
.cc .rp-flux{flex:1;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:12px}
.cc .rp-bulle{max-width:min(80%,620px);border-radius:14px;padding:11px 14px;font-size:.9rem;
  line-height:1.6;white-space:pre-wrap;word-wrap:break-word}
.cc .rp-bulle.moi{align-self:flex-end;background:var(--blue);color:#fff;border-bottom-right-radius:4px}
.cc .rp-bulle.ia{align-self:flex-start;background:var(--surf2);color:var(--ink);
  border:1px solid var(--line);border-bottom-left-radius:4px}
.cc .rp-saisie{border-top:1px solid var(--line);padding:12px;display:flex;gap:10px;align-items:flex-end}
.cc .rp-saisie textarea{flex:1;border:1px solid var(--line);border-radius:12px;background:var(--surf);
  color:var(--ink);font:inherit;font-size:.9rem;padding:11px 13px;resize:none;max-height:140px;line-height:1.5}
.cc .rp-chips{display:flex;flex-wrap:wrap;gap:7px;margin:14px 0}
.cc .rp-chip{border:1px solid var(--line);background:var(--surf);color:var(--ink2);border-radius:999px;
  padding:7px 13px;font:inherit;font-size:.8rem;font-weight:650;cursor:pointer;
  display:inline-flex;align-items:center;gap:6px;transition:.14s}
@media (hover:hover){.cc .rp-chip:hover{border-color:var(--blue);color:var(--blue-7)}}
.cc .rp-chip i{color:var(--stu-or-k,#b35c36)}

/* ── UNE LISTE REPLIÉE À N LIGNES (`data-rp-lignes`, 2026-09-05) ─────────────
 * 🔴 « Ce que la famille voit » alignait jusqu'à SEPT pastilles dans une colonne
 *    de tableau : trois lignes, et toute la rangée poussée en hauteur. Demande
 *    du propriétaire : deux lignes au plus, un bouton juste en dessous.
 *
 * ⚠ LA HAUTEUR EST POSÉE PAR LE SCRIPT, PAS ICI, et c'est la seule façon d'être
 *   juste : une valeur écrite en dur (« 2 × 30 px ») coupe au milieu d'une ligne
 *   dès que la police, le zoom ou une traduction changent la donne. rep-ui.js
 *   mesure les lignes réelles ; cette feuille ne fournit que le masque et la
 *   transition. `.rp-replie-on` n'est posée que s'il y a vraiment à replier —
 *   sans elle, aucun `overflow` ne s'applique, donc aucun risque de rogner une
 *   liste courte si le script ne s'exécute pas. */
.cc .rp-replie-on{overflow:hidden;transition:max-height .18s ease}
@media (prefers-reduced-motion:reduce){.cc .rp-replie-on{transition:none}}
/* Le bouton est un LIEN d'apparence, pas un bouton d'action : il ne change rien
   à la donnée, il montre le reste. Il se pose sous la liste, aligné à gauche. */
.cc .rp-plus{display:inline-block;margin-top:6px;padding:0;border:0;background:none;
  color:var(--blue-7);font:inherit;font-size:.76rem;font-weight:700;cursor:pointer}
@media (hover:hover){.cc .rp-plus:hover{text-decoration:underline}}
.cc .rp-plus:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:4px}
/* Les pastilles de « ce que la famille voit » : même gabarit que `.rp-pill`,
   mais dans un contenant qui sait retourner à la ligne et se replier. */
.cc .rp-vus{display:flex;flex-wrap:wrap;gap:6px}

/* ══ PIÈCES JOINTES (2026-09-02) ═══════════════════════════════════════════
   ⚠ AUCUNE COULEUR EN DUR : les jetons du shell portent déjà le thème clair et
     sombre. Une valeur écrite ici serait juste dans un thème et fausse dans
     l'autre — le défaut « variable CSS inventée » déjà relevé sur ce projet. */
.rp-pjs{margin:14px 0 4px}
.rp-pj-h{margin:0 0 8px;font-size:.84rem;font-weight:800;color:var(--ink);
  display:flex;align-items:center;gap:7px}
.rp-pj-h i{color:var(--stu-or-k,#b35c36)}
.rp-pj-liste{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px}
.rp-pj{display:inline-flex;align-items:center;gap:7px;font-size:.82rem;
  background:var(--surf2);border:1px solid var(--line);border-radius:10px;
  padding:6px 10px;max-width:100%}
.rp-pj i{color:var(--ink3);flex:none}
.rp-pj a{color:var(--ink);text-decoration:none;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;max-width:16rem}
/* Survols sous `(hover:hover)` (audit 2026-09-10), comme les autres de cette feuille. */
@media (hover:hover){.rp-pj a:hover{text-decoration:underline}}
.rp-pj .faint{font-size:.74rem;flex:none}
.rp-pj-x{background:none;border:0;padding:0 0 0 2px;cursor:pointer;color:var(--ink3);
  line-height:1;flex:none}
@media (hover:hover){.rp-pj-x:hover{color:var(--stu-dg,#b3261e)}}
.rp-pj-x:disabled{opacity:.4;cursor:default}
.rp-pj-add{cursor:pointer}
/* ⚠ Le <input type="file"> est `hidden` : c'est le <label> qui reçoit le clic.
     Sans `cursor:pointer`, rien ne dit que l'étiquette est cliquable. */

/* ══ OPPORTUNITÉS (§15, 2026-09-02) ════════════════════════════════════════
   ⚠ AUCUNE COULEUR EN DUR : les jetons du shell portent les deux thèmes. */
.rp-opps{display:flex;flex-direction:column;gap:12px}

/* ── Les candidatures reçues, côté famille (2026-09-05) ──────────────────────
 * ⚠ ELLES VIVENT DANS LEUR DEMANDE, en retrait : une candidature isolée ne veut
 *   rien dire — il faut savoir à quelle demande elle répond. D'où le liseré de
 *   gauche, qui dit « ceci dépend de ce qui précède », comme `.rp-al`.
 * ⚠ ET ELLES NE SONT PAS DES `.rp-opp` : imbriquer une carte dans une carte
 *   empilerait deux fonds et deux traits — le défaut que `.rp-bloc` annule déjà
 *   pour lui-même. Ici le fond est celui de la carte hôte. */
.cc .rp-cands{display:flex;flex-direction:column;gap:10px;margin-top:12px}
.cc .rp-cand{border:1px solid var(--line);border-inline-start:3px solid var(--blue);
  border-radius:12px;background:var(--surf2);padding:12px 14px}
.cc .rp-cand .rp-opp-d{margin-top:8px}
/* L'astérisque des champs obligatoires : le module n'en avait pas, et un
   formulaire qui exige sans le dire fait échouer la première soumission. */
.cc .rp-req{color:var(--danger);font-weight:800}
.rp-opp{background:var(--surf);border:1px solid var(--line);border-radius:14px;padding:16px 18px}
.rp-opp-h{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap}
.rp-opp-s{flex:none;width:44px;height:44px;border-radius:12px;display:flex;align-items:center;
  justify-content:center;font-weight:800;font-size:.95rem;border:1px solid var(--line)}
.rp-opp-s.bon{background:var(--ok-bg,rgba(16,142,110,.12));color:var(--ok,#0e8e6e)}
.rp-opp-s.moyen{background:var(--warn-bg,rgba(179,92,54,.12));color:var(--stu-or-k,#b35c36)}
.rp-opp-s.faible{background:var(--surf2);color:var(--ink3)}
.rp-opp-t{display:block;font-weight:800;font-size:.94rem;color:var(--ink)}
.rp-opp-m{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px;font-size:.79rem;color:var(--ink3)}
.rp-opp-d{margin:10px 0 0;font-size:.86rem;line-height:1.6;color:var(--ink2)}
.rp-opp-x{margin-top:10px;font-size:.82rem}
.rp-opp-x summary{cursor:pointer;color:var(--ink3);font-weight:600}
.rp-opp-crit{display:flex;flex-wrap:wrap;gap:7px;margin-top:8px}
.rp-opp-c{font-size:.75rem;padding:3px 9px;border-radius:999px;border:1px solid var(--line);
  background:var(--surf2);color:var(--ink3)}
.rp-opp-c.bon{color:var(--ok,#0e8e6e)}
.rp-opp-c.moyen{color:var(--stu-or-k,#b35c36)}
.rp-opp-c b{margin-left:4px;color:var(--ink2)}
/* La fenêtre de candidature — même forme que celle du fragment familial. */
.rp-dlg{position:fixed;inset:0;z-index:1200;display:flex;align-items:center;
  justify-content:center;padding:16px;background:rgba(0,0,0,.45)}
.rp-dlg-in{background:var(--surf);border:1px solid var(--line);border-radius:16px;
  padding:20px;max-width:560px;width:100%;max-height:90vh;overflow:auto}
.rp-dlg-in h4{margin:0 0 4px;font-size:.98rem;font-weight:800;color:var(--ink);
  display:flex;align-items:center;gap:8px}

/* ══ BADGES (§18, 2026-09-02) ══════════════════════════════════════════════
   ⚠ Le badge NON acquis n'est pas caché : il est estompé et porte ce qui reste
     à faire. Ne montrer que les acquis laisse un débutant sans repère. */
.rp-badges{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
.rp-badge{display:inline-flex;align-items:center;gap:7px;font-size:.8rem;font-weight:600;
  padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:var(--surf2)}
.rp-badge.on{color:var(--ok,#0e8e6e);border-color:var(--ok,#0e8e6e)}
.rp-badge.off{color:var(--ink3);opacity:.85}
.rp-badge b{font-weight:500;font-size:.74rem;color:var(--ink3);margin-left:2px}
.rp-badges-x summary{cursor:pointer;color:var(--ink3);font-size:.82rem;font-weight:600}

/* Le signal d'opportunités : une note cliquable, pas un simple encadré. */
.rp-opp-lien{text-decoration:none;display:flex;margin-bottom:14px}
@media (hover:hover){.rp-opp-lien:hover{border-color:var(--stu-or-k,#b35c36)}}

/* ══ « CE QUI MANQUE POUR ÊTRE PROPOSÉ » (profil, 2026-09-05) ═══════════════
 * 🔴 CE N'EST PAS UNE BARRE DE PROGRESSION. Un pourcentage de complétude dit
 *    « 60 % » et laisse chercher les 40 % restants ; ici chaque ligne NOMME le
 *    champ absent, dit CE QU'IL COÛTE (les poids réels de `rep_match_score()` :
 *    matière 30, niveau 20, disponibilité 15, proximité 10, tarif 10) et MÈNE à
 *    l'endroit où le remplir. Un manque sans son lien, c'est une réprimande.
 *
 * ⚠ CHAQUE LIGNE EST UN `<a>`, pas une puce décorée d'un lien. La cible
 *   cliquable fait toute la largeur : sur téléphone, viser un lien de quatre
 *   mots au bout d'une phrase est un travail.
 *
 * ⚠ TON D'ALERTE, PAS D'ERREUR. Un profil incomplet n'est pas une faute — c'est
 *   un profil qu'on est en train d'écrire. D'où l'ambre du shell, et non le
 *   rouge : `--bad` dirait à un débutant qu'il a cassé quelque chose. */
.rp-manques{display:flex;flex-direction:column;gap:10px}
.rp-manque{display:flex;align-items:flex-start;gap:12px;text-decoration:none;
  padding:13px 15px;border:1px solid var(--line);border-left:3px solid var(--amber);
  border-radius:12px;background:var(--surf2)}
@media (hover:hover){.rp-manque:hover{border-color:var(--stu-or-k,#b35c36);
  border-left-color:var(--stu-or-k,#b35c36)}}
.rp-manque > i{color:var(--amber);font-size:1.05rem;line-height:1.35}
.rp-manque .q{flex:1;font-size:.88rem;font-weight:700;color:var(--ink)}
.rp-manque .q .w{display:block;font-size:.79rem;font-weight:400;color:var(--ink3);
  margin-top:3px}
.rp-manque .a{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-size:.8rem;font-weight:600;color:var(--stu-or-k,#b35c36)}
/* Sur téléphone la ligne se replie : l'action passe sous le texte plutôt que de
   comprimer les deux en colonnes de six caractères. */
@media (max-width:640px){
  .rp-manque{flex-wrap:wrap}
  .rp-manque .a{width:100%;justify-content:flex-end}
}

/* ══ UNE RANGÉE DE CASES À COCHER ═══════════════════════════════════════════
 * ⚠ LA MÊME FORME ÉTAIT ÉCRITE DEUX FOIS EN STYLE EN LIGNE — `repetiteur-planning.php`
 *   (le choix des élèves d'une séance) et ce profil (le choix des modalités) — au
 *   pixel près. Deux copies d'une même intention, donc une occasion de n'en
 *   corriger qu'une. La règle est posée ici, les deux pages la nomment.
 *
 * ⚠ `repetiteur-eleve.php` GARDE SON STYLE EN LIGNE, ET CE N'EST PAS UN OUBLI :
 *   ses cases de partage sont SANS cadre, volontairement — une liste de choses
 *   qu'on montre à la famille, pas une rangée de pastilles. Les ranger sous la
 *   même classe changerait son apparence pour servir la symétrie du code. */
.rp-cases{display:flex;flex-wrap:wrap;gap:10px}
.rp-cases > label{display:inline-flex;align-items:center;gap:7px;font-size:.86rem;
  color:var(--ink2);border:1px solid var(--line);border-radius:10px;padding:7px 11px;
  cursor:pointer}
@media (hover:hover){.rp-cases > label:hover{border-color:var(--stu-or-k,#b35c36)}}
/* ══ RÉGLAGES (2026-09-03) ═════════════════════════════════════════════════
   ⚠ L'aide de chaque réglage est AFFICHÉE, pas en infobulle : un nombre qu'on
     change sans savoir ce qu'il commande se change au hasard. */
.rp-reglages{display:flex;flex-direction:column;gap:2px}
.rp-reg{display:flex;gap:16px;align-items:flex-start;padding:12px 0;
  border-bottom:1px solid var(--line)}
.rp-reg:last-child{border-bottom:0}
.rp-reg-l{flex:1;min-width:0;cursor:pointer}
.rp-reg-t{display:block;font-weight:700;font-size:.88rem;color:var(--ink)}
.rp-reg-a{display:block;font-size:.8rem;line-height:1.55;color:var(--ink3);margin-top:3px}
.rp-reg-c{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:3px;
  min-width:9rem}
.rp-reg-c input{width:7rem;text-align:right}
.rp-reg-u{font-size:.76rem;color:var(--ink3)}
.rp-somme-ko{color:var(--stu-dg,#b3261e)}
@media (max-width:640px){
  .rp-reg{flex-direction:column;gap:8px}
  .rp-reg-c{align-items:flex-start;min-width:0}
}

/* ══ CORRECTION ASSISTÉE — §11 (2026-09-04) ═══════════════════════════════
   ⚠ LA PROPOSITION SE DISTINGUE DE LA CORRECTION. Elle est encadrée et teintée
     autrement que les lignes du tableau, précisément pour qu'on ne la lise pas
     comme une note déjà posée : c'est un avis, pas une décision.
   ⚠ ELLE VIT DANS UNE LIGNE DU TABLEAU, pas dans une fenêtre : une modale
     cacherait le champ « Note » qu'elle sert à remplir. */
.rp-ia-ligne > td{background:var(--surface2,#fbf9f7);padding:14px 12px}
.rp-ia-boite{font-size:.86rem;line-height:1.6;color:var(--ink)}
.rp-ia-tete{display:flex;align-items:center;gap:7px;margin-bottom:8px;font-size:.86rem}
.rp-ia-syn{margin:0 0 10px;color:var(--ink2)}
.rp-ia-note{display:inline-block;border:1px solid var(--line);border-radius:10px;
  padding:6px 12px;margin-bottom:10px;font-size:.88rem}
.rp-ia-bloc{margin-bottom:10px}
.rp-ia-bloc ul{margin:5px 0 0;padding-left:20px}
.rp-ia-bloc li{margin-bottom:4px}
.rp-ia-not{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}

/* ══ MON ACTIVITÉ — §21 (2026-09-04) ══════════════════════════════════════ */
.rp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:12px;
  margin-bottom:18px}
.rp-kpi{border:1px solid var(--line);border-radius:14px;padding:16px 18px;background:var(--surface)}
.rp-kpi-v{display:block;font-size:1.5rem;font-weight:800;color:var(--ink);line-height:1.15}
.rp-kpi-l{display:block;font-size:.78rem;color:var(--ink3);margin-top:3px}
.rp-kpi-s{display:block;font-size:.74rem;color:var(--ink3);margin-top:5px}
/* La barre d'un mois : c'est la HAUTEUR qui porte la valeur — le piège déjà payé
   une fois sur ce projet est d'écrire `width` en croyant régler la hauteur. */
.rp-hist{display:flex;align-items:flex-end;gap:6px;height:120px;padding:0 2px;
  border-bottom:1px solid var(--line);margin-bottom:6px;overflow-x:auto}
.rp-hist-b{flex:1;min-width:14px;background:var(--stu-or-k,#b35c36);border-radius:5px 5px 0 0;
  opacity:.85}
@media (hover:hover){.rp-hist-b:hover{opacity:1}}
.rp-hist-x{display:flex;gap:6px;font-size:.7rem;color:var(--ink3)}
.rp-hist-x span{flex:1;min-width:14px;text-align:center}

/* ══ RÉVISION — §12 (2026-09-04) ══════════════════════════════════════════ */
.rp-rev{display:flex;flex-direction:column;gap:10px}
.rp-rev-i{display:flex;align-items:center;gap:12px;border:1px solid var(--line);
  border-radius:12px;padding:11px 14px}
.rp-rev-n{flex:1;min-width:0;font-weight:600;font-size:.88rem}
.rp-rev-m{flex:none;font-size:.76rem;color:var(--ink3)}
.rp-rev-j{flex:none;width:6rem;height:7px;border-radius:4px;background:var(--line);overflow:hidden}
.rp-rev-j i{display:block;height:100%;background:var(--stu-or-k,#b35c36)}
/* ⚠ Sur téléphone, le nom passe sur SA ligne, jauge et chiffre dessous. Jauge (6rem)
     et chiffre ne cèdent rien : à 320 px le nom tombait à 65 px et « Mathématiques »
     (98 px) s’imprimait sur la jauge (repetiteur-activite) ; aux révisions, le
     bouton « En faire un devoir » sortait de l’écran de 46 px. Même geste que .rp-manque. */
@media (max-width:640px){
  .rp-rev-i{flex-wrap:wrap;row-gap:8px}
  .rp-rev-n{flex-basis:100%}
}

/* ══ VITRINE PUBLIQUE — §17 (2026-09-04) ══════════════════════════════════ */
.rp-vit{display:grid;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));gap:14px}
/* ⚠ `var(--surf)`, PAS `var(--surface)` (corrigé le 2026-09-05). Le jeton
     `--surface` n'existe nulle part : shell.css déclare `--surf` et `--surf2`.
     Une variable inventée ne lève AUCUNE erreur — la propriété est simplement
     ignorée, et la carte n'avait donc pas de fond du tout. Invisible sur le fond
     blanc de l'annuaire public, visible dès qu'on pose ces mêmes cartes dans un
     `.rp-bloc` (la recherche des familles) : le trait sans le fond. */
.rp-vit-c{border:1px solid var(--line);border-radius:16px;padding:16px;background:var(--surf);
  display:flex;flex-direction:column;gap:8px}
.rp-vit-h{display:flex;align-items:center;gap:11px}
.rp-vit-a{flex:none;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  background:var(--line);font-weight:800;font-size:.92rem;color:var(--ink2)}
.rp-vit-n{font-weight:700;font-size:.94rem;line-height:1.25}
.rp-vit-s{font-size:.78rem;color:var(--ink3)}
.rp-vit-m{display:flex;flex-wrap:wrap;gap:6px}
.rp-vit-t{font-size:.74rem;border:1px solid var(--line);border-radius:8px;padding:3px 8px;
  color:var(--ink3)}
@media (max-width:640px){ .rp-kpis{grid-template-columns:repeat(2,1fr)} }

/* ══ LE CHOIX, LES RAISONS, LES RECOMMANDATIONS (2026-09-06) ═════════════════
 *
 * Trois classes nées avec la sollicitation directe. Elles sont écrites ICI et
 * non dans la page : c'est la leçon de `--surface`, six lignes plus haut — une
 * classe qu'aucune feuille ne définit ne lève rien et ne se voit qu'à l'écran,
 * sur une page qu'on ne regardait pas.
 *
 * ⚠ LA BARRE D'ACTION EST POUSSÉE EN BAS DE LA CARTE (`margin-top:auto`). Les
 *   fiches d'une même rangée n'ont pas la même hauteur — présentation plus ou
 *   moins longue, badges présents ou non — et un bouton posé au fil du contenu
 *   se serait retrouvé à trois hauteurs différentes sur la même ligne. C'est le
 *   `flex-direction:column` de `.rp-vit-c` qui le permet, sans hauteur fixée. */
.rp-vit-act{margin-top:auto;padding-top:10px;border-top:1px solid var(--line2,var(--line));
  display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.rp-vit-act .btn{font-size:.82rem;padding:8px 13px}

/* Les raisons d'une recommandation : une liste, pas un paragraphe. Elles se
   parcourent du regard — c'est ce qui permet d'écarter une fiche en deux
   secondes sans lire la présentation. */
.rp-pourquoi{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.rp-pourquoi li{display:flex;align-items:flex-start;gap:7px;font-size:.8rem;line-height:1.45;
  color:var(--ink2)}
.rp-pourquoi li i{color:var(--green);margin-top:.15em;flex:none}

/* ⚠ LE BLOC REPLIABLE GARDE L'ASPECT D'UN `.rp-bloc`. `<details>` porte son
   propre affichage — un triangle noir et un curseur texte — qui n'appartient à
   aucun autre écran du module. On lui rend la forme d'un en-tête cliquable, et
   le chevron suit l'ouverture comme celui des rubriques du menu. */
.rp-reco > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:9px}
.rp-reco > summary::-webkit-details-marker{display:none}
.rp-reco > summary::after{content:"\F282";font-family:bootstrap-icons;margin-inline-start:auto;
  font-size:.85rem;color:var(--ink3);transition:transform .2s ease}
.rp-reco[open] > summary::after{transform:rotate(180deg)}
.rp-reco > summary h3{margin:0}

/* ══ LE QUORUM TERRITORIAL (§34, 2026-09-05) ═════════════════════════════════
 * ⚠ CINQ RÈGLES, PAS UNE FEUILLE DE PLUS. L'écran du quorum réemploie tout ce
 *   que le module a déjà : `.rp-chips` pour les cercles, `.rp-tabs`/`.rp-pan`
 *   pour les panneaux, `.rp-chat`/`.rp-flux`/`.rp-bulle` pour le fil, `.stu`
 *   pour les tableaux. Ne manquaient que l'état actif d'une pastille de cercle,
 *   deux états de sujet, et la signature d'une bulle. */

/* ⚠ LES CERCLES SONT DES LIENS, PAS DES BOUTONS : le cercle regardé fait partie
 *   de l'adresse. Un `<a>` arrive souligné et coloré par le navigateur — on
 *   l'aligne sur la pastille sans toucher à la règle qu'elle partage avec les
 *   pastilles-boutons des autres écrans. */
.cc a.rp-chip{text-decoration:none}
.cc .rp-chip.on{border-color:var(--blue);background:var(--bl-025);color:var(--blue-7);
  font-weight:800}
.cc .rp-chip.on i{color:var(--blue-7)}
.cc .rp-chip .faint{font-variant-numeric:tabular-nums;font-weight:800;font-size:.74rem}

/* ══ LE RÉPERTOIRE DES MOIS (fiche de paie, 2026-09-05) ══════════════════════
 * 🔴 DOUZE PASTILLES « 2026-09 » DÉBORDAIENT SUR DEUX LIGNES, au-dessus de
 *    quatre cartes qui flottaient aussi : rien ne reliait le choix du mois aux
 *    nombres qu'il commande. Le modèle repris est celui du répertoire de
 *    `liste-des-classes-et-cours.php` — étiquette, barre d'outils, grille — et
 *    la bascule est LA MÊME (`.stu-vues`/`.stu-vbtn`, dans `shell.css`) : on
 *    n'a pas écrit un second composant qui lui ressemble.
 *
 * ⚠ LE CONTENEUR EST `.sec`, QUI EST DÉJÀ BLANC dans ce module depuis le fond
 *   posé plus haut. Ajouter une carte à l'intérieur aurait empilé deux
 *   surfaces — le défaut que `.cc .sec .rp-bloc` annule justement. */
.cc .rp-repert-bar{display:flex;gap:12px;align-items:center;flex-wrap:wrap;
  margin-bottom:14px}
/* L'aide se range à droite, comme la pastille de compte d'un en-tête. */
.cc .rp-repert-aide{margin-inline-start:auto}
/* Le compte des mois d'une année, dans son bouton — même forme que la pastille
   de compte des onglets du shell (`.tab .c`). */
.cc .rp-repert-n{background:var(--surf);color:var(--ink3);border-radius:999px;
  font-size:.7rem;font-weight:800;padding:1px 7px;margin-inline-start:5px}
.cc .stu-vbtn.on .rp-repert-n{background:var(--bl);color:var(--blue-7)}

/* 🔴 `hidden` NE SUFFIT PAS SUR UNE PASTILLE : `.rp-chip` pose
 *    `display:inline-flex`, qui l'emporte sur le `display:none` du navigateur.
 *    Sans cette ligne, la bascule d'année ne cachait rien du tout. */
.cc .rp-chip[hidden]{display:none}

/* Le mois se lit en deux temps : son NOM, puis son année en second plan. Un
   code « 2026-09 » se déchiffre ; un nom se lit. */
.cc .rp-chip.rp-mois{padding:8px 14px;gap:7px}
.cc .rp-chip.rp-mois .m{font-weight:750}
.cc .rp-chip.rp-mois .a{font-size:.72rem;color:var(--ink3);font-variant-numeric:tabular-nums}
.cc .rp-chip.rp-mois.on .a{color:var(--blue-7)}
/* Le point du bulletin déjà émis. Il porte un `title`, et l'aide de la barre
   dit ce qu'il signifie : une couleur seule ne se lit pas. */
.cc .rp-mois-pt{width:7px;height:7px;border-radius:50%;flex:none;
  background:var(--ink3)}
.cc .rp-mois-pt.ok{background:var(--green,#16a06a)}
.cc .rp-mois-pt.info{background:var(--blue)}
.cc .rp-mois-pt.brouillon{background:var(--amber)}

/* ══ LA CARTE DE CRÉDIT IA (2026-09-05) ═════════════════════════════════════
 * 🔴 UNE BARRE DE QUOTA N'EST PAS UN LIEU D'ACHAT. La jauge partagée disait le
 *    solde, et le propriétaire a répondu deux fois « je ne vois pas le bouton ».
 *    Une carte, un nombre lisible, un prix, un champ et un bouton : le geste est
 *    là où l'information est.
 *
 * ⚠ ELLE VIT DANS LA FEUILLE DU MODULE, pas dans la page : trois écrans la
 *   rendent (tableau de bord, assistant, devoirs).
 *
 * ⚠ LES TROIS TONS SONT CEUX DU MODULE (`--line`, `--amber`, `--danger`), pas
 *   trois nouvelles couleurs. Une carte qui vire au rouge doit virer au MÊME
 *   rouge que les notes de la page. */
.cc .rp-credit{background:var(--surf2);border:1px solid var(--line);border-radius:16px;
  padding:16px 18px}
.cc .rp-credit.warn{border-color:var(--amber);background:var(--amber-l,var(--surf2))}
.cc .rp-credit.ko{border-color:var(--danger,#d64b4b)}
.cc .rp-credit-h{display:flex;align-items:center;gap:8px;font-size:.9rem;color:var(--ink)}
.cc .rp-credit-h i{color:var(--stu-or-k,#b35c36)}
.cc .rp-credit-p{margin-inline-start:auto;font-size:.72rem;font-weight:700;color:var(--ink3);
  background:var(--surf);border:1px solid var(--line);border-radius:999px;padding:2px 10px}
/* Le solde se lit d'un coup d'œil : le nombre porte, le quota accompagne. */
.cc .rp-credit-n{display:flex;align-items:baseline;gap:7px;margin-top:10px}
.cc .rp-credit-n b{font-size:1.7rem;font-weight:800;line-height:1.1;color:var(--ink);
  font-variant-numeric:tabular-nums}
.cc .rp-credit-n span{font-size:.8rem;color:var(--ink3)}
.cc .rp-credit-j{height:8px;border-radius:999px;background:var(--line2,var(--line));
  overflow:hidden;margin-top:9px}
.cc .rp-credit-j i{display:block;height:100%;border-radius:999px;background:var(--blue)}
.cc .rp-credit.warn .rp-credit-j i{background:var(--amber)}
.cc .rp-credit.ko .rp-credit-j i{background:var(--danger,#d64b4b)}
.cc .rp-credit-m{margin:9px 0 0;font-size:.82rem;font-weight:650;color:var(--ink2)}
.cc .rp-credit-q{margin:9px 0 0;font-size:.8rem;color:var(--ink3);line-height:1.5}

/* ⚠ L'ÉTIQUETTE DU CHAMP EST VISIBLE, PAS CACHÉE. « Lots » tout court ne dit
     rien ; c'est la phrase du dessus qui donne la valeur d'un lot, et il faut
     que le champ soit nommé pour qui n'a pas lu la phrase. */
/* 🔴 « LOTS » ET « COMMANDER » TENAIENT SUR TROIS LIGNES (relevé 05-09 au soir,
 *    capture du propriétaire). Mesuré dans la colonne étroite de l'écran ALIE :
 *
 *      largeur disponible                    341 px
 *      étiquette 24 + champ 78 + bouton 235  337 px
 *      + deux écarts de 9 px                 355 px   → 14 px de trop
 *
 *    Quatorze pixels, et `flex-wrap:wrap` renvoyait le bouton à la ligne — puis
 *    `margin-inline-start:auto` le poussait à droite, seul, détaché du champ
 *    qu'il commande. La rangée occupait 88 px de haut pour un geste d'une ligne.
 *
 * ⚠ ON NE GAGNE PAS CES 14 px EN RÉTRÉCISSANT AU MILLIMÈTRE. Le libellé se
 *   traduit en huit langues : « Order credits », « اطلب أرصدة »… Un ajustement
 *   calculé sur la longueur du français aurait tenu jusqu'au premier changement
 *   de dictionnaire, et se serait cassé sans que personne ne le voie.
 *
 *   Le bouton prend donc CE QUI RESTE (`flex:1 1 auto` + `min-width:0`) au lieu
 *   d'exiger sa largeur naturelle, et son texte s'abrège par une ellipse s'il
 *   n'a vraiment pas la place — comme le titre d'une carte de classe. La rangée
 *   ne se casse plus, quelle que soit la langue.
 *
 * ⚠ ET `margin-inline-start:auto` DISPARAÎT : il n'avait de sens que pour
 *   pousser le bouton au bout d'une ligne où il restait de la place. Le champ et
 *   son bouton se lisent mieux côte à côte — c'est un seul geste, pas deux.
 *
 * ⚠ SOUS 900 px la grille se replie sur une colonne : la rangée retrouve toute
 *   la largeur, et le bouton reprend sa taille naturelle sans rien à faire. */
.cc .rp-credit-a{display:flex;align-items:center;gap:9px;flex-wrap:nowrap;margin-top:14px}
.cc .rp-credit-l{font-size:.78rem;font-weight:700;color:var(--ink3);flex:none}
.cc .rp-credit-a input{width:64px;flex:none;border:1px solid var(--line);border-radius:10px;
  background:var(--surf);color:var(--ink);font:inherit;font-size:.86rem;padding:8px 6px;
  text-align:center}
.cc .rp-credit-a .btn{flex:1 1 auto;min-width:0;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;justify-content:center}
/* 🔴 SUR TÉLÉPHONE, LE BOUTON PREND SA PROPRE LIGNE — ET C'EST LE CONTRAIRE
 *    D'UN RENONCEMENT. Mesuré : à 375 px la rangée ne fait plus que 297 px, et
 *    « Commander des crédits » en réclame 235 ; tenir la ligne unique à tout
 *    prix ABRÉGEAIT le libellé de l'action principale — « Commander des cré… ».
 *    Tronquer ce qu'on demande à l'utilisateur de presser est pire que de le
 *    descendre d'une ligne, où il a toute la largeur pour se lire.
 * ⚠ LA DEMANDE DU PROPRIÉTAIRE PORTAIT SUR LA COLONNE ÉTROITE DU BUREAU, où les
 *   341 px disponibles suffisent exactement : là, la rangée reste d'un seul
 *   tenant. Le repli ne s'applique qu'en dessous de 900 px.
 * ⚠ L'ELLIPSE RESTE, en dernier recours : elle ne se déclenche plus que si même
 *   une ligne entière ne suffit pas — et elle ne peut plus faire déborder la
 *   page, depuis le `min-width:0` posé sur les enfants de la grille. */
@media (max-width:900px){
  .cc .rp-credit-a{flex-wrap:wrap}
  .cc .rp-credit-a .btn{flex:1 1 100%}
}

/* ══ L ÉCRAN DE L ASSISTANT (2026-09-05) ════════════════════════════════════
 * ⚠ DEUX COLONNES INÉGALES : la conversation prend les deux tiers, le crédit
 *   et les garanties le tiers. `.rp-grid2` seul donne DEUX COLONNES ÉGALES
 *   (`auto-fit,minmax(320px,1fr)`) — ce qui étranglerait le fil et laisserait
 *   du blanc à droite. Le modificateur ne change que la répartition ; le repli
 *   sous 900 px reste celui de la grille du module.
 *
 * ⚠ ET LE CHAT PERD SON CADRE DANS UNE CARTE. `.rp-chat` porte son propre fond
 *   et son propre trait — utiles quand il flottait sur le fond de page, deux
 *   surfaces empilées maintenant qu il vit dans un `.sec` blanc. Même geste que
 *   `.cc .sec .rp-bloc`, et pour la même raison. */
.cc .rp-grid2.rp-alie{grid-template-columns:minmax(0,1.9fr) minmax(0,1fr)}
/* 🔴 `1fr` SEUL VAUT `minmax(auto,1fr)`, ET `auto` NE DESCEND PAS SOUS LE
 *    CONTENU MINIMAL. Éprouvé le 2026-09-05 en allongeant volontairement le
 *    libellé du bouton de commande : la colonne s'est étirée à 1 808 px au lieu
 *    de laisser le bouton s'abréger, et toute la page débordait latéralement.
 *    C'est le débordement classique des grilles, et il ne se voit qu'avec un
 *    contenu insécable — donc jamais en français, et peut-être en arabe.
 * ⚠ `min-width:0` SUR LES ENFANTS AUSSI : la piste `minmax(0,…)` autorise la
 *   colonne à rétrécir, mais l'élément qu'elle contient garde, lui, sa largeur
 *   minimale automatique. Les deux sont nécessaires — l'un sans l'autre ne fait
 *   rien de visible, ce qui est la meilleure façon de croire le défaut corrigé. */
@media (max-width:900px){.cc .rp-grid2.rp-alie{grid-template-columns:minmax(0,1fr)}}
.cc .rp-grid2.rp-alie > *{min-width:0}
.cc .sec .rp-chat{background:none;border:0;border-radius:0}
.cc .sec .rp-chat .rp-flux{padding:2px 0 12px}

/* Les garanties de l assistant : la même forme que `.its-liste`, sans en
   dépendre — `it.css` n est pas chargée par ce module. */
.cc .rp-garanties{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:10px}
.cc .rp-garanties li{display:flex;align-items:flex-start;gap:9px;font-size:.85rem;
  color:var(--ink2);line-height:1.55}
.cc .rp-garanties li i{flex:none;margin-top:3px;font-size:.95em}
.cc .rp-garanties li i.oui{color:var(--green,#16a06a)}
.cc .rp-garanties li i.non{color:var(--danger,#d64b4b)}
.cc .rp-garanties li i.hum{color:var(--stu-or-k,#b35c36)}
@media (max-width:520px){.cc .rp-credit-a .btn{margin-inline-start:0;flex:1 1 100%}}

/* Sur téléphone, les mois défilent plutôt que de casser la carte en trois
   lignes — même parti que `.mk-filtres`. */
@media (max-width:640px){
  .cc #rpMois{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px;
    -webkit-overflow-scrolling:touch}
  .cc #rpMois > *{flex:0 0 auto}
  .cc .rp-repert-aide{margin-inline-start:0;flex:1 1 100%}
  /* 🔴 LE COMPTE DISPARAÎT AVEC L ETIQUETTE. Sous 640 px, le shell replie un
     `.stu-vbtn` inactif sur son seul pictogramme (`font-size:0`) ; ma pastille
     de compte, elle, gardait sa taille propre et survivait — on lisait « 9 »
     tout seul, puis une icône et « 3 », sans savoir de quelles années il
     s agissait. Vu à l écran, pas déduit. */
  .cc .rp-repert-n{display:none}
}

/* Deux états qu'aucune pastille existante ne portait : un sujet animé depuis la
   dernière visite, et la ligne qui est la vôtre dans l'annuaire. */
.cc .rp-pill.neuf{background:var(--blue);color:#fff;border:1px solid var(--blue)}
.cc .rp-pill.moi{background:var(--bl);color:var(--blue-7);border:1px solid var(--bl2)}

/* ⚠ `.lui` PARTAGE LA RÈGLE DE `.ia`, il ne la recopie pas. La bulle « d'en
 *   face » a exactement la même forme, qu'elle vienne d'un assistant ou d'un
 *   confrère ; seul le NOM de la classe change, pour que le fil du quorum ne
 *   prétende pas parler à une IA. */
.cc .rp-bulle.lui{align-self:flex-start;background:var(--surf2);color:var(--ink);
  border:1px solid var(--line);border-bottom-left-radius:4px}
/* ⚠ LA SIGNATURE EST DANS LA BULLE, DONC SOUS `white-space:pre-wrap` : elle est
 *   posée en bloc pour ne pas hériter d'un retour à la ligne du corps. */
.cc .rp-bulle .qb-nom{display:block;font-size:.74rem;font-weight:800;margin-bottom:3px;
  color:var(--blue-7)}
.cc .rp-bulle .qb-h{display:block;margin-top:5px;font-size:.68rem;opacity:.7;
  font-variant-numeric:tabular-nums}
.cc .rp-bulle.moi .qb-nom{color:#fff}

/* ── LE RYTHME, DERNIER MOT ───────────────────────────────────────────────────
 * 🔴 CES TROIS-LÀ BATTAIENT `.cc > * + *` À ÉGALITÉ DE SPÉCIFICITÉ (deux classes
 *    chacune), et l'ordre du fichier tranchait en leur faveur : une page qui
 *    commence par une barre d'onglets, un bandeau d'information ou une rangée de
 *    pastilles avait donc 18, 12 ou 14 px là où tout le reste en a 26.
 *
 * ⚠ BORNÉ AUX ENFANTS DIRECTS DE `.cc` : les mêmes classes servent AUSSI à
 *   l'intérieur des sections, où leur écart propre est le bon. `>` est ce qui
 *   distingue « un bloc de la page » de « un élément dans un bloc » — sans lui,
 *   on aurait écarté de 26 px des pastilles collées à leur titre.
 *
 * ⚠ ET EN FIN DE FEUILLE, délibérément : à spécificité égale, c'est l'ordre qui
 *   décide. Le poser plus haut n'aurait rien changé, en silence. */
.cc > .rp-tabs + *,
.cc > * + .rp-tabs,
.cc > * + .rp-note,
.cc > * + .rp-chips{margin-top:28px}

/* 🔴 CES QUATRE COUPLES ÉTAIENT TOMBÉS DANS LA RÈGLE SUIVANTE (relevé 05-09,
 *    au soir). Le sélecteur de la barre d'outils avait été ajouté À LA SUITE de
 *    la liste, sans fermer l'accolade : les quatre couples ci-dessus héritaient
 *    donc des **18 px de la barre**, alors qu'ils décrivent des blocs de premier
 *    niveau. Une virgule de trop, aucun message, et un rythme faux sur toutes
 *    les pages qui ouvrent par un encart ou une barre d'onglets.
 *    Les deux règles sont désormais SÉPARÉES, et c'est visible à la lecture.
 *
 * ⚠ `.rp-outils` DOIT RESTER À PART : `.cc .rp-outils` pose ses marges et pèse
 *   (0,2,0) — plus lourd que `.cc > * + *`. Sans un couple nommé, la barre
 *   garderait son écart propre au milieu d'une page au rythme du module. C'est
 *   exactement le reproche fait à la liste nommée : elle oublie toujours le
 *   suivant.
 *
 * 🔴 MAIS ELLE NE PREND PAS LE RYTHME DES BLOCS, ET C'ÉTAIT LE DÉFAUT (05-09).
 *    À écart égal des deux côtés, la barre flottait au milieu du blanc, à égale
 *    distance de ce qui précède et de ce qu'elle COMMANDE — la capture du
 *    propriétaire ne montrait que cela : une ligne de contrôles perdue.
 *    Une barre d'outils n'est pas un sujet, c'est l'en-tête de ce qui suit :
 *    18 px au-dessus, 12 en dessous. L'asymétrie EST l'information.
 *
 * ⚠ ET LES 12 px SE POSENT ICI, PAS SEULEMENT EN `margin-bottom`. Deux marges
 *   verticales adjacentes ne s'additionnent pas : elles se fondent sur la PLUS
 *   GRANDE. Le `margin-bottom:12px` de la barre était donc écrasé par le
 *   `margin-top` du bloc suivant, et personne ne voyait pourquoi. */
.cc > * + .rp-outils{margin-top:18px}
.cc > .rp-outils + *{margin-top:12px}

/* ⚠ LA RANGÉE D'INDICATEURS EN TÊTE DE PAGE N'A PLUS BESOIN D'UNE RÈGLE À ELLE.
 *   Le shell pose déjà `.cc:not(.cc-air) > .kpis:first-child{margin-top:28px}`,
 *   c'est-à-dire EXACTEMENT le rythme que le module retient désormais. La copie
 *   qui vivait ici ne servait qu'à ramener `repetiteur-revenus.php` sur la
 *   valeur du module quand celle-ci s'en écartait ; les deux ayant convergé, la
 *   garder serait entretenir une seconde définition du même écart — et deux
 *   définitions du même écart finissent toujours par diverger. */

/* ══ ET LE PREMIER BLOC NE COLLE PLUS AU BANDEAU (2026-09-05) ════════════════
 * 🔴 CES DEUX LIGNES VALAIENT `margin-top:0`, ET C'ÉTAIT LE DÉFAUT SIGNALÉ.
 *    Écrites la veille pour que la barre d'onglets ou l'encart d'information ne
 *    prenne pas DEUX écarts quand il ouvre la page, elles réglaient un problème
 *    qui n'existait pas — le `.cc` n'a pas de marge propre — et en créaient un
 *    vrai : le bloc se retrouvait bord à bord avec le bandeau.
 *
 * ⚠ LA RÈGLE EST GÉNÉRIQUE, PAS UNE LISTE. Les huit écrans concernés ouvrent
 *   leur `.cc` par six classes différentes (`.rp-bloc`, `.rp-note`, `.rp-kpis`,
 *   `.rp-grid2`, `.rp-outils`, `.rp-chat`) ; en énumérer cinq aurait laissé la
 *   sixième collée, et la septième page à écrire avec elle. `:first-child` les
 *   prend toutes, y compris celles qui n'existent pas encore.
 *
 * ⚠ UN `<script>` EN TÊTE DE `.cc` NE COMPTE PAS : il ne se voit pas, mais il
 *   EST le premier enfant, et il volerait la marge au bloc qui le suit — lequel
 *   n'est alors plus `:first-child`. C'est le même écueil que `.cc-air` traite
 *   par `:not(script)`. Ici on l'exclut du côté du premier enfant ET on rend la
 *   marge au suivant.
 *
 * ⚠ ET UN PREMIER ENFANT `hidden` LA REND AUSSI : la règle `[hidden]` plus haut
 *   pèse (0,1,1), moins que (0,2,0), donc elle ne suffirait pas ici. */
.cc > :first-child:not(script),
.cc > script:first-child + *{margin-top:28px}
.cc > [hidden]:first-child{margin-top:0}
.cc > *[class*="rp-mt"]:first-child{margin-top:0}

/* ══ UN SEUL NOMBRE, CELUI DE L'APPLICATION (2026-09-05, au soir) ════════════
 * 🔴 LE MODULE AVAIT PRIS 32 px, ET C'ÉTAIT TROP. La valeur venait de `.cc-air`
 *    — le rythme que les espaces commercial et modération se sont donné — et
 *    elle avait été reprise ici par analogie : « mêmes écrans denses, même
 *    besoin d'air ». Le propriétaire a tranché à la capture : les écarts entre
 *    sections se voyaient plus que les sections. On revient donc au rythme du
 *    shell, `.sec{margin-top:28px}`, qui EST le standard de l'application.
 *
 * ⚠ ET LA REQUÊTE DE MÉDIA QUI VIVAIT ICI A DISPARU AVEC LUI. Elle ramenait le
 *   téléphone de 32 à 22 px, c'est-à-dire qu'elle corrigeait un écart que le
 *   module n'a plus. Le shell, lui, ne réduit PAS `.sec` sur téléphone : garder
 *   une réduction propre au module aurait été s'écarter du standard par l'autre
 *   bout, et redonner deux valeurs à un même intervalle. Un seul nombre, 28,
 *   partout — c'est ce qui se vérifie d'un coup d'œil sur une capture. */

/* ⚠ LES TUILES DE « MON ACTIVITÉ » DANS UN BLOC BLANC (2026-09-06). Elles
 *   portent la classe `.rp-kpi`, pas `.kpi` du shell : la règle posée plus haut
 *   pour la grille du tableau de bord ne les couvrait donc pas, et six carrés
 *   blancs cerclés sur un fond blanc font carte-dans-carte. Même geste, même
 *   raison — le gris léger leur rend leur relief. */
.cc .rp-bloc .rp-kpis{margin:0}
.cc .rp-bloc .rp-kpi{background:var(--surf2);box-shadow:none}

/* ══ AUCUNE BARRE D'OUTILS NE S'ARRÊTE AVANT LE BORD (2026-09-06) ════════════
 *
 * 🔴 TROIS D'ENTRE ELLES LAISSAIENT UN GRAND VIDE À DROITE. Mesuré à 1 115 px de
 *    large : `repetiteur-devoirs` 558 px de vide, `repetiteur-revenus` 483,
 *    `repetiteur-planning` 458. Ces trois-là n'ont PAS de champ de recherche —
 *    seulement des onglets et un bouton d'action — donc rien qui puisse absorber
 *    l'espace libre, et la rangée s'interrompait au tiers de la largeur.
 *
 * ⚠ ON POUSSE LE BOUTON, ON N'ÉTIRE PAS LES ONGLETS. Donner `flex:1` à
 *   `.stu-vues` aurait distendu les pastilles jusqu'à ce qu'elles ne se lisent
 *   plus comme un groupe. Le bouton d'action, lui, a sa place naturelle au bout
 *   de la ligne : c'est la convention du shell (`.panehead > form:last-child`).
 *
 * ⚠ SANS EFFET LÀ OÙ LE CHAMP OCCUPE DÉJÀ TOUT : sur « Mes élèves » et
 *   « Séances », `.rp-q{flex:1 1 320px}` ne laisse aucun espace libre, et une
 *   marge automatique de zéro ne déplace rien. Une seule règle pour les deux
 *   formes de barre — pas une exception par écran. */
.cc .rp-outils > .btn:last-child{margin-inline-start:auto}
