/**
 * LE REPLI POUR UN SITE QUI N'EMPLOIE PAS CORPUS - 24 septembre 2026
 *
 * POURQUOI CE FICHIER EXISTE. Cyrille ne peut pas faire de publicite pour
 * Corpus sur le site des extensions de Joomla.org : il n'y presente que ses
 * modules. Ce module doit donc fonctionner AU MINIMUM sous Cassiopeia, en plus
 * de Corpus. Ce n'est pas une option.
 *
 * IL NE SE CHARGE QUE SANS CORPUS. Le repartiteur regarde si la feuille
 * `template.corpus` est declaree ; si elle l'est, ce fichier n'est jamais
 * demande. Consequence : ZERO octet et ZERO risque de regression pour les
 * utilisateurs de Corpus, qui sont les seuls clients d'aujourd'hui.
 *
 * CE QU'IL CONTIENT, ET RIEN DE PLUS :
 *
 *   1. LES JETONS. Corpus en pose une centaine dans `:root` ; le module en
 *      emploie une trentaine. Quarante-et-un de ses `var()` portaient deja un
 *      repli en ligne, huit n'en avaient aucun. Tout est declare ici, une
 *      fois, ce qui evite d'avoir a ecrire un repli dans chaque `var()`.
 *
 *      UN `:root` ICI NE PEUT RIEN ECRASER, puisque ce fichier n'existe pas
 *      quand Corpus est la. C'est ce qui rend la solution sure.
 *
 *   2. LES CLASSES DU TEMPLATE que les mises en page ecrivent : `.bouton`,
 *      `.carte`, `.message`, `.accordeon`, `.etiquette`, `.corpus-specs`,
 *      `.note`. Elles sont reprises de `template.css`, allegees de ce qui ne
 *      sert pas au module.
 *
 * CE QU'IL NE CONTIENT PAS : les classes de Bootstrap (`badge`, `carousel-*`,
 * `visually-hidden`, `list-unstyled`, `rounded-circle`), livrees par Joomla a
 * tout le site, Cassiopeia compris.
 *
 * LES COULEURS VIENNENT DU SITE D'ACCUEIL QUAND IL LES DONNE, et c'est la
 * remarque de Cyrille du 24 septembre 2026 : « l'accent ne devrait pas etre la
 * valeur primaire de Cassiopeia ? » Si, evidemment.
 *
 * MESURE FAITE SUR SON BANC : Cassiopeia declare 160 proprietes sur `:root`,
 * dont `--cassiopeia-color-primary` (#112855), `--cassiopeia-color-link`
 * (#224faa), et les jetons de Bootstrap SANS le prefixe `bs-` : `--primary`,
 * `--secondary`, `--link-color`, `--body-color`, `--border-color`,
 * `--success`, `--warning`, `--danger`, `--info`, `--border-radius`.
 *
 * CHAQUE JETON PART DONC EN CASCADE DE REPLIS : d'abord le nom propre a
 * Cassiopeia, puis le nom generique de Bootstrap, puis notre valeur neutre.
 * Un module pose dans un autre template Bootstrap prend ses couleurs a lui ;
 * un template qui n'expose rien retombe sur le gris, qui ne jure avec rien.
 * Rien n'est devine, tout est lu.
 *
 * LE GRIS ARDOISE RESTE LE DERNIER REPLI, et celui qui veut les siennes
 * redeclare trois jetons dans l'onglet CSS du module.
 *
 * MAIS PAS `currentColor` POUR UN FOND, jamais : il vaut la couleur du texte de
 * l'element, y compris celle qu'on vient de lui poser. Un bouton qui ecrit son
 * texte en blanc puis son fond en `currentColor` sort blanc sur blanc. Mesure
 * faite le 24 septembre 2026, sur le bandeau d'appel.
 */

/* ---------------------------------------------------------------------------
   1. LES JETONS
   --------------------------------------------------------------------------- */
