/* =====================================================================
 * Page Réalisations — feuille de page
 *
 * Chargée APRÈS styles.css, qui reste en lecture seule pour cette page.
 * Tout ce qui est créé ici porte le préfixe « rea- », pour qu'aucun
 * sélecteur nouveau ne puisse entrer en collision avec le tronc commun et
 * que la fusion reste mécanique plutôt qu'arbitrale.
 *
 * Ce qui devra être PROMU au tronc commun à la fusion est signalé par
 * « [TRONC] ». Le reste appartient à la page.
 *
 * Version 013 — 27 août 2026. Passes mobiles 1 à 7 — la page est composée.
 * ===================================================================== */

/* ---------------------------------------------------------------------
 * [TRONC] Italique.
 *
 * Le tronc commun ne déclare que le romain, parce qu'aucune page n'en
 * avait besoin jusqu'ici. Le cadre de réalisation des lightboxes en a
 * besoin : il change de voix, pas de volume. Le fichier est sous-ensemblé
 * aux mêmes 647 glyphes que les quatre autres coupes du site.
 *
 * Regular Italic et non Light Italic : la ligne se pose sous un descriptif
 * déjà en Regular 14 gris bleuté, et une graisse 300 à ce corps sur cette
 * couleur devient fragile. Seule l'inclinaison doit changer.
 * ------------------------------------------------------------------- */

@font-face {
  font-family: "Source Sans 3 zeMoritz Web";
  src: url("assets/fonts/source-sans-3-italic.woff2?v=20260827a") format("woff2");
  font-style: italic;
  font-weight: 400;
  font-display: swap;
}

/* ---------------------------------------------------------------------
 * Bandeau de page
 *
 * Réalisations n'a pas d'écran d'ouverture : elle commence directement en
 * header compact. Le bandeau est donc statique, dans le flux, et défile
 * avec la page.
 *
 * ATTENTION — depuis que « data-site-header » est posé sur ce bandeau pour
 * régler le seuil du header au survol, « script.js » y écrit « --p: 1 » en
 * style en ligne et lui ajoute « est-compact ». Ces deux marques sont
 * exactes — cette page est en permanence dans l'état compact — mais elles
 * ne sont plus inertes comme avant : tout ce que le tronc fait dépendre de
 * « --p » s'applique désormais ici. Un seul sélecteur est concerné, la
 * taille du logo, neutralisée juste en dessous. Les trois autres emplois de
 * « --p » dans le tronc sont portés par « .site-header » ou
 * « .hero-content », qui n'existent pas sur cette page ; « est-compact »
 * n'y intervient que combiné à « .site-header ». Vérifié le 27 août.
 *
 * [TRONC] à la fusion : ce bandeau servira à toutes les pages sans
 * ouverture (Contact, Mentions légales, Politique de confidentialité).
 * ------------------------------------------------------------------- */

.rea-bandeau__blanc {
  height: 110px;
  display: grid;
  place-items: center;
  background: var(--color-white);
}

/*
 * Logo relevé sur la maquette : 273 x 61, soit le SVG 600 x 133 réduit.
 *
 * La taille est écrite, pas obtenue par réduction. Le tronc exprime la
 * même cote autrement — « width: min(440px, …) » ramené à 0,62 par
 * « transform », ce qui donne bien 273 — parce que là-bas c'est une
 * métamorphose en cours ; ici il n'y a pas de course, seulement une
 * arrivée. La transformation est donc annulée : sans cela le facteur
 * s'appliquerait une seconde fois, sur une largeur déjà réduite, et le
 * logo tomberait à 169 px.
 */
.rea-bandeau__blanc .brand-link {
  display: block;
  width: 273px;
  margin-inline: auto;
  transform: none;
}

.rea-bandeau__blanc .brand-logo {
  width: 273px;
  height: auto;
  display: block;
}

/*
 * « .compact-nav » du tronc est en position absolue, invisible, et son
 * opacité dépend de « --p ». Ici la barre est un objet ordinaire : on
 * neutralise ces trois états. On ne touche pas au tronc, on le recouvre.
 */