/* LE RELAIS QUI CASSE LE CYCLE SUR `--info`. Bootstrap et Corpus donnent LE
   MEME NOM a ce jeton. Ecrire `--info: var(--info, ...)` sur `.opus`
   fait un CYCLE, et le CSS rend alors la propriete invalide, sans un mot dans
   la console. La sortie est de lire la valeur du site UN CRAN PLUS HAUT, sur
   `:root`, ou notre `--info` n'existe pas encore : la, `var(--info)` designe
   sans ambiguite celui de Bootstrap. Le nom du relais est prefixe pour ne
   croiser celui de personne. */
:root {
  --opus-info: var(--info, #30638d);
}

.opus {
  /* L'echelle d'espacement. Les six valeurs de Corpus, a l'identique. */
  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 24px;
  --e-6: 32px;
  --e-7: 40px;
  --gouttiere: var(--e-5);
  --gouttiere-grille: var(--e-5);

  /* Les traits et les angles. */
  --trait: 1px;
  --trait-fort: 2px;
  --angle: var(--border-radius, 0.25rem);
  --angle-lg: var(--border-radius-lg, 0.5rem);
  --filet-part: 70%;
  --filet-epaisseur: 2px;

  /* Les couleurs, neutres faute de connaitre la charte du site. */
  --encre: currentColor;
  --texte-doux: var(--gray-600, rgb(0 0 0 / 62%));
  --bord: var(--border-color, rgb(0 0 0 / 15%));
  --bord-fort: var(--gray-600, rgb(0 0 0 / 30%));
  /* L'ACCENT EST UNE VRAIE COULEUR, ET SURTOUT PAS `currentColor`.
     Premiere version : `--accent: currentColor`, pour ne rien imposer. Le
     bouton sortait blanc sur blanc. « Sur le bandeau d'appel, je vois le
     bouton HS », Cyrille, 24 septembre 2026, et la cause est un piege connu de
     `currentColor` : il vaut la couleur du texte DE L'ELEMENT, y compris celle
     qu'on vient de lui poser. Le bouton ecrit `color: var(--accent-texte)`,
     donc blanc, puis `background: var(--accent)`, donc `currentColor`, donc
     blanc aussi.
     UN GRIS ARDOISE PLUTOT QU'UNE COULEUR : il ne jure avec aucune charte,
     porte du texte blanc sans effort de contraste, et se remplace par une
     ligne dans l'onglet CSS du module pour qui veut la sienne. */
  --accent: var(--cassiopeia-color-primary, var(--primary, #2b3137));
  --accent-texte: #fff;
  /* LES DEUX DERIVES DE L'ACCENT. La premiere ligne est la valeur neutre, que
     garde un navigateur sans `color-mix` ; la seconde la remplace partout
     ailleurs et suit alors l'accent du site. */
  --accent-doux: rgb(43 49 55 / 6%);
  --accent-doux: color-mix(in srgb, var(--accent) 8%, transparent);
  --accent-trait: rgb(43 49 55 / 25%);
  --accent-trait: color-mix(in srgb, var(--accent) 25%, transparent);
  --accent-survol: var(--cassiopeia-color-hover, var(--link-color, #3c444d));
  --accent-actif: var(--cassiopeia-color-primary, var(--primary, #1e2226));
  --fond: var(--body-bg, #fff);
  --fond-alt: var(--gray-100, rgb(0 0 0 / 3%));
  --fond-creuse: var(--gray-100, rgb(0 0 0 / 3%));
  --fond-teinte: var(--gray-200, rgb(0 0 0 / 6%));
  --fond-eleve: var(--body-bg, #fff);

  /* LES QUATRE COULEURS D'ETAT VIENNENT DU SITE. `--info` passe par le relais
     pose sur `:root` plus haut ; les trois autres se raccrochent directement,
     leurs noms francais ne croisant rien (`--succes` n'est pas `--success`).
     LES FONDS SE CALCULENT A PARTIR DU TON, au lieu d'etre quatre valeurs
     choisies par nous : un dixieme de la couleur sur le fond du site. Chaque
     ligne en dur garde un navigateur sans `color-mix` a flot. */
  --info: var(--opus-info);
  --info-fond: #eaf2f8;
  --info-fond: color-mix(in srgb, var(--info) 10%, var(--body-bg, #fff));
  --succes: var(--success, #1f6b3d);
  --succes-fond: #eaf5ee;
  --succes-fond: color-mix(in srgb, var(--succes) 10%, var(--body-bg, #fff));
  --alerte: var(--warning, #8a5300);
  --alerte-fond: #fdf3e3;
  --alerte-fond: color-mix(in srgb, var(--alerte) 10%, var(--body-bg, #fff));
  --erreur: var(--danger, #a02127);
  --erreur-fond: #fbeded;
  --erreur-fond: color-mix(in srgb, var(--erreur) 10%, var(--body-bg, #fff));

  /* La forme des pieces. */
  --forme-carte-fond: var(--body-bg, #fff);
  --forme-carte-bordure: 1px solid var(--border-color, rgb(0 0 0 / 15%));
  --forme-carte-angle: var(--border-radius, 0.5rem);
  --forme-carte-ombre: none;
  --forme-carte-ombre-survol: var(--box-shadow-sm, 0 2px 8px rgb(0 0 0 / 10%));
  --forme-carte-fond-survol: var(--body-bg, #fff);
  --forme-bouton-angle: var(--border-radius, 0.25rem);
  --forme-message-angle: var(--border-radius, 0.25rem);
  --forme-etiquette-angle: 999px;
  --forme-panneau-bordure: var(--trait) solid var(--bord);
  --forme-panneau-angle: var(--border-radius-lg, 0.5rem);
  --forme-image-angle: var(--border-radius, 0.25rem);
  --forme-image-bordure: 0;
  --ombre-douce: none;
  --ombre-flottante: var(--box-shadow, 0 2px 8px rgb(0 0 0 / 10%));
  /* LE FOCUS PREND LA COULEUR DE LIEN DU SITE, qui est celle que le visiteur
     associe deja a « ce sur quoi on agit ». */
  --focus: var(--cassiopeia-color-link, var(--link-color, #1c5a86));
  --focus-halo: rgb(28 90 134 / 30%);
  --focus-halo: color-mix(in srgb, var(--focus) 30%, transparent);

  /* La typographie. Corpus lie ces tailles a son echelle ; ici on retombe sur
     des valeurs relatives, qui suivent au moins la taille de base du site. */
  --t-h1: 2rem;
  --t-h2: 1.5rem;
  --t-introduction: 1.125rem;
  --i-introduction: 1.5;
  --t-petit: 0.9375rem;
  --i-petit: 1.5;
  --t-mention: 0.8125rem;
  --i-mention: 1.4;
  --graisse-normale: 400;
  --graisse-appuyee: 600;
  --graisse-forte: 700;
}

/* ---------------------------------------------------------------------------
   LA RESPIRATION AUTOUR DU MODULE, 24 septembre 2026

   « Avec Cassiopeia je trouve que les marges sont vraiment faibles », Cyrille.
   Mesure sur le banc : HUIT PIXELS entre le bas du module et le contenu qui
   suit, et zero au-dessus.

   CE N'EST PAS UN OUBLI DE CASSIOPEIA, C'EST UN PARTAGE DES ROLES. Sous
   Corpus, la respiration vient de la SECTION qui porte le module :
   `template.css` pose `padding-block: var(--e-7)` sur `.section`, soit 40
   pixels en haut et en bas. Le module n'a donc jamais eu a s'en occuper.
   Cassiopeia, lui, pose ses modules dans une grille sans retrait vertical : le
   module se retrouve colle a ce qui l'entoure.

   LE MODULE POSE DONC LA SIENNE, ET SEULEMENT SANS CORPUS. Ce fichier ne se
   charge pas quand Corpus est la : aucun risque de doubler le retrait chez les
   clients d'aujourd'hui.

   `padding` ET NON `margin`, pour deux raisons. Les marges verticales se
   FUSIONNENT : deux modules l'un sous l'autre n'auraient qu'un seul ecart
   entre eux au lieu de deux, et l'espacement dependrait de ce qu'il y a autour.
   Et un fond de rangee pose sur toute la largeur doit couvrir ce retrait, ce
   qu'une marge ne permet pas.
   --------------------------------------------------------------------------- */
.opus {
  padding-block: var(--e-7);
}

/* SAUF DANS UNE CARTE DE CASSIOPEIA, 25 septembre 2026.

   « Les marges me semblent bien grandes », Cyrille, le lendemain. Le module
   etait cette fois pose avec le style de module « card » : la carte apporte
   deja son `card-body` a 16 px. Les trois retraits s'empilaient, 16 de la
   carte, 40 du module, 24 du fond teinte : 80 px entre le bord de la carte et
   le texte. Mesure apres retrait des 40 : 17 px entre le bord de la carte et
   l'aplat, en haut comme en bas.

   Le retrait du 24 septembre reste donc juste, mais seulement quand rien ne
   respire autour du module (style « none » ou « noCard »). Le selecteur vise
   l'enfant DIRECT de `card-body` : c'est ainsi que Cassiopeia pose un module,
   et un `.opus` place plus bas dans une carte d'un autre ordre garde les
   siens. */
.card-body > .opus {
  padding-block: 0;
}

/* PAS DE MODE SOMBRE A NOUS, et c'est une decision du 24 septembre 2026.
   Une premiere version suivait le reglage du navigateur. Elle avait un defaut
   grave : sur un site Cassiopeia en clair, un visiteur dont le navigateur est
   regle en sombre voyait le module passer au noir SEUL, au milieu d'une page
   restee blanche. Le module ne sait pas lire le theme du site d'accueil ; il
   ne doit donc rien decider. Il prend le fond du site (`--body-bg`) et la
   couleur de son texte, et suit ce que le site fait, y compris quand le site
   ne fait rien. Un template qui gere vraiment le sombre redeclare ses jetons,
   et le module suit sans une ligne de plus. */

/* ---------------------------------------------------------------------------
   2. LES CLASSES DU TEMPLATE

   TOUTES SONT PORTEES PAR `.opus`, et jamais posees seules. Un site
   d'accueil peut avoir SES `.carte` et SON `.message` : les habiller depuis un
   module serait exactement le defaut qu'on reproche aux extensions qui
   debordent de leur perimetre.
   --------------------------------------------------------------------------- */

/* --- Les deux teintes de fond ------------------------------------------- */
/* LE REGLAGE « FOND » ECRIT `section--alt` OU `section--tint`, classes de
   Corpus. Sous Corpus elles ne posent que le jeton `--fond-zone`, que
   `.opus__fond` peint (blocs.css). Sans Corpus, rien ne posait le jeton : le
   reglage ne faisait rien. On les reprend ici, bornees a `.opus__fond` pour
   ne jamais toucher une autre `section--alt` que porterait le site. */
.opus__fond.section--alt  { --fond-zone: var(--fond-alt); }
.opus__fond.section--tint { --fond-zone: var(--fond-teinte); }

/* --- La grille de douze, et ses colonnes --------------------------------- */
/* `tmpl/default.php` ECRIT `grille` ET `colonne-N` SUR CHAQUE RANGEE. Ces deux
   classes appartiennent au template Corpus, pas au module : sans elles, les
   colonnes redeviennent des blocs empiles et le montage se deforme. Mesure
   faite dans `media/css/template.css` de Corpus, l. 469 pour la grille, l. 8536
   pour le repli. Les memes valeurs, aux memes seuils. */
.opus .grille {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gouttiere-grille);
}

.opus .colonne-1  { grid-column: span 1; }
.opus .colonne-2  { grid-column: span 2; }
.opus .colonne-3  { grid-column: span 3; }
.opus .colonne-4  { grid-column: span 4; }
.opus .colonne-5  { grid-column: span 5; }
.opus .colonne-6  { grid-column: span 6; }
.opus .colonne-7  { grid-column: span 7; }
.opus .colonne-8  { grid-column: span 8; }
.opus .colonne-9  { grid-column: span 9; }
.opus .colonne-10 { grid-column: span 10; }
.opus .colonne-11 { grid-column: span 11; }
.opus .colonne-12 { grid-column: span 12; }

.opus .colonne--avant { order: -1; }
.opus .colonne--apres { order: 1; }

/* LE REPLI : sous 62rem, toute colonne prend la largeur entiere, sauf la
   douzieme qui la prenait deja. Corpus remet aussi l'ordre a plat. */
@media (max-width: 62rem) {
  .opus .colonne-1,  .opus .colonne-2,
  .opus .colonne-3,  .opus .colonne-4,
  .opus .colonne-5,  .opus .colonne-6,
  .opus .colonne-7,  .opus .colonne-8,
  .opus .colonne-9,  .opus .colonne-10,
  .opus .colonne-11 {
    grid-column: span 12;
  }

  .opus .colonne--avant,
  .opus .colonne--apres {
    order: 0;
  }
}

/* --- Le bouton, dans ses trois formats ----------------------------------- */
.opus .bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: 40px;
  padding: var(--e-2) var(--e-4);
  font: inherit;
  font-size: var(--t-petit);
  font-weight: var(--graisse-appuyee);
  text-decoration: none;
  cursor: pointer;
  border: var(--trait) solid transparent;
  border-radius: var(--forme-bouton-angle);
  background: var(--accent);
  color: var(--accent-texte);
}

.opus .bouton:hover {
  background: var(--accent-survol);
  color: var(--accent-texte);
  text-decoration: none;
}

.opus .bouton--second {
  background: transparent;
  color: inherit;
  border-color: var(--bord-fort);
}

.opus .bouton--second:hover {
  background: var(--accent-doux);
  color: inherit;
}

.opus .bouton--tertiaire {
  background: transparent;
  color: inherit;
  border-color: transparent;
  text-decoration: underline;
  min-height: auto;
  padding: 0;
}

/* --- La carte ------------------------------------------------------------ */
.opus .carte {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--forme-carte-fond);
  border: var(--forme-carte-bordure);
  border-radius: var(--forme-carte-angle);
  box-shadow: var(--forme-carte-ombre);
  overflow: hidden;
}

.opus .carte:hover {
  border-color: var(--bord-fort);
  box-shadow: var(--forme-carte-ombre-survol);
  background: var(--forme-carte-fond-survol);
}

.opus .carte:focus-within {
  outline: var(--trait-fort) solid var(--focus);
  outline-offset: 2px;
}

.opus .carte p {
  margin: 0;
  font-size: var(--t-petit);
  line-height: var(--i-petit);
}

.opus .carte__corps {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-4);
  flex: 1 1 auto;
}

.opus .carte__image {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.opus .carte__titre {
  margin: 0;
}

/* LE LIEN ETIRE, qui rend une carte cliquable en entier. Il vient de Corpus et
   non de Bootstrap, mesure du 22 septembre 2026 : il faut donc le refaire. */
.opus .carte__titre a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.opus__cartes--inerte .carte__titre a::after {
  content: none;
}

/* --- Le message, dans ses quatre tons ------------------------------------ */
.opus .message {
  display: flex;
  gap: var(--e-3);
  align-items: flex-start;
  padding: var(--e-3) var(--e-4) calc(var(--e-3) + 2px);
  border: 0;
  border-radius: var(--forme-message-angle);
  margin-bottom: var(--e-3);
  background: var(--fond-alt);
}

.opus .message p {
  margin: 0;
  font-size: var(--t-petit);
  line-height: var(--i-petit);
}

.opus .message__titre {
  font-weight: var(--graisse-appuyee);
}

/* LE PICTOGRAMME DE CORPUS N'EST PAS REPRIS : c'est un masque CSS qui pointe
   vers sa planche d'icones, absente ici. Le ton se lit au fond, au filet du bas
   et a la couleur du titre, qui portent deja le sens.

   DEUX TRAITS DE COULEURS DIFFERENTES, et c'est ce que Cyrille a vu le 24
   septembre 2026 : « le trait bleu a gauche et en dessous ». La cause etait
   chez nous. `_elements.php` ecrit `message rule message--<ton>`, exactement
   le balisage du tampon de Corpus ; or `template.css` l. 2373 pose
   `border: 0` sur `.message` et donne le ton au filet du bas, par
   `--filet-couleur`. Nous avions invente une bordure gauche EN PLUS, et laisse
   le filet du bas sur l'accent du site. D'ou deux traits, l'un au ton du
   message, l'autre a l'accent. Le dessin est desormais celui de Corpus, a la
   lettre : pas de bordure, un seul filet, au ton. */
.opus .message--info    { background: var(--info-fond);   --filet-couleur: var(--info); }
.opus .message--succes  { background: var(--succes-fond); --filet-couleur: var(--succes); }
.opus .message--alerte  { background: var(--alerte-fond); --filet-couleur: var(--alerte); }
.opus .message--erreur  { background: var(--erreur-fond); --filet-couleur: var(--erreur); }

/* LE TITRE PORTE LE TON, comme dans Corpus l. 2444. */
.opus .message--info   .message__titre { color: var(--info); }
.opus .message--succes .message__titre { color: var(--succes); }
.opus .message--alerte .message__titre { color: var(--alerte); }
.opus .message--erreur .message__titre { color: var(--erreur); }

/* --- L'accordeon --------------------------------------------------------- */
.opus .accordeon {
  border: var(--forme-panneau-bordure);
  border-radius: var(--forme-panneau-angle);
  overflow: hidden;
}

.opus .accordeon > :last-child {
  border-bottom: 0;
}

/* LE TRAIT EST SUR LE BOUTON, PAS SUR LE TITRE, et c'est ce que j'avais rate.
   « Sur Cassiopeia, il manque un trait au-dessus des questions », Cyrille,
   24 septembre 2026. Releve dans `template.css` l. 4921 : c'est
   `.accordeon__bouton` qui porte `border-bottom`, et le titre ne porte qu'une
   remise a zero de ses marges. Pose sur le titre, le trait disparaissait des
   que le bouton peignait son fond par-dessus. */
.opus .accordeon__titre {
  margin: 0;
  padding-bottom: 0;
  width: auto;
}

.opus .accordeon__bouton {
  display: flex;
  width: 100%;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-3) var(--e-4);
  font: inherit;
  font-size: var(--t-petit);
  font-weight: var(--graisse-appuyee);
  text-align: left;
  background: var(--fond-eleve);
  border: 0;
  border-bottom: var(--trait) solid var(--bord);
  color: var(--encre);
  cursor: pointer;
}

.opus .accordeon__bouton:hover {
  background: var(--fond-alt);
}

/* LE VOLET PORTE LE SIEN AUSSI : sans lui, le dernier volet ouvert n'aurait
   rien sous lui, et le bloc paraitrait coupe. */
.opus .accordeon__volet {
  padding: var(--e-4);
  border-bottom: var(--trait) solid var(--bord);
}

/* --- Les etiquettes ------------------------------------------------------ */
.opus .etiquettes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  list-style: none;
  margin: 0 0 var(--e-4);
  padding: 0;
}

.opus .etiquettes li {
  margin: 0;
}

.opus .etiquette {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: 2px var(--e-2);
  background: var(--accent-doux);
  color: inherit;
  border: var(--trait) solid var(--accent-trait);
  border-radius: var(--forme-etiquette-angle);
  font-size: var(--t-mention);
  line-height: var(--i-mention);
  font-weight: var(--graisse-appuyee);
  text-decoration: none;
}

/* --- La fiche de caracteristiques ---------------------------------------- */
.opus .corpus-specs > div {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--e-1);
  padding: var(--e-2) 0;
  border-bottom: var(--trait) solid var(--bord);
}

.opus .corpus-specs > div:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.opus .corpus-specs dt {
  margin-right: auto;
  padding-right: var(--e-4);
  font-weight: var(--graisse-normale);
  color: var(--texte-doux);
}

.opus .corpus-specs dd {
  margin: 0;
  font-weight: var(--graisse-forte);
}

/* --- Le tableau ---------------------------------------------------------- */
/* LE DESSIN DE `.tableau` DANS CORPUS, recopie de `template.css` (l. 4912 a
   4957, relu le 2 octobre 2026) avec les jetons du repli. Sans lui, la table
   de l'element Tableau sortirait sous Cassiopeia avec les seuls traits de
   Bootstrap, et ses reglages de bordure n'auraient rien a retirer.
   Le `.opus` devant : un site peut avoir SES `.tableau`.
   `:where()` AUTOUR DE LA CLASSE, ET C'EST MESURE A L'AVANCE : cette feuille
   est chargee APRES `blocs.css`. Avec `.opus` en plus, chaque regle pesait une
   classe de plus que celle de Corpus, donc autant que nos reglages, et les
   battait par l'ordre : les lignes alternees ne se decochaient plus sous
   Cassiopeia. `:where()` retire le poids de `.tableau` : il reste celui de
   `.opus`, une classe, exactement celui des regles de Corpus. */
.opus :where(.tableau) {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--t-petit);
  border: var(--forme-panneau-bordure);
  border-radius: var(--forme-panneau-angle);
  overflow: hidden;
}

.opus :where(.tableau) caption {
  caption-side: top;
  text-align: left;
  padding: 0 0 var(--e-2);
  font-size: var(--t-mention);
  color: var(--texte-doux);
}

.opus :where(.tableau) th,
.opus :where(.tableau) td {
  padding: var(--e-2) var(--e-3);
  text-align: left;
  border-bottom: var(--trait) solid var(--bord);
}

.opus :where(.tableau) thead th {
  background: var(--fond-alt);
  color: var(--encre);
  font-weight: var(--graisse-forte);
  font-size: var(--t-mention);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.opus :where(.tableau) tbody tr:last-child :is(th, td) {
  border-bottom: 0;
}

.opus :where(.tableau) tbody tr:nth-child(even) {
  background: var(--fond-creuse);
}

.opus :where(.tableau) tbody tr:hover {
  background: var(--accent-doux);
}

/* --- La mention discrete ------------------------------------------------- */
.opus .note {
  font-size: var(--t-mention);
  line-height: var(--i-mention);
  color: var(--texte-doux);
}

/* --- Le filet de titre --------------------------------------------------- */
.opus .rule {
  position: relative;
}

.opus .rule::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: var(--filet-part);
  height: var(--filet-epaisseur);
  /* `--filet-couleur` D'ABORD, l'accent ensuite. C'est ce que fait
     `template.css` l. 418, et c'est par la qu'un message donne sa couleur a son
     propre filet. L'avoir oublie donnait deux traits de couleurs differentes
     sur un meme bloc. */
  background: var(--filet-couleur, var(--accent));
  border-radius: var(--filet-epaisseur);
}

/* ---------------------------------------------------------------------------
   3. LA VISIONNEUSE DE LA GALERIE

   Elle est fabriquee par `sans-corpus.js`, donc elle vit HORS du module, en
   enfant de `body` : ses classes ne peuvent pas etre portees par
   `.opus`. Elles portent donc un nom a elles, assez long pour ne
   rencontrer personne.
   --------------------------------------------------------------------------- */
.opus-visionneuse {
  /* LE DESSIN ET LES MESURES DE CORPUS (`.visionneuse` de template.css,
     mesurees sur le banc le 28 septembre 2026). La boite est posee sur
     `body`, hors de `.opus` : les jetons du module n'y arrivent pas, d'ou ces
     trois relais, qui reprennent les memes sources et les memes replis. */
  --v-accent: var(--cassiopeia-color-primary, var(--primary, #2b3137));
  --v-doux: var(--gray-600, rgb(0 0 0 / 62%));
  --v-bord: var(--border-color, rgb(0 0 0 / 15%));
  width: min(64rem, 92vw);
  max-width: none;
  padding: 0;
  border: 1px solid var(--v-bord);
  border-radius: 0.5rem;
  background: var(--body-bg, #fff);
  color: var(--body-color, #14171a);
}

.opus-visionneuse::backdrop {
  background: rgb(0 0 0 / 80%);
}

.opus-visionneuse__corps {
  padding: 16px;
}

.opus-visionneuse img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 70vh;
  object-fit: contain;
  background: var(--gray-100, rgb(0 0 0 / 3%));
}

.opus-visionneuse__legende {
  margin: 12px 0 0;
  color: var(--v-doux);
  font-size: 1rem;
  line-height: 1.4;
}

.opus-visionneuse__pied {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
}

.opus-visionneuse__boutons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
}

.opus-visionneuse__rang {
  margin: 0;
  color: var(--v-doux);
  font-variant-numeric: tabular-nums;
}

/* Les boutons de Corpus : 6px 12px, angle 6px, 16px en demi-gras. La
   navigation a contour dans la couleur d'accent, Fermer plein. */
.opus-visionneuse button {
  padding: 6px 12px;
  font: inherit;
  font-size: 1rem;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--v-accent);
  border-radius: 6px;
  background: transparent;
  color: var(--v-accent);
}

.opus-visionneuse button:hover {
  background: color-mix(in srgb, var(--v-accent) 8%, transparent);
}

.opus-visionneuse .opus-visionneuse__fermer {
  background: var(--v-accent);
  color: #fff;
}

.opus-visionneuse .opus-visionneuse__fermer:hover {
  background: color-mix(in srgb, var(--v-accent) 85%, #000);
}

.opus-visionneuse button:focus-visible {
  outline: 3px solid var(--v-accent);
  outline-offset: 2px;
}

@media (prefers-color-scheme: dark) {
  .opus-visionneuse {
    --v-doux: rgb(255 255 255 / 66%);
    --v-bord: rgb(255 255 255 / 20%);
    background: #1b1f24;
    color: #f2f4f6;
  }

  .opus-visionneuse button:not(.opus-visionneuse__fermer) {
    border-color: rgb(255 255 255 / 34%);
    color: #f2f4f6;
  }
}

@media print {
  .opus-visionneuse { display: none; }
}

/* --- Le chevron de l'accordeon ---------------------------------------------
   « Il manque les chevrons », Cyrille, 24 septembre 2026, sous Cassiopeia.
   Corpus le pose en masque CSS (`template.css` l. 4938) ; sans Corpus, rien ne
   le posait.

   UN MASQUE ET NON UNE IMAGE : le chevron prend `currentColor`, donc il suit la
   couleur du texte du bouton, en clair comme en sombre, sans deuxieme regle.

   LE SVG EST EN LIGNE DANS LA REGLE, sans fichier a charger : c'est un trait,
   il pese moins cher ecrit ici qu'en requete.

   IL TOURNE QUAND LE VOLET S'OUVRE, et c'est `aria-expanded` qui le dit : le
   meme attribut sert a la machine et au dessin, donc les deux ne peuvent pas
   se contredire. */
.opus .accordeon__bouton::after {
  content: "";
  flex: none;
  margin-left: auto;
  width: 1.25em;
  height: 1.25em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 15.5 5.5 9l1.4-1.4L12 12.7l5.1-5.1L18.5 9 12 15.5Z'/></svg>") center/contain no-repeat;
  mask: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 15.5 5.5 9l1.4-1.4L12 12.7l5.1-5.1L18.5 9 12 15.5Z'/></svg>") center/contain no-repeat;
  transition: transform 0.15s;
}

.opus .accordeon__bouton[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

/* Le volet ferme ne se voit pas. Sans Corpus, `hidden` seul perd contre le
   `display` que nous posons sur le bouton voisin dans certaines feuilles. */
.opus .accordeon__volet[hidden] {
  display: none;
}

/* LE PICTOGRAMME LUI-MEME, MESURE DANS `template.css` l. 445 ET 452.
   Un `<svg>` sans dimension vaut 300 sur 150 pixels pour le navigateur : sans
   ces quatre lignes, l'icone d'un bouton sortait grande comme une image, et
   noire, puisque `fill` vaut `black` par defaut et non la couleur du texte.
   C'est le meme oubli que celui de la grille, trouve le meme jour. */
.opus .i {
  flex: none;
  fill: currentColor;
  vertical-align: -0.25em;
  width: 1.25em;
  height: 1.25em;
}