.rea-bandeau__nav {
  position: static;
  height: 56px;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* La page courante du menu a été promue au tronc commun le 27 août :
 * « .compact-nav__current » dans styles.css. Le menu est le même partout. */

/* ---------------------------------------------------------------------
 * Gabarit de la page
 * ------------------------------------------------------------------- */

/*
 * Le présentoir fait 994 px, et il donne sa largeur à toute la page.
 * En dessous de 1200 px il se réduit au lieu de pousser un défilement
 * horizontal — la plage 900 → 1200 px reste sans arbitrage sur tout le
 * site, elle est portée à la revue Go / No Go.
 */
.rea-shell {
  width: min(calc(100% - 2 * var(--gutter)), 994px);
  margin-inline: auto;
}


/* ---------------------------------------------------------------------
 * ⚠ PAS DE RÉSERVE BASSE EN BUREAU — DÉCISION DE FLORIAN DU 30 AOÛT 2026.
 *
 * Cette section portait « padding-bottom: 40px », la réserve basse du
 * gabarit. Elle est retirée EN BUREAU, et en bureau seulement.
 *
 * Pourquoi. Le pictogramme ZZ ne tombait pas au même endroit d'une page à
 * l'autre. MESURÉ à 1440 le 30 août : sur l'accueil, dont la maquette v4 est
 * la seule qui existe, le pictogramme fait 82 px de large et s'arrête à
 * 32 px du filet du pied de page — les 32 px étant la seule réserve haute du
 * pied de page lui-même. Sur Réalisations, il faisait 100 px et s'arrêtait
 * à 72 px : 40 px de réserve basse, puis les 32 px du pied de page.
 *
 * Florian a tranché sur image : « 82 et 32 sont les invariants du site ».
 * Les six fiches projets les respectent aussi.
 *
 * ⚠ LA RÉSERVE BASSE MOBILE, ELLE, NE BOUGE PAS. Le bloc sous 900 px garde
 * ses 32 px : la composition mobile de cette page a été jugée sur l'iPhone
 * de Florian et validée telle quelle. C'est pour cela que la valeur mobile
 * est écrite ici sans valeur bureau au-dessus d'elle — ce n'est pas un
 * oubli.
 * ------------------------------------------------------------------- */
.rea {
  position: relative;
  padding-top: 56px;
}

/* ---------------------------------------------------------------------
 * Titre, chapô, corps
 *
 * Trois largeurs décroissantes : 994 pour le présentoir, 868 pour le
 * chapô, 617 pour le corps. La dernière n'est pas un caprice : à 994 px
 * une ligne de texte à 18 px compte environ 120 signes, soit le double du
 * confort de lecture. À 617 elle en compte 78.
 * ------------------------------------------------------------------- */

.rea-titre {
  max-width: 868px;
  margin: 0;
  color: var(--color-anthracite);
  font-size: 27px;
  font-weight: var(--weight-semibold);
  line-height: 34px;
}

.rea-chapo {
  max-width: 868px;
  margin: 5px 0 0;
  color: var(--color-orange-mid);   /* 3,84:1 sur blanc — au-dessus du seuil du grand texte */
  font-family: var(--font-display);
  font-size: 42px;
  font-weight: var(--weight-bold);
  line-height: 46px;
}

.rea-corps {
  max-width: 617px;
  margin-top: 17px;
}

.rea-corps p {
  margin: 0;
  font-size: 18px;
  line-height: 26px;
}

.rea-corps p + p {
  margin-top: 15px;
}

/* ---------------------------------------------------------------------
 * Les deux commandes
 *
 * Hiérarchie : le filtre est la commande principale, il porte l'orange
 * foncé. La densité est un confort, elle porte le gris bleuté. L'accent
 * va à ce qui décide du contenu, pas à ce qui décide de la taille.
 * ------------------------------------------------------------------- */

.rea-densite {
  margin-top: 26px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
}

.rea-densite__label {
  color: var(--color-blue-gray);    /* 4,99:1 sur blanc */
  font-size: 16px;
  line-height: 30px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.rea-segment {
  display: flex;
  height: 30px;
  border: 1px solid var(--color-blue-gray);
  overflow: hidden;
}

.rea-segment__bouton {
  width: 36px;
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--color-blue-gray);
  background: var(--color-white);
  font-family: inherit;
  font-size: 16px;
  line-height: 28px;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.rea-segment__bouton + .rea-segment__bouton {
  border-left: 1px solid var(--color-blue-gray);
}

.rea-segment__bouton[aria-pressed="true"] {
  color: var(--color-white);
  background: var(--color-blue-gray);   /* 4,99:1 */
}

.rea-filtres {
  margin-top: 36px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px;
}

.rea-filtre {
  height: 30px;
  margin: 0;
  padding: 0 7px;
  border: 1px solid var(--color-blue-gray);
  color: var(--color-blue-gray);
  background: var(--color-white);
  font-family: inherit;
  font-size: 16px;
  font-weight: var(--weight-semibold);
  line-height: 26px;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

.rea-filtre__nb {
  margin-left: 5px;
  font-size: 13px;
  font-weight: var(--weight-regular);
}

.rea-filtre[aria-pressed="true"] {
  border-color: var(--color-orange-dark);
  color: var(--color-white);
  background: var(--color-orange-dark);   /* blanc sur #b04a00 : 5,49:1 */
}

/* Le survol ne doit pas laisser croire qu'un filtre inactif est actif. */
@media (hover: hover) {
  .rea-filtre:hover,
  .rea-segment__bouton:hover {
    border-color: var(--color-anthracite);
    color: var(--color-anthracite);
  }

  .rea-filtre[aria-pressed="true"]:hover,
  .rea-segment__bouton[aria-pressed="true"]:hover {
    color: var(--color-white);
  }

  .rea-filtre[aria-pressed="true"]:hover {
    border-color: var(--color-orange-dark);
  }
}

/* ---------------------------------------------------------------------
 * Le présentoir
 *
 * Les tailles de vignette ne sont pas écrites : le navigateur répartit
 * 994 px moins les écarts. À 4 colonnes il trouve 226 px exactement ; à 3
 * et à 5, les fractions tombent respectivement sur 310,67 et 174,8 — un
 * pixel de mieux que les valeurs entières de la maquette.
 *
 * Pas de seconde requête média : le nombre de colonnes est une variable,
 * pas une bascule. La cote structurante du site reste 900 px, et une seule.
 * ------------------------------------------------------------------- */

.rea-grille {
  margin-top: 47px;
  display: grid;
  grid-template-columns: repeat(var(--rea-colonnes, 4), minmax(0, 1fr));
  gap: 30px;
  align-items: start;
}

.rea-vignette {
  position: relative;   /* ancre la surface cliquable ci-dessous */
  margin: 0;
}

/*
 * Ouverture de la fenêtre.
 *
 * Le bouton ne porte que le titre — c'est lui qui donne son nom accessible
 * à la commande, et c'est le seul texte qui vaille pour l'annoncer. Sa
 * surface, elle, est étendue à toute la vignette par un pseudo-élément :
 * un seul arrêt au clavier, une cible confortable à la souris, et la
 * légende reste dans son « figcaption ».
 */
.rea-vignette__ouvrir {
  display: block;
  /*
   * Un bouton se dimensionne sur son contenu et déborde de sa cellule dès
   * que le titre est long et la colonne étroite — à 320 px et cinq
   * colonnes, « Innovative Water Care Europe | … » sortait de 22 px. Ces
   * trois déclarations le ramènent au comportement d'un paragraphe.
   */
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  color: inherit;
  background: none;
  font: inherit;
  text-align: left;
  white-space: normal;
  overflow-wrap: break-word;
  cursor: pointer;
}

/*
 * LE TITRE DEVENU LIEN — les six vignettes à fiche.
 *
 * « .rea-vignette__ouvrir » ramenait déjà un bouton au comportement d'un
 * paragraphe : couleur, police, fond, alignement, tout est neutralisé. Une
 * seule chose lui échappait, parce qu'un bouton ne l'a jamais : LE
 * SOULIGNEMENT que le navigateur donne à un lien. Sans cette règle, six
 * titres sur vingt-sept arriveraient soulignés.
 *
 * Le reste est repris tel quel, et c'est voulu : la couleur au survol, le
 * liseré au clavier, et la surface cliquable qui couvre TOUTE la vignette —
 * un visiteur clique la photo comme le titre, sur les vingt-sept.
 */
.rea-vignette__lien {
  text-decoration: none;
}

.rea-vignette__ouvrir::after {
  content: "";
  position: absolute;
  inset: 0;
}

/*
 * Le liseré de focus appartient à la vignette entière, pas aux deux lignes
 * de titre : sur une image de 226 px, un contour posé sur le seul texte ne
 * se voit pas. Le bouton rend donc le sien, et la figure le reprend.
 */
.rea-vignette__ouvrir:focus-visible {
  outline: none;
  box-shadow: none;
}

.rea-vignette:has(.rea-vignette__ouvrir:focus-visible) {
  outline: var(--focus-outer);
  outline-offset: 3px;
  box-shadow: var(--focus-inner);
}

/*
 * Retour au survol. Un changement de couleur du titre, et rien de plus :
 * un agrandissement de l'image serait une cinquième famille d'effet, alors
 * que la quatrième a déjà coûté un arbitrage explicite. La teinte employée
 * est celle des filtres actifs — 5,49:1 sur blanc.
 */
@media (hover: hover) {
  .rea-vignette:has(.rea-vignette__ouvrir:hover) .rea-vignette__titre {
    color: var(--color-orange-dark);
  }
}

.rea-vignette__titre {
  transition: color var(--transition-fast);
}

.rea-vignette__cadre {
  position: relative;
  aspect-ratio: 1;       /* la boîte est réservée avant le chargement : la grille ne saute pas */
  background: var(--color-off-white);
  overflow: hidden;
}

.rea-vignette__cadre img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/*
 * Le badge n'apparaît que lorsque la fiche existe. Tant qu'elle n'existe
 * pas, retirer la classe « rea-vignette--fiche » suffit : rien à annoncer,
 * rien à promettre.
 */
.rea-vignette__badge {
  position: absolute;
  bottom: 0;
  left: 0;
  margin: 0;
  padding: 4px 9px;
  color: var(--color-deep-black);    /* noir sur orange : 7,21:1 */
  background: var(--color-orange);
  font-size: 12px;
  font-weight: var(--weight-semibold);
  line-height: 16px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.rea-vignette figcaption {
  padding-top: 11px;
}

.rea-vignette__titre {
  margin: 0;
  color: var(--color-deep-black);
  font-size: 14px;
  font-weight: var(--weight-semibold);
  line-height: 20px;
}

.rea-vignette__descriptif {
  margin: 2px 0 0;
  color: var(--color-blue-gray);
  font-size: 14px;
  line-height: 20px;
}

/*
 * Filtrage. On emploie l'attribut « hidden », jamais « display: none » à
 * la main : la règle globale du tronc le rend inopérant à l'écran ET le
 * sort de l'ordre de tabulation, et l'intention reste lisible dans le
 * balisage.
 * Aucune animation de réagencement : ce serait une cinquième famille
 * d'effet, et la quatrième a déjà coûté un arbitrage explicite.
 */

/*
 * L'état vide retient la hauteur : sans plancher, la page raccourcit au
 * point que le footer remonterait dans le champ du bandeau.
 */
.rea-vide {
  margin: 60px 0 0;
  min-height: 226px;
  color: var(--color-blue-gray);
  font-size: 18px;
}

/* =====================================================================
 * La fenêtre de projet
 *
 * Cotes relevées sur la maquette : 585 de large, 535 pour l'image, 25 de
 * marge intérieure de chaque côté — 535 + 25 + 25 = 585, la largeur n'est
 * donc pas un réglage mais une conséquence. La hauteur, elle, est laissée
 * libre : mesuré sur les vingt-sept projets, le bloc de texte fait 109 px
 * dans le cas courant et 155 px au pire — cadre de réalisation sur deux
 * lignes plus ligne complémentaire — quand les 695 px de la maquette n'en
 * laissaient que 135. Fixer la hauteur aurait tronqué six fenêtres ; c'est
 * le seul écart pris avec la maquette, et il est délibéré.
 *
 * On emploie l'élément « dialog » natif. Il apporte la capture du clavier,
 * la touche Échap, l'inertie du reste de la page et le retour du focus sur
 * la vignette d'origine. Aucune bibliothèque n'entre dans le projet pour
 * refaire ce que le navigateur fait déjà.
 * ===================================================================== */

.rea-lb {
  width: min(585px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100vh - 32px);
  margin: auto;
  padding: 25px;
  border: 0;
  border-radius: 15px;
  color: var(--color-deep-black);
  background: var(--color-white);
  overflow: auto;
}

/*
 * Le fond. Flou de 4 px et perte de 6 % de luminosité : la page reste
 * reconnaissable derrière — on n'a pas changé d'endroit — mais elle cesse
 * de disputer l'attention à la fenêtre. Le voile sombre par-dessus n'est
 * pas décoratif : c'est lui qui garantit le contraste des trois commandes
 * blanches lorsque la première vue d'un projet est une photo claire.
 */
.rea-lb::backdrop {
  background: rgba(21, 21, 21, 0.35);
  backdrop-filter: blur(4px) brightness(0.94);
  -webkit-backdrop-filter: blur(4px) brightness(0.94);
}

/* ---------------------------------------------------------------------
 * Le carrousel
 * ------------------------------------------------------------------- */

.rea-lb__scene {
  position: relative;
  aspect-ratio: 1;          /* la boîte est réservée avant le chargement */
  background: var(--color-off-white);
  border-radius: 3px;
  overflow: hidden;
}

.rea-lb__piste {
  display: flex;
  height: 100%;
  transition: transform 320ms ease;
}

.rea-lb__piste > * {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  object-fit: contain;      /* jamais de recadrage : on montre le travail entier */
  display: block;
}

/*
 * Les trois commandes. Blanches, avec une ombre portée sombre : c'est la
 * paire qui tient, et elle tient aussi bien sur une photo claire que sur
 * une photo sombre. Les fichiers livrés sont en noir profond, conformément
 * à la convention du site — un pictogramme, une couleur — et c'est la
 * feuille qui les recolore, par « currentColor ».
 */
.rea-lb__nav,
.rea-lb__fermer {
  position: absolute;
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--color-white);
  background: none;
  /*
   * Deux ombres et non une : la première, serrée, dessine le contour même
   * quand le fond est un blanc pur — le cas des planches de logotypes ; la
   * seconde, plus large, assoit le dessin sur les photos claires. Vérifié
   * sur les trois cas extrêmes du fonds : logotype sur blanc, couverture
   * noire, contenants sur fond blanc.
   */
  filter: drop-shadow(0 0 1px rgba(21, 21, 21, 0.9))
          drop-shadow(0 1px 4px rgba(21, 21, 21, 0.6));
  cursor: pointer;
}

.rea-lb__nav {
  top: 50%;
  width: 44px;              /* cible tactile, quelle que soit la taille du dessin */
  height: 60px;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
}

.rea-lb__nav--prec { left: 4px; }
.rea-lb__nav--suiv { right: 4px; }
.rea-lb__nav--suiv svg { transform: scaleX(-1); }

.rea-lb__fermer {
  top: 10px;
  right: 10px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
}

/*
 * Rang de la vue. Il n'est pas décoratif : sans lui, on ne sait pas si le
 * carrousel a une fin. Masqué au lecteur d'écran, qui reçoit la même
 * information par la région « status » — l'écrire deux fois la ferait dire
 * deux fois.
 */
.rea-lb__rang {
  position: absolute;
  right: 12px;
  bottom: 10px;
  margin: 0;
  padding: 2px 8px;
  color: var(--color-white);
  background: rgba(21, 21, 21, 0.55);
  border-radius: 11px;
  font-size: 12px;
  font-weight: var(--weight-semibold);
  line-height: 18px;
  font-variant-numeric: tabular-nums;
}

/* Une seule vue : ni chevrons, ni compteur. Il n'y a rien à parcourir. */
.rea-lb[data-vues="1"] .rea-lb__nav,
.rea-lb[data-vues="1"] .rea-lb__rang {
  display: none;
}

/* ---------------------------------------------------------------------
 * Le bloc de texte
 *
 * Quatre niveaux, du plus au moins engageant : le titre, ce que c'est,
 * puis dans quelles conditions ce fut fait. Les deux dernières lignes
 * partagent exactement le même traitement, parce qu'elles disent la même
 * sorte de chose — qui a fait quoi — et qu'en distinguer une reviendrait à
 * hiérarchiser deux aveux.
 * ------------------------------------------------------------------- */

.rea-lb__texte {
  padding-top: 20px;
}

.rea-lb__titre {
  margin: 0;
  color: var(--color-deep-black);   /* 18,26:1 sur blanc */
  font-size: 14px;
  font-weight: var(--weight-semibold);
  line-height: 20px;
}

.rea-lb__descriptif {
  margin: 2px 0 0;
  color: var(--color-blue-gray);    /* 4,99:1 */
  font-size: 14px;
  line-height: 20px;
}

.rea-lb__cadre-realisation {
  margin-top: 12px;
}

.rea-lb__cadre-realisation p {
  margin: 0;
  color: var(--color-blue-gray);
}

/*
 * Le contexte de réalisation est la SEULE ligne en italique de la fenêtre.
 * Même corps que le titre et le descriptif : ce qu'elle dit n'est pas d'un
 * rang inférieur, c'est d'une autre nature. Seule l'inclinaison le signale.
 */
.rea-lb__realisation {
  font-size: 14px;
  font-style: italic;
  line-height: 20px;
}

/*
 * La ligne complémentaire, elle, est une précision sur la précision : elle
 * descend d'un corps et revient au romain. Deux italiques l'une sous
 * l'autre auraient fait perdre à la première ce qu'elle signale.
 */
.rea-lb__complement {
  margin-top: 6px;
  font-size: 12px;
  font-style: normal;
  line-height: 17px;
}

/* ---------------------------------------------------------------------
 * Pictogramme de fin
 * ------------------------------------------------------------------- */

.rea-mark {
  margin: 56px auto 0;
  display: block;
  width: 82px;   /* 82 et non 100 : voir la note du 30 août ci-dessus */
}

.rea-mark img {
  width: 100%;
  height: auto;
  display: block;
}

/* =====================================================================
 * COMPOSITION MOBILE — sous 900 px
 *
 * La cote de bascule est celle du site, 900 px, et il n'y en a pas d'autre :
 * la même en CSS que dans « estMobile() ». Le nombre de colonnes de la
 * grille est une variable, pas une seconde bascule.
 *
 * Cette page n'a pas de maquette mobile — vérifié sur tout le OneDrive le
 * 27 août. Les cotes de chassis sont donc TRANSPOSÉES de la maquette v3 de
 * Présentation (bandeau 76, logo 160, marges 20, colonne plafonnée à 560),
 * et les corps de texte des sept passes mobiles de cette page-là. Chaque
 * transposition dit sur quoi elle s'appuie, là où elle est écrite.
 *
 * Passes 1 à 7 — socle et bandeau, texte, commandes, présentoir, fenêtre,
 * glissement au doigt, fin de page. 27 août 2026.
 * ===================================================================== */

/* Le burger non habillé au-dessus de 900 px a été PROMU au tronc commun le
 * 27 août au soir : le défaut existait aussi sur Présentation, mesuré. La règle
 * est désormais dans styles.css, elle corrige les deux pages. */

@media (max-width: 899px) {

  /*
   * Largeur du présentoir en composition mobile. Déclarée ici et non dans le
   * tronc : c'est une cote de cette page, comme le 994 du desktop.
   */
  :root {
    --rea-presentoir: min(calc(100vw - 2 * var(--mob-marge)), 1000px);
  }

  /* ..................................................................
   * Le gabarit
   *
   * La page reprend la colonne du site — « --mob-colonne », déclarée par le
   * tronc dans le même bloc mobile : min(100% - 40px, 560px). Le présentoir
   * de 994 px n'a plus de sens ici, et une largeur propre à cette page en
   * aurait encore moins : c'est la même colonne que sur Présentation, ou
   * ce sont deux marges différentes sur deux pages du même site.
   * .................................................................. */

  .rea-shell {
    width: var(--mob-colonne);
  }

  /*
   * Réserve haute. En desktop la page respire 56 px sous un bandeau de
   * 166 px ; en mobile le bandeau tombe à 76 et la réserve se resserre avec
   * lui. 36 px posent la première encre à 116 px du haut de la page.
   */
  .rea {
    padding-top: 36px;
    padding-bottom: 32px;   /* la réserve basse se resserre avec le reste */
  }

  /* ..................................................................
   * Le bandeau de page
   *
   * CORRECTION DU 27 AOÛT, demandée par Florian : le header mobile est le
   * MÊME sur tout le site. Le bandeau de cette page ne doit donc pas être un
   * dessin à lui — il doit être, au pixel, le bandeau compact de Présentation :
   * barre blanche de 76 px, logo de 160 px calé à gauche à 20 px du bord, et
   * le burger à droite.
   *
   * Les cotes ci-dessous reproduisent EXACTEMENT celles que le tronc donne à
   * « .panneau-header__blanc » et « .panneau-header__marque » sous 900 px —
   * y compris les 5 px de descente du logo, qui n'est pas centré sur la
   * hauteur de la barre. Conséquence voulue : quand le header fixe du site
   * descend, il se pose sur ce bandeau sans rien déplacer d'un pixel.
   *
   * Le bandeau ne porte pas de burger : il n'y a qu'un « [data-burger] » dans
   * le site, et c'est celui du header fixe. Ce bandeau-ci reste donc la
   * version sans JavaScript du header — le logo, l'ancre du haut de page, et
   * la réserve de 76 px — sur laquelle le vrai header vient se poser.
   * .................................................................. */

  .rea-bandeau__blanc {
    height: var(--mob-bandeau);        /* 76 px */
    display: flex;                     /* reprise explicite du « grid » desktop */
    align-items: center;
    justify-content: flex-start;       /* reprise explicite de « place-items: center » */
    padding-inline: var(--mob-marge);  /* 20 px */
  }

  .rea-bandeau__blanc .brand-link {
    width: var(--mob-logo-compact);    /* 160 px */
    margin-inline: 0;                  /* reprise explicite du « auto » desktop */
    margin-top: 5px;                   /* le logo n'est pas centré : il descend */
  }

  .rea-bandeau__blanc .brand-logo {
    width: var(--mob-logo-compact);
  }

  /*
   * Avec JavaScript, le header fixe du site est posé dès le premier pixel,
   * exactement sur ce bandeau. Le laisser peint dessous ne montrerait rien de
   * plus, mais laisserait une seconde cible clavier invisible sous la
   * première — ce que le projet interdit. « visibility » et non « display » :
   * la boîte de 76 px reste, donc la réserve sous le header fixe reste, et
   * « #haut-de-page » reste une cible d'ancre positionnable.
   *
   * Le sélecteur est préfixé « .js » : sans JavaScript, le header fixe
   * n'existe pas et c'est ce bandeau-ci qui porte le logo. Rien n'est perdu.
   */
  .js .rea-bandeau__blanc {
    visibility: hidden;
  }

  /*
   * Reprise EXPLICITE, non complétée : la navigation du bandeau était déjà
   * masquée par la sécurité du 27 août, et elle le reste. À trois entrées
   * elle dépasse 320 px de large, et le projet interdit tout défilement
   * horizontal de 320 à 1920 px.
   */
  .rea-bandeau__nav {
    display: none;
  }

  /* ..................................................................
   * Titre, chapô, corps
   *
   * TRANSPOSITION. Les trois cotes viennent des passes mobiles de
   * Présentation, pas d'une maquette de cette page-ci :
   *
   * — le titre prend 22,5 / 29, la cote du « h1 » de l'écran d'ouverture
   *   (passe 1) ;
   * — le chapô prend 33,5 / 38, la cote des grands titres mobiles de 02-4
   *   et 02-5 (passes 5 et 6). Il est en Barlow gras comme en desktop : ce
   *   qui change est le corps, pas la voix ;
   * — le corps prend 17 / 26, le corps de texte de TOUTE la page mobile de
   *   Présentation — 02-1, le pavé de 02-2, 02-3, 02-4, 02-5. Une page du
   *   même site ne lit pas dans deux corps différents.
   *
   * Le rapport titre / chapô est conservé : 27 → 42 en desktop (x 1,56),
   * 22,5 → 33,5 en mobile (x 1,49).
   * .................................................................. */

  .rea-titre {
    max-width: none;
    font-size: 22.5px;
    line-height: 29px;
  }

  .rea-chapo {
    max-width: none;
    margin-top: 6px;
    font-size: 33.5px;
    line-height: 38px;
  }

  .rea-corps {
    max-width: none;
    margin-top: 20px;
  }

  .rea-corps p {
    font-size: 17px;
    line-height: 26px;
  }

  /*
   * Écart entre paragraphes : 15 px, la même valeur qu'en desktop et qu'en
   * mobile sur 02-1 et 02-5. Redit explicitement, non hérité.
   */
  .rea-corps p + p {
    margin-top: 15px;
  }

  /* ..................................................................
   * Les deux commandes
   *
   * LE RÉGLAGE DE DENSITÉ DISPARAÎT. À 390 px de large, ses trois valeurs
   * donnent des vignettes de 110, 78 et 60 px : aucune ne compose quoi que
   * ce soit, et la plus large est déjà moins bonne que les deux colonnes
   * posées plus bas. Une commande qui n'a que de mauvaises réponses n'a pas
   * à être offerte.
   *
   * « display: none » et non « hidden » : c'est le modèle du site pour une
   * commande qui n'existe qu'à une seule largeur — les pastilles de
   * carrousel, absentes en desktop. Il sort aussi de l'ordre de tabulation,
   * ce qui est exactement ce qu'on veut : rien d'invisible ne doit rester
   * atteignable au clavier.
   *
   * Le nombre de colonnes reste écrit dans la grille, ci-dessous : la
   * variable posée en ligne par le script ne commande plus rien ici.
   * .................................................................. */

  .rea-densite {
    display: none;
  }

  /*
   * Les sept filtres. Rien n'est caché, rien ne défile : un filtre hors
   * champ est un filtre mort, et c'est par eux qu'on découvre ce que
   * contient la page. Ils s'enroulent donc sur trois lignes.
   *
   * Reprise EXPLICITE du desktop, non complétée : « space-between » y
   * répartit sept boutons sur une seule ligne de 994 px. Enroulés, il
   * creuse des trous au bout de chaque ligne et fait flotter les boutons.
   * On repasse au calage à gauche.
   */
  .rea-filtres {
    margin-top: 26px;
    justify-content: flex-start;
    column-gap: 8px;
    row-gap: 14px;
  }

  .rea-filtre {
    position: relative;
    padding: 0 8px;
    font-size: 15px;
  }

  /*
   * Zone tactile. Le dessin garde ses 30 px de haut — c'est la cote du
   * site —, et un pseudo-élément porte la cible à 44. C'est exactement le
   * procédé employé sur les boutons de 02-6, qui font 37 px dessinés pour
   * 44 px cliquables : on n'invente pas un second procédé.
   *
   * L'écart entre deux lignes vaut 14 px, soit 30 + 14 = 44 : deux cibles
   * successives se touchent sans jamais se chevaucher.
   */
  .rea-filtre::after {
    content: "";
    position: absolute;
    inset: -7px 0;
  }

  /* ..................................................................
   * Le présentoir
   *
   * DEUX COLONNES, écrites et non calculées. « auto-fill » aurait été
   * séduisant, mais il donne une colonne unique à 320 px de large et trois
   * colonnes de 133 px à 480 : le nombre de colonnes se serait mis à
   * dépendre de la largeur alors que la décision, elle, est prise. Deux
   * colonnes de 320 à 899 px, et la vignette suit.
   *
   * Cotes obtenues : 165 px de côté à 390 px de large, 130 à 320, 270 au
   * plafond de la colonne. La légende, elle, ne change pas de corps — la
   * fenêtre de projet reprend la légende de la vignette au même corps, et
   * casser cette symétrie ferait mentir la fenêtre.
   *
   * L'écart vertical est plus large que l'horizontal : entre deux rangées
   * il ne sépare pas deux images mais une légende de l'image suivante.
   * .................................................................. */

  .rea-grille {
    margin-top: 32px;
    /*
     * Le présentoir sort de la colonne de texte, exactement comme en desktop
     * où il fait 994 px quand le chapô en fait 868 et le corps 617. Sur un
     * téléphone les deux se confondent — la fenêtre est plus étroite que la
     * colonne plafonnée — et l'écart n'apparaît qu'à partir de la tablette,
     * là où il sert.
     *
     * Le motif est celui des bandes de carrousel du tronc : une largeur en
     * unités de fenêtre, puis un retrait négatif pour recentrer. En unités de
     * fenêtre et non en pourcentage — un pourcentage se résoudrait contre la
     * colonne de texte, donc rétrécirait le présentoir au lieu de l'élargir.
     */
    width: var(--rea-presentoir);
    margin-inline: calc(50% - var(--rea-presentoir) / 2);
    /*
     * DEUX COLONNES SUR TÉLÉPHONE, TROIS SUR TABLETTE — et le nombre n'est
     * écrit nulle part : il découle de la largeur. Aucune seconde cote de
     * bascule n'est inventée, la cote du site reste 900 px et reste unique.
     *
     * La vignette ne descend jamais sous 40 % de la fenêtre, et ne dépasse
     * jamais 200 px de plancher : le premier chiffre garde deux colonnes
     * jusqu'en bas (130 px de vignette à 320 px de large), le second fait
     * apparaître la troisième vers 680 px. Mesuré : 2 colonnes de 320 à
     * ~660 px, 3 au-delà, et 229 px de vignette sur iPad en portrait —
     * exactement la cote du desktop à quatre colonnes.
     */
    grid-template-columns: repeat(auto-fill, minmax(min(40vw, 200px), 1fr));
    column-gap: 20px;
    row-gap: 34px;
  }

  .rea-vignette figcaption {
    padding-top: 9px;
  }

  /*
   * L'état vide retient toujours la hauteur, à la cote de la vignette
   * mobile et non plus à celle de la vignette desktop : sans plancher, la
   * page raccourcirait au point que le footer remonterait sous le bandeau.
   */
  .rea-vide {
    margin-top: 40px;
    min-height: 165px;
    font-size: 17px;
  }

  /* ..................................................................
   * Le pictogramme de fin
   *
   * TRANSPOSITION : 83 px de large, la cote du pictogramme ZZ mobile de
   * 02-6 (passe 7 de Présentation), contre 100 en desktop. C'est le même
   * dessin au même endroit du parcours — la fin de la page —, il prend
   * donc la même taille que là-bas.
   * .................................................................. */

  .rea-mark {
    margin-top: 48px;
    width: 83px;
  }

  /* ..................................................................
   * La fenêtre de projet
   *
   * Elle fonctionnait déjà à toutes les largeurs : ce qui suit ne la répare
   * pas, il la compose. Les trois règles posées le 27 août — marges de 16,
   * arrondi de 12, titre agrandi — étaient une sécurité prise avant toute
   * passe mobile, et le CSS le disait. Les deux premières sont REPRISES
   * telles quelles ; la troisième est remplacée par le bloc de texte
   * ci-dessous, qui la refait pour de bon.
   * .................................................................. */

  /*
   * La hauteur se borne en « svh » et non en « vh ». Sur iOS, « vh » est la
   * hauteur de la fenêtre barres RÉTRACTÉES : une fenêtre haute y dépasse
   * alors sous la barre d'adresse, et c'est justement quand elle est haute
   * qu'on ne peut pas se le permettre. « svh » est la plus petite hauteur
   * visible — barres déployées. La fenêtre ne dépasse donc jamais, au prix
   * d'un peu de marge quand les barres se rétractent.
   */
  .rea-lb {
    width: min(585px, calc(100vw - 32px));
    max-height: calc(100svh - 32px);
    padding: 16px;
    border-radius: 12px;
  }

  /*
   * Le carré de l'image cesse d'être un carré quand la hauteur manque — en
   * paysage, où la fenêtre n'a plus que 390 px de haut. Il se plafonne alors
   * à 52 % de la hauteur visible — et il RESTE un carré : c'est la largeur
   * qui suit la hauteur, par « aspect-ratio », au lieu de s'étaler en
   * rectangle off-white autour d'une image devenue petite. En portrait
   * l'inverse s'applique et la borne ne mord sur rien. Aucune requête média
   * nouvelle, aucune seconde cote de bascule.
   */
  .rea-lb__scene {
    max-width: 52svh;    /* c'est la LARGEUR qu'on borne : « aspect-ratio: 1 » fait le reste */
    max-height: 52svh;
    margin-inline: auto;
  }

  /*
   * Les trois commandes passent toutes à 44 px de côté au moins — la cible
   * du doigt, la même que celle des filtres et de la flèche de remontée. Le
   * dessin, lui, ne bouge pas : c'est la boîte qui grandit autour.
   * Les chevrons se collent aux bords : sur 326 px de large, chaque pixel
   * repris au centre est un pixel rendu à l'image.
   */
  .rea-lb__fermer {
    top: 6px;
    right: 6px;
    width: 44px;
    height: 44px;
  }

  .rea-lb__nav--prec { left: 0; }
  .rea-lb__nav--suiv { right: 0; }

  /* ..................................................................
   * Le geste : la piste défile au doigt
   *
   * Au doigt, on s'attend à faire glisser. Ce n'est PAS une famille d'effet
   * nouvelle : le glissement de carrousel est la deuxième famille du site,
   * admise le 24 août, et c'est déjà ce que font les deux carrousels de
   * Présentation — avec le même mécanisme, celui du navigateur. Le projet
   * s'interdit une cinquième famille ; il ne s'interdit pas d'employer la
   * deuxième une troisième fois.
   *
   * Rien n'est réécrit à la main : « scroll-snap » cale, le doigt déplace,
   * et le script se contente de lire où la piste s'est arrêtée. Les chevrons
   * restent — ils disent qu'il y a une suite, et ils servent à la souris
   * comme au clavier.
   *
   * En desktop, la piste garde son « transform » : la composition validée le
   * 27 août n'est pas touchée.
   * .................................................................. */

  .rea-lb__piste {
    overflow-x: auto;
    overscroll-behavior-x: contain;   /* le glissement ne déborde pas sur la page */
    scroll-snap-type: x mandatory;
    /*
     * La barre de défilement se retire : sur un carrousel de deux à huit
     * vues, le compteur et les chevrons disent déjà où l'on en est, et une
     * barre viendrait mordre le bas de l'image.
     */
    scrollbar-width: none;
    transition: none;                 /* le déplacement n'est plus une transition */
  }

  .rea-lb__piste::-webkit-scrollbar {
    display: none;
  }

  .rea-lb__piste > * {
    scroll-snap-align: start;
  }

  /* ..................................................................
   * Le bloc de texte de la fenêtre
   *
   * Il monte d'un cran, et il monte EN BLOC : le desktop pose titre,
   * descriptif et contexte au même corps — seules la graisse, la couleur et
   * l'inclinaison les séparent —, et la ligne complémentaire deux points en
   * dessous. Ce rapport est ce qui fait tenir la page ; le mobile le
   * transpose au lieu de le défaire.
   *
   * 14 / 14 / 14 / 12 en desktop devient 16 / 16 / 16 / 14. La vignette,
   * elle, garde son corps 14 : à 165 px de large elle n'est plus à la même
   * échelle que la fenêtre, et la symétrie qui vaut à 226 px de vignette
   * pour 535 px de fenêtre ne vaut plus ici.
   * .................................................................. */

  .rea-lb__texte {
    padding-top: 16px;
  }

  .rea-lb__titre {
    font-size: 16px;
    line-height: 22px;
  }

  .rea-lb__descriptif {
    font-size: 16px;
    line-height: 22px;
  }

  .rea-lb__realisation {
    font-size: 16px;
    line-height: 22px;
  }

  .rea-lb__complement {
    font-size: 14px;
    line-height: 19px;
  }

}

/* ---------------------------------------------------------------------
 * Mouvement réduit
 *
 * Le tronc commun ramène déjà toute transition à 0,01 ms avec « important ».
 * La règle du projet veut que chaque animation nouvelle REDISE sa relève
 * plutôt que de compter dessus : si le bloc du tronc changeait, le glissement
 * du carrousel ne repartirait pas tout seul. Les vues se substituent alors
 * l'une à l'autre sans course, ce qui reste parfaitement lisible — le rang
 * affiché et la région « status » disent de toute façon où l'on en est.
 *
 * Les vidéos, elles, ne se lancent pas d'elles-mêmes sous ce réglage : c'est
 * « realisations.js » qui pose alors les commandes de lecture, parce qu'un
 * mouvement de six secondes en boucle est exactement ce que la préférence
 * demande d'éviter.
 * ------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .rea-lb__piste {
    transition: none !important;
    /*
     * Redit pour le mécanisme mobile aussi : le glissement programmé par les
     * chevrons demande « behavior: auto » dans le script, et le CSS le redit
     * ici plutôt que de compter sur le bloc du tronc. Les vues se substituent
     * alors l'une à l'autre sans course — le rang affiché et la région
     * « status » disent de toute façon où l'on en est.
     */
    scroll-behavior: auto !important;
  }

  .rea-vignette__titre {
    transition: none !important;
  }
}
