/**
 * Ekdotis — page d'accueil, § 12.
 *
 * Le vocabulaire de blocs du § 12.2 et les trois compositions. Chargé sur la
 * seule page qui s'en sert, et avant la feuille de l'enfant, qui doit pouvoir
 * le surcharger.
 *
 * AUCUNE VALEUR EN DUR : tout vient du :root de main.css. Ce fichier ne
 * déclare aucune propriété personnalisée — il n'y a qu'un seul vocabulaire, et
 * il est ailleurs.
 *
 * AUCUNE REQUÊTE MÉDIA DE MISE EN PAGE. Toutes les grilles sont en auto-fill :
 * le nombre de colonnes se calcule à partir d'une piste minimale, il ne se
 * déclare pas. Deux colonnes à 390 px, six à 1280 px, sans qu'aucun palier ne
 * soit écrit. La maquette employait repeat(4, 1fr) et repeat(3, 1fr) — comptes
 * fixes, illisibles sous 700 px.
 */

/* -------------------------------------------------------------------------
 * Conteneur de flux — § 12.2, § 2.5
 * ---------------------------------------------------------------------- */

/*
 * IL PORTE L'ESPACEMENT VERTICAL, ET LUI SEUL. Aucun bloc ne pose de marge
 * au-dessus ni en dessous de lui-même : un bloc absent ne laisse donc aucune
 * marge résiduelle, et la règle du § 2.5 ne coûte rien à écrire.
 *
 * DEUX COLONNES AU PLUS, et c'est le max() qui le garantit. Une piste minimale
 * de 20 rem laisserait auto-fill en composer trois dans un conteneur de
 * 1280 px, et deux blocs en demie ne feraient plus une rangée. En bornant la
 * piste à la moitié du conteneur, on obtient deux colonnes tant qu'elles
 * tiennent, une seule en dessous — sans requête média.
 */
.accueil-flux {
	align-items: start;
	display: grid;
	gap: var(--block-gap);
	/* La piste ne dépasse jamais le conteneur (2 novembre 2026, W7 bis) :
	   à 320 px, le flux n'a que 288 px et la piste minimale de 20 rem en
	   imposait 320 — les sections débordaient de 32 px sur tous les sites. */
	grid-template-columns: repeat(auto-fill, minmax(min(100%, max(var(--half-col-min), (100% - var(--block-gap)) / 2)), 1fr));
	margin-inline: auto;
	max-width: var(--content-width);
	/* L'écart de bloc ouvre le flux et sépare les blocs ; il ne le ferme pas
	   (13 octobre) : le pied porte sa propre marge, et les deux cumulés
	   laissaient 168 px de vide sous la dernière section. */
	padding-block: var(--block-gap) 0;
	padding-inline: var(--gutter);
}

/*
 * Un bloc pleine largeur traverse la rangée ; un bloc en demie occupe une
 * colonne. Deux demies consécutives se rangent côte à côte d'elles-mêmes.
 *
 * UNE DEMIE SEULE RESTE DANS SA DEMI-LARGEUR et laisse l'autre moitié vide.
 * C'est voulu : aucune redistribution, la mise en page d'un bloc ne dépend
 * jamais de la présence d'un autre. Un état dégradé est temporaire, et une page
 * qui se réorganise toute seule change de forme sans prévenir.
 */
.bloc--pleine {
	grid-column: 1 / -1;
}

.bloc {
	display: flex;
	flex-direction: column;
	gap: var(--space-m);
	min-width: 0;
}

/*
 * LA BANDE DES NOUVEAUTÉS (13 octobre) — même technique que le bandeau de la
 * fiche livre (§ 2.46) : la section garde sa boîte et sa place dans le flux ;
 * un pseudo-élément absolu de sa hauteur étale son ombre sur 100vmax de chaque
 * côté et se coupe à sa propre hauteur, donc aucun défilement horizontal. Le
 * contexte d'empilement (`z-index: 0`) passe le pseudo-élément sous le contenu
 * sans créer de contexte de formatage de bloc. Le retrait est le remplissage
 * vertical de la section dans la bande ; transparent et nul au parent, la
 * section ne change pas d'un pixel.
 */
.bloc--nouveautes {
	padding-block: var(--accueil-nouveautes-retrait);
	position: relative;
	z-index: 0;
}

.bloc--nouveautes::before {
	background: var(--accueil-nouveautes-fond);
	box-shadow: 0 0 0 100vmax var(--accueil-nouveautes-fond);
	clip-path: inset(0 -100vmax);
	content: "";
	inset: 0;
	position: absolute;
	z-index: -1;
}

/* -------------------------------------------------------------------------
 * Intitulé de bloc
 * ---------------------------------------------------------------------- */

/*
 * Le contrat --section-title-* entier, et non le seul corps : il est écrit pour
 * les titres de section du § 17 et porte le motif de son réglage.
 */
.bloc__intitule {
	font-family: var(--section-title-family);
	font-size: var(--section-title-size);
	font-weight: var(--section-title-weight);
	letter-spacing: var(--section-title-spacing);
	line-height: var(--leading-snug);
	margin: 0;
	text-transform: var(--section-title-transform);
}

.bloc__debordement {
	font-family: var(--font-ui);
	font-size: var(--font-size-xs);
	margin: 0;
}

/* -------------------------------------------------------------------------
 * Grilles et pistes — § 12.2
 * ---------------------------------------------------------------------- */

.bloc-grille {
	display: grid;
	gap: var(--space-m);
}

.bloc-grille--couvertures {
	grid-template-columns: repeat(auto-fill, var(--cover-col));
}

/*
 * SOUS 48 REM, DEUX COUVERTURES PAR RANGÉE AU MOINS (13 octobre). À 375 px la
 * grille fait 320 px ; deux pistes de 9,5 rem et leur écart de 1,5 rem en
 * demandaient 328, et chaque couverture prenait la rangée entière — six
 * couvertures de 320 × 461 px, une page de 4 000 px. L'écart de colonne passe
 * à --space-s et la piste minimale ne dépasse jamais la moitié de la grille :
 * deux colonnes dès 320 px, trois dès qu'elles tiennent. Au-dessus, rien ne
 * change.
 */
@media (max-width: 47.99rem) {
	.bloc-grille--couvertures {
		column-gap: var(--space-s);
		grid-template-columns: repeat(auto-fill, minmax(min(var(--cover-col-min), calc(50% - var(--space-s) / 2)), 1fr));
	}
}

.bloc-grille--catalogue {
	grid-template-columns: repeat(auto-fill, var(--catalogue-col));
}

.bloc-grille--compacte {
	gap: var(--space-s);
	grid-template-columns: repeat(auto-fill, var(--compact-col));
}

.bloc-grille--actualites {
	grid-template-columns: repeat(auto-fill, var(--news-col));
}

.bloc-grille--grande {
	gap: var(--space-l);
	grid-template-columns: repeat(auto-fill, var(--half-col));
}

/*
 * Défilement horizontal — § 12.3. CSS pur : rien ne bouge tout seul, le
 * visiteur pilote. La piste est focalisable et se parcourt aux flèches,
 * comportement natif d'une zone qui déborde.
 */
.bloc-piste {
	display: grid;
	gap: var(--space-m);
	grid-auto-columns: var(--cover-col-min);
	grid-auto-flow: column;
	overflow-x: auto;
	padding-bottom: var(--space-2xs);
	scroll-snap-type: x mandatory;
}

.bloc-piste > * {
	scroll-snap-align: start;
}

.bloc-liste {
	display: flex;
	flex-direction: column;
}

.bloc-citations {
	display: flex;
	flex-direction: column;
	gap: var(--space-m);
}

/* -------------------------------------------------------------------------
 * Bandeau — § 12.3
 * ---------------------------------------------------------------------- */

/*
 * L'entrée occupe 88 % de la largeur, et le débord partiel de la suivante est
 * la seule affordance. Aucune puce, aucune flèche, aucun contrôle : des puces
 * en ancres :target écriraient dans l'URL et pollueraient l'historique, et tout
 * autre contrôle demanderait du JavaScript.
 *
 * La piste n'existe qu'à partir de deux entrées, et c'est un branchement PHP :
 * une entrée seule n'a pas de conteneur du tout, donc pas de zone focalisable
 * devant une image unique.
 */
.bandeau__piste {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
}

.bandeau__piste > .bandeau__entree {
	flex: 0 0 88%;
	padding-right: var(--space-xl);
	scroll-snap-align: start;
}

.bandeau__entree {
	align-items: center;
	display: grid;
	gap: var(--space-l);
	grid-template-columns: repeat(auto-fit, minmax(min(var(--news-col-min), 100%), 1fr));
}

/*
 * UNE ENTRÉE SANS IMAGE OCCUPE TOUTE LA LARGEUR, sans colonne vide. Le texte ne
 * reste pas dans une moitié en attendant une image qui n'existe pas.
 */
.bandeau__entree--sans-image {
	display: block;
}

.bandeau__media {
	margin: 0;
}

.bandeau__image {
	aspect-ratio: var(--banner-ratio);
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

.bandeau__corps {
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
	max-width: var(--reading-width);
}

.bandeau__titre {
	font-family: var(--font-body);
	font-size: var(--font-size-2xl);
	font-weight: 600;
	line-height: var(--leading-tight);
	margin: 0;
}

.bandeau__texte {
	color: var(--text-muted);
	font-family: var(--font-ui);
	font-size: var(--font-size-s);
	line-height: var(--leading-normal);
	margin: 0;
}

.bandeau__action {
	margin: 0;
}

.bandeau__lien {
	font-family: var(--font-ui);
	font-size: var(--font-size-xs);
	text-underline-offset: 4px;
}

/*
 * LE BANDEAU EN DIAPORAMA — 30 octobre (maquette Rey, § 12.3). Structure
 * seulement : le script pose `est-diaporama` sur une piste de deux entrées ou
 * plus et ajoute les commandes sous elle. Une vue occupe alors toute la
 * largeur, la barre native cède la place aux commandes ; sans script, rien
 * de ceci ne s'applique et la piste garde ses 88 %.
 */
.bandeau__piste.est-diaporama {
	position: relative;
	scrollbar-width: none;
}

.bandeau__piste.est-diaporama::-webkit-scrollbar {
	display: none;
}

.bandeau__piste.est-diaporama > .bandeau__entree {
	flex-basis: 100%;
	padding-right: 0;
}

.bandeau__commandes {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
	margin-top: var(--space-s);
}

.bandeau__fleche,
.bandeau__repere,
.bandeau__pause {
	align-items: center;
	background: none;
	border: 0;
	color: inherit;
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	justify-content: center;
	min-height: var(--cible);
	min-width: var(--cible);
	padding: 0;
}

.bandeau__reperes {
	display: flex;
	flex-wrap: wrap;
}

/* Un repère : un point dans une cible de 44 px ; le courant, plein. */
.bandeau__repere::before {
	border: 2px solid currentColor;
	border-radius: 50%;
	content: "";
	height: 10px;
	width: 10px;
}

.bandeau__repere[aria-current="true"]::before {
	background: currentColor;
}

.bandeau__compteur {
	font-family: var(--font-ui);
	font-size: var(--font-size-xs);
	font-variant-numeric: tabular-nums;
	margin: 0 var(--space-xs);
}

.bandeau__fleche:focus-visible,
.bandeau__repere:focus-visible,
.bandeau__pause:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

/*
 * UNE ENTRÉE LIÉE À UN LIVRE : la couverture entière, jamais recadrée au
 * format du bandeau ; le cartouche à côté, puis dessous en mobile.
 */
.bandeau__media--couverture {
	display: flex;
	justify-content: center;
}

.bandeau__couverture-lien {
	display: block;
}

.bandeau__couverture {
	display: block;
	height: auto;
	max-height: 28rem;
	max-width: 100%;
	width: auto;
}

.bandeau__auteurs,
.bandeau__mention {
	font-family: var(--font-ui);
	font-size: var(--font-size-s);
	margin: 0;
}

/* -------------------------------------------------------------------------
 * Couvertures — § 12.2
 * ---------------------------------------------------------------------- */

/*
 * L'OMBRE A REMPLACÉ LE FILET le 13 octobre (règles communes des directions,
 * suivi § 2.44) : `--shadow-raised` est un jeton, une direction le règle, et
 * l'ancien argument — deux cents surfaces à composer — tenait pour une ombre
 * portée large ; celle du parent est de deux pixels.
 *
 * La hauteur suit le rapport de l'image, la largeur vient de la cellule : sur
 * l'accueil les grilles sont des planches de couvertures, et l'effet d'étagère
 * du § 3.13 — qui dimensionne par la hauteur — suppose une ligne de base
 * commune qui n'a de sens que dans une liste de catalogue.
 */
/* Plus de cadre d'un pixel (13 octobre) : le relief est l'ombre portée,
   un jeton que chaque direction règle. */
.bloc-couverture {
	box-shadow: var(--shadow-raised);
	background: var(--surface-alt);
	display: block;
	height: auto;
	width: 100%;
}

/*
 * SANS COUVERTURE, UN CADRE AUX MÊMES PROPORTIONS. Une cellule qui
 * s'effondrerait à la hauteur de son texte casserait l'alignement de toute la
 * rangée.
 */
.bloc-couverture--substitut {
	aspect-ratio: var(--cover-ratio, 0.6667);
}

/* -------------------------------------------------------------------------
 * Alignement des couvertures d'accueil — § 3.13, réglage `couverture_alignement`
 *
 * LES TUILES D'ACCUEIL SUIVENT LE MÊME RÉGLAGE QUE LES LISTES, depuis le
 * 24 août. Le mode de dimensionnement reste réglable — largeur égale comprise,
 * qui était le rendu d'origine de l'accueil — mais l'alignement par le bas,
 * lui, ne l'est pas : c'est la règle des listes, dans les trois modes.
 *
 * CE QUI SE PASSAIT AVANT, ET POURQUOI IL FALLAIT LE CORRIGER : à largeur
 * égale, la couverture d'un grand format est la plus COURTE de la rangée. Les
 * tuiles étant alignées par le haut, elle s'arrêtait en l'air, et un beau livre
 * s'affichait plus petit qu'un poche. Mesuré le 24 août sur l'accueil : 246 px
 * pour un 0,73 contre 295 px pour un 0,61, à 179 px de large tous les deux, et
 * 49 px d'écart entre leurs bas.
 *
 * LA TUILE DEVIENT UNE GRILLE, ET LA RÉSERVE EST UN PSEUDO-ÉLÉMENT. La première
 * rangée contient deux choses superposées : un bloc vide qui donne à la rangée
 * la hauteur de la plus haute couverture que la liste puisse produire, et
 * l'image, posée sur le bas de cette rangée. C'est le seul moyen de réserver
 * une hauteur qu'on ne connaît qu'en proportion de la largeur de colonne.
 *
 * Aucun balisage n'a changé — `blocs/couverture.php` garde ses quatre exigences
 * du § 12.2 intactes.
 *
 * LA GRANDE IMAGE RESTE DEHORS. Elle est recadrée en 4/5 (`--cover-large-ratio`)
 * et compose un bloc, pas une étagère : il n'y a rien à aligner avec elle.
 * ---------------------------------------------------------------------- */

.livre-tuile:not(.livre-tuile--grande) > .livre-tuile__lien,
.catalogue-tuile > .catalogue-tuile__lien {
	display: grid;
	grid-template-rows: auto auto;
	justify-items: start;
}

/*
 * LA RÉSERVE EST AUSSI LE CADRE (13 octobre). Le pseudo-élément qui réserve la
 * hauteur de la rangée peint le fond `--couverture-cadre-fond` et s'élargit de
 * `--couverture-cadre-marge` de chaque côté : en `content-box`, le rapport
 * vaut pour la boîte de contenu, la marge s'ajoute autour, et le cadre fait
 * exactement la couverture plus son air. La couverture, posée en bas à gauche
 * de la même case, recule d'autant. Transparent et nul au parent : rien ne
 * change tant qu'une forme ne les pose pas.
 */
.livre-tuile:not(.livre-tuile--grande) > .livre-tuile__lien::before,
.catalogue-tuile > .catalogue-tuile__lien::before {
	aspect-ratio: var(--boite-couverture, 0.6667);
	background: var(--couverture-cadre-fond);
	box-sizing: content-box;
	content: "";
	grid-area: 1 / 1;
	padding: var(--couverture-cadre-marge);
	pointer-events: none;
	width: calc(100% - 2 * var(--couverture-cadre-marge));
}

.livre-tuile:not(.livre-tuile--grande) .bloc-couverture,
.catalogue-tuile .bloc-couverture {
	align-self: end;
	grid-area: 1 / 1;
	justify-self: start;
	margin: 0 0 var(--couverture-cadre-marge) var(--couverture-cadre-marge);
}

/*
 * LA BOÎTE EST RELATIVE, ET ELLE NE PEUT PAS ÊTRE AUTRE CHOSE. Les grilles
 * d'accueil sont en `auto-fill` : leur colonne fait ce que la fenêtre permet, et
 * la feuille de style n'en connaît pas la largeur. Une hauteur en pixels — les
 * 18,75 rem des listes de catalogue — se ferait rogner par `max-width` dès que
 * la colonne est plus étroite que la couverture, et l'égalité de hauteur
 * tomberait sans prévenir. Mesuré le 24 août : à 1 200 px de fenêtre, la colonne
 * d'accueil fait 179 px, une couverture de 300 px de haut en demande 219.
 *
 * TOUT SE DIT DONC EN POURCENTAGE DE LA CELLULE, la seule mesure que la
 * cellule sache donner. La largeur de chaque couverture est une fraction de la
 * colonne, sa proportion lui rend sa hauteur, et les deux bornes de proportion
 * que le plugin pose sur le conteneur suffisent à ce que toutes tombent juste.
 *
 * LA BOÎTE EST L'IMAGE, ET C'EST LA CONDITION DU FILET. Une boîte plus large que
 * la couverture, avec l'image inscrite dedans, aurait aligné aussi bien — mais
 * le filet d'un pixel du § 12.2 se serait dessiné autour de la boîte, à distance
 * de la couverture. Le cadre doit coller à ce qu'il encadre.
 */

/* --- modes « hauteur égale » et « proportionnel » -------------------------
 *
 * LA PROPORTION LA PLUS LARGE COMMANDE : c'est la couverture la plus large qui
 * touche les bords de sa cellule la première, donc elle qui fixe la hauteur que
 * toutes les autres atteindront. Chacune y arrive par le haut de la boîte, et
 * les plus étroites y occupent moins de largeur — c'est exactement l'effet
 * recherché.
 *
 * `--book-scale` fait toute la différence entre les deux modes, comme dans les
 * listes : le plugin ne le pose qu'en mode proportionnel, et seulement sur les
 * fiches qui portent leur format. Rapporté à la plus haute échelle de la liste,
 * il rétrécit la boîte des livres plus petits, dans les deux dimensions à la
 * fois — et `align-items: end` les repose sur la ligne commune.
 */

.couvertures-hauteur .livre-tuile__lien,
.couvertures-proportionnel .livre-tuile__lien,
.couvertures-hauteur .catalogue-tuile__lien,
.couvertures-proportionnel .catalogue-tuile__lien {
	/* La réserve est la boîte de la plus haute : celle qui atteint l'échelle
	   maximale de la liste. Les autres y sont posées par le bas. */
	--boite-couverture: var(--list-max-ratio, 0.6667);
}

.couvertures-hauteur .livre-tuile:not(.livre-tuile--grande) .bloc-couverture,
.couvertures-proportionnel .livre-tuile:not(.livre-tuile--grande) .bloc-couverture,
.couvertures-hauteur .catalogue-tuile .bloc-couverture,
.couvertures-proportionnel .catalogue-tuile .bloc-couverture {
	height: auto;
	width: calc((100% - 2 * var(--couverture-cadre-marge)) * var(--book-scale, 1) / var(--cover-max-scale, 1) * var(--cover-ratio, 0.6667) / var(--list-max-ratio, 0.6667));
}

/* --- mode « largeur égale » ----------------------------------------------
 *
 * Le rendu d'origine de l'accueil, avec sa ligne de base en plus. La boîte
 * prend cette fois la proportion la plus ÉTROITE de la liste — la plus haute,
 * donc, à largeur commune. Toutes les images gardent la largeur de leur
 * cellule, et leurs bas s'alignent.
 */

.couvertures-largeur .livre-tuile__lien,
.couvertures-largeur .catalogue-tuile__lien {
	--boite-couverture: var(--list-min-ratio, 0.6667);
}

.couvertures-largeur .livre-tuile:not(.livre-tuile--grande) .bloc-couverture,
.couvertures-largeur .catalogue-tuile .bloc-couverture {
	height: auto;
	width: calc(100% - 2 * var(--couverture-cadre-marge));
}

.bloc-couverture--grande {
	aspect-ratio: var(--cover-large-ratio);
	object-fit: cover;
}

/* -------------------------------------------------------------------------
 * Tuiles de livre
 * ---------------------------------------------------------------------- */

.livre-tuile,
.catalogue-tuile {
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
	min-width: 0;
}

.livre-tuile__lien,
.catalogue-tuile__lien {
	color: inherit;
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	text-decoration: none;
}

.livre-tuile__titre {
	color: var(--list-title-color);
	font-family: var(--font-body);
	font-size: var(--font-size-m);
	font-weight: var(--list-title-weight);
	line-height: var(--leading-snug);
	margin: 0;
}

.livre-tuile--grande .livre-tuile__titre {
	font-size: var(--font-size-xl);
	line-height: var(--leading-snug);
}

.livre-tuile__signature,
.catalogue-tuile__signature {
	color: var(--list-author-color);
	font-family: var(--font-body);
	font-size: var(--font-size-m);
	font-weight: var(--list-author-weight);
	line-height: var(--leading-snug);
	margin: 0;
}

/* Les noms sont des liens depuis le 29 octobre : ils gardent la couleur de la
   signature, qu'une forme règle sur son aplat ; soulignés au survol et au
   focus par la règle commune. */
.livre-tuile__signature a,
.catalogue-tuile__signature a {
	color: inherit;
}

.livre-tuile__meta {
	color: var(--text-faint);
	font-family: var(--font-ui);
	font-size: var(--font-size-2xs);
	line-height: var(--leading-normal);
	margin: 0;
}

.livre-tuile__resume {
	color: var(--text-muted);
	font-family: var(--font-ui);
	font-size: var(--font-size-s);
	line-height: var(--leading-normal);
	margin: 0;
	max-width: var(--reading-width);
}

/* -------------------------------------------------------------------------
 * Catalogue complet — tenue à deux cents couvertures
 * ---------------------------------------------------------------------- */

/*
 * `content-visibility: auto` fait que le navigateur ne compose que ce qui
 * approche de l'écran ; `contain-intrinsic-size` annonce la place que la
 * cellule prendra, faute de quoi la barre de défilement sauterait à chaque
 * cellule composée.
 *
 * La hauteur annoncée est celle de la piste plus la ligne de titre : elle n'a
 * pas à être exacte, seulement plausible — une valeur trop éloignée ferait
 * bouger le défilement, jamais rien de pire.
 */
.bloc-grille--catalogue .catalogue-tuile {
	contain-intrinsic-size: auto var(--catalogue-col-min) auto 14rem;
	content-visibility: auto;
}

.bloc-grille--compacte .catalogue-tuile {
	contain-intrinsic-size: auto var(--compact-col-min) auto 7rem;
}

.catalogue-tuile__titre {
	color: var(--list-title-color);
	font-family: var(--font-body);
	font-size: var(--font-size-xs);
	font-weight: var(--list-title-weight);
	line-height: var(--leading-snug);
	margin: 0;
}

.catalogue-tuile__signature {
	font-size: var(--font-size-xs);
}

/* -------------------------------------------------------------------------
 * Actualités
 * ---------------------------------------------------------------------- */

/*
 * Cellules calées en haut : un article sans image se resserre sur son texte, et
 * la rangée reste alignée. Réserver la hauteur d'une image absente ferait
 * flotter le texte de l'article illustré au-dessus des autres.
 */
.actualite-tuile {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	min-width: 0;
}

.actualite-tuile__media {
	display: block;
}

.actualite-tuile__image {
	aspect-ratio: var(--news-ratio);
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

.actualite-tuile__date {
	color: var(--text-faint);
	font-family: var(--font-ui);
	font-size: var(--font-size-2xs);
	margin: 0;
}

.actualite-tuile__titre {
	font-family: var(--font-body);
	font-size: var(--font-size-l);
	font-weight: 600;
	line-height: var(--leading-snug);
	margin: 0;
}

.actualite-tuile__titre a {
	color: inherit;
	text-decoration: none;
}

.actualite-tuile__titre a:hover {
	text-decoration: underline;
}

.actualite-tuile__chapo {
	color: var(--text-muted);
	font-family: var(--font-ui);
	font-size: var(--font-size-s);
	line-height: var(--leading-normal);
	margin: 0;
	max-width: var(--reading-width);
}

/* Liste compacte : ni image ni chapô. */
.actualite-ligne {
	align-items: baseline;
	display: grid;
	gap: var(--space-s);
	grid-template-columns: minmax(0, 6rem) minmax(0, 1fr);
	padding-block: var(--space-2xs);
}

.actualite-ligne__date {
	color: var(--text-faint);
	font-family: var(--font-ui);
	font-size: var(--font-size-2xs);
}

.actualite-ligne__titre {
	color: inherit;
	font-family: var(--font-body);
	font-size: var(--font-size-m);
	line-height: var(--leading-snug);
	text-decoration: none;
}

.actualite-ligne__titre:hover {
	text-decoration: underline;
}

/* -------------------------------------------------------------------------
 * Événements
 * ---------------------------------------------------------------------- */

.evenement-ligne {
	display: grid;
	gap: var(--space-s);
	grid-template-columns: minmax(0, 7rem) minmax(0, 1fr);
	padding-block: var(--space-xs);
}

.evenement-ligne__date {
	color: var(--text);
	font-family: var(--font-ui);
	font-size: var(--font-size-2xs);
	line-height: var(--leading-normal);
}

.evenement-ligne__corps {
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
	min-width: 0;
}

.evenement-ligne__titre {
	color: inherit;
	font-family: var(--font-body);
	font-size: var(--font-size-m);
	font-weight: 600;
	line-height: var(--leading-snug);
	text-decoration: none;
}

.evenement-ligne__titre:hover {
	text-decoration: underline;
}

.evenement-ligne__lieu {
	color: var(--text-muted);
	font-family: var(--font-ui);
	font-size: var(--font-size-xs);
}

/*
 * RENCONTRES EN VEDETTE (`presentation => 'vedette'`, 26 octobre) — la
 * première en grand, jour, mois et année, heure, puis titre et lieu ; les
 * suivantes en lignes compactes. Aucun filet : l'espacement sépare. Rendu de
 * base, valable dans toute direction ; la forme Affiche le règle sur la
 * maquette (A5b). « Tout l'agenda » descend au pied du bloc quand le bloc est
 * étiré sur sa rangée.
 */
.bloc--evenements-vedette .bloc__debordement {
	margin-top: auto;
}

/*
 * LES IMAGES (26 octobre, décision de Phil à 08h20) : la vedette a la sienne,
 * chaque suivante une petite — la règle de la carte d'agenda, par le fragment
 * commun. Jamais recadrées : hauteur fixe, largeur déduite du rapport,
 * `object-fit: contain` si la largeur manque.
 *
 * CÔTE À CÔTE SEULEMENT SI LE BLOC A LA PLACE, et c'est le bloc qu'on
 * interroge, pas la fenêtre : la demie fait 270 px utiles à 1 024 (colonne
 * d'en-tête), 460 à 1 440. Sous 28 rem de bloc, ou sous 900 px de fenêtre
 * (empilement de la rangée), l'image de la vedette passe au-dessus du texte.
 * Les suivantes sont l'une sous l'autre à toutes les largeurs.
 */
.bloc--evenements-vedette {
	--rencontre-vedette-image: 15rem;
	--rencontre-ligne-image: 6.5rem;
	container-type: inline-size;
}

.rencontre-vedette {
	display: flex;
	flex-direction: column;
	gap: var(--space-s);
}

.rencontre-vedette__corps {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	min-width: 0;
}

.rencontre-vedette__media,
.rencontre-ligne__media {
	align-self: flex-start;
	display: block;
	flex: none;
	max-width: 100%;
}

.rencontre-vedette__image,
.rencontre-ligne__image {
	display: block;
	max-width: 100%;
	object-fit: contain;
	width: auto;
}

.rencontre-vedette__image {
	height: var(--rencontre-vedette-image);
}

.rencontre-ligne__image {
	height: var(--rencontre-ligne-image);
}

.rencontre-vedette__bouton {
	align-self: flex-start;
	margin-top: var(--space-xs);
}

.rencontre-vedette__bouton:is(:hover, :focus-visible) {
	text-decoration: underline;
	text-underline-offset: 3px;
}


/*
 * LA DATE SUR UNE LIGNE (26 octobre, 08h35) : la phrase de la carte d'agenda
 * sans le jour de la semaine, un seul corps, le plus grand qui tient dans la
 * colonne. La colonne est un conteneur ; le gabarit compte les signes de la
 * date réelle par classe de chasse (--n-chiffres, --n-espaces, --n-points,
 * --n-etroites, --n-larges, --n-lettres) ; le corps vaut la largeur de la
 * colonne divisée par leur somme pondérée.
 *
 * LES CHASSES SONT MESURÉES, en em, chaque signe pris entre deux autres, le
 * plus large de sa classe retenu, à 16, 20, 26, 32 et 40 px — une police à
 * taille optique s'élargit aux petits corps ; au parent, le plus large de
 * quatre polices de titre essayées (Georgia pour les chiffres et les
 * lettres, system-ui pour les espaces). Vérifié sur toutes les dates sans
 * jour — douze mois, jours 1 à 31, sans heure, à l'heure ronde, avec
 * minutes —, à ces cinq corps : la largeur réelle ne dépasse jamais la
 * prévision. Plancher 1 rem, plafond 2,5 rem ; jamais de retour.
 */
.rencontre-vedette__corps {
	container-type: inline-size;
}

.rencontre-vedette__date {
	--chasse-chiffre: 0.702;
	--chasse-espace: 0.276;
	--chasse-point: 0.338;
	--chasse-etroite: 0.521;
	--chasse-lettre: 0.691;
	--chasse-large: 1.016;
	color: var(--text);
	font-family: var(--section-title-family);
	font-size: clamp(
		1rem,
		100cqi / (
			var(--n-chiffres, 0) * var(--chasse-chiffre)
			+ var(--n-espaces, 0) * var(--chasse-espace)
			+ var(--n-points, 0) * var(--chasse-point)
			+ var(--n-etroites, 0) * var(--chasse-etroite)
			+ var(--n-larges, 0) * var(--chasse-large)
			+ var(--n-lettres, 0) * var(--chasse-lettre)
		),
		2.5rem
	);
	font-weight: 700;
	line-height: 1.15;
	margin: 0;
	overflow: hidden;
	white-space: nowrap;
}

.rencontre-vedette__texte,
.rencontre-ligne__texte {
	color: var(--text);
	font-family: var(--font-body);
	font-size: var(--font-size-m);
	line-height: var(--leading-normal);
	margin: 0;
}

.rencontre-vedette__titre {
	font-size: var(--font-size-l);
	line-height: var(--leading-snug);
	margin: var(--space-2xs) 0 0;
}

.rencontre-vedette__titre a,
.rencontre-ligne__titre {
	color: inherit;
	text-decoration: none;
}

.rencontre-vedette__titre a:is(:hover, :focus-visible),
.rencontre-ligne__titre:is(:hover, :focus-visible) {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.rencontre-vedette__lieu {
	font-family: var(--font-ui);
	font-size: var(--font-size-s);
	margin: 0;
}

.rencontres-suivantes {
	display: flex;
	flex-direction: column;
	gap: var(--space-s);
	list-style: none;
	margin: var(--space-xs) 0 0;
	padding: 0;
}

.rencontre-ligne {
	align-items: flex-start;
	display: flex;
	gap: var(--space-s);
}

.rencontre-ligne__corps {
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
	min-width: 0;
}

.rencontre-ligne__date {
	font-family: var(--font-ui);
	font-size: var(--font-size-s);
	font-weight: 700;
}

.rencontre-ligne__titre {
	font-family: var(--font-body);
	font-size: var(--font-size-m);
	font-weight: 600;
	line-height: var(--leading-snug);
}

.rencontre-ligne__lieu {
	font-family: var(--font-ui);
	font-size: var(--font-size-xs);
}

/* Côte à côte : après les règles de base, qu'elles remplacent. */
@container (min-width: 28rem) {
	@media (min-width: 56.25rem) {
		.rencontre-vedette:has(> .rencontre-vedette__media) {
			align-items: flex-start;
			flex-direction: row;
			gap: var(--space-m);
		}

		/* Conteneur, la colonne n'a pas de largeur propre : elle prend le
		   reste de la rangée. */
		.rencontre-vedette:has(> .rencontre-vedette__media) > .rencontre-vedette__corps {
			flex: 1 1 0;
		}
	}
}

/* Les suivantes l'une sous l'autre à toutes les largeurs (26 octobre,
   décision de Phil) : côte à côte, chacune n'avait que 136 px de texte à
   1 440, et le nom de l'invité ne tenait pas en deux lignes. Elles restent
   en colonne (règle de base, plus haut) ; leur texte prend la largeur. */
.rencontre-ligne__corps {
	flex: 1 1 0;
}

/* -------------------------------------------------------------------------
 * Revue de presse
 * ---------------------------------------------------------------------- */

.presse-citation {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	margin: 0;
}

.presse-citation__texte {
	font-family: var(--font-body);
	font-size: var(--font-size-l);
	font-style: italic;
	line-height: var(--leading-snug);
	margin: 0;
	max-width: var(--reading-width);
}

.presse-citation__source {
	color: var(--text-faint);
	font-family: var(--font-ui);
	font-size: var(--font-size-2xs);
	font-style: normal;
}

.presse-citation__source a {
	color: inherit;
}

/* -------------------------------------------------------------------------
 * Texte libre
 * ---------------------------------------------------------------------- */

.texte-libre {
	max-width: var(--reading-width);
}

.texte-libre > :first-child {
	margin-top: 0;
}

.texte-libre > :last-child {
	margin-bottom: 0;
}

/*
 * LE COMPAGNON DU TEXTE (§ 12.2, 13 octobre) — les collections à droite du texte
 * de présentation, calculées, jamais saisies. La rangée n'existe que si le
 * texte est saisi et qu'une collection a un livre publié : sinon le gabarit
 * rend le texte seul, comme avant. Au-dessus de 48 rem, LA RANGÉE SE CALE SUR
 * LA GRILLE DES COUVERTURES de la bande au-dessus (13 octobre, après-midi) :
 * six pistes égales et la même gouttière que `.bloc-grille--couvertures`, qui
 * compte six colonnes dès 1 280 px — les bords tombent au pixel sur les
 * couvertures. Le texte, intitulé compris, occupe les pistes 1 à 3, la
 * quatrième reste vide, le compagnon prend les pistes 5 et 6, calé en haut sur
 * l'intitulé du texte — sur la ligne de base de leurs intitulés (`first
 * baseline` : le premier alignement de ligne de base de chaque colonne est
 * celui de son intitulé), et non sur le haut de leurs boîtes, de corps
 * différents. Quand la bande compte moins de six colonnes (entre
 * 48 rem et 1 280 px), les six pistes ne coïncident plus avec elle et la règle
 * devient : texte sur la moitié gauche, compagnon sur le dernier tiers. En
 * dessous de 48 rem, une colonne, le compagnon sous le texte. Séparés par
 * l'espace : aucun filet, aucune puce.
 */
.texte-rangee {
	align-items: first baseline;
	display: grid;
	gap: var(--space-l) var(--space-m);
}

.texte-rangee__colonne {
	display: flex;
	flex-direction: column;
	gap: var(--space-m);
	min-width: 0;
}

.texte-compagnon {
	display: flex;
	flex-direction: column;
	gap: var(--space-s);
	min-width: 0;
}

/* L'intitulé du compagnon : celui des sections, un cran plus petit. */
.bloc__intitule--compagnon {
	font-size: var(--section-title-size-second);
}

.texte-compagnon__liste {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	list-style: none;
	margin: 0;
	padding: 0;
}

.texte-compagnon__entree {
	align-items: baseline;
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--space-2xs);
}

.texte-compagnon__nombre {
	color: var(--text-muted);
	font-family: var(--font-ui);
	font-size: var(--font-size-xs);
}

@media (min-width: 48rem) {
	.texte-rangee {
		column-gap: var(--space-m);
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	.texte-rangee__colonne {
		grid-column: 1 / span 3;
	}

	.texte-compagnon {
		grid-column: 5 / span 2;
	}
}

/* -------------------------------------------------------------------------
 * Les blocs de la maquette LLL — § 12.2, 17 octobre
 * ---------------------------------------------------------------------- */

/*
 * STRUCTURE SEULEMENT : des grilles, des écarts aux jetons d'espace, des
 * marges remises à zéro. Aucune couleur, famille ni corps — les titres gardent
 * ceux de leur balise. L'habillage (inclinaisons, ombres, trames, pastille
 * ronde, aplats) viendra de la forme qui conseille la composition Affiche.
 *
 * Livre du moment et collection à la une : le texte, puis le visuel ; deux
 * colonnes de 48 rem et plus, le texte sur trois cinquièmes. Auteur·ice à la
 * une : portrait et texte côte à côte dès 48 rem, le texte seul s'il n'y a pas
 * de portrait. La devise tient sur une ligne : ce qui dépasse est masqué.
 */
.livre-du-moment,
.collection-une,
.auteur-une {
	display: grid;
	gap: var(--space-l);
}

.livre-du-moment__corps,
.collection-une__corps,
.auteur-une__corps {
	display: flex;
	flex-direction: column;
	gap: var(--space-s);
	min-width: 0;
}

.livre-du-moment__surtitre,
.livre-du-moment__titre,
.livre-du-moment__sous-titre,
.livre-du-moment__contributeurs,
.livre-du-moment__actions,
.livre-du-moment__pastille,
.collection-une__surtitre,
.collection-une__nom,
.collection-une__actions,
.collection-une__livre-signature,
.auteur-une__surtitre,
.auteur-une__nom,
.auteur-une__livre,
.devise {
	margin: 0;
}

.livre-du-moment__texte > :first-child,
.collection-une__texte > :first-child,
.auteur-une__bio > :first-child {
	margin-top: 0;
}

.livre-du-moment__texte > :last-child,
.collection-une__texte > :last-child,
.auteur-une__bio > :last-child {
	margin-bottom: 0;
}

.livre-du-moment__actions,
.collection-une__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-xs);
}

.livre-du-moment__visuel,
.collection-une__livre {
	align-items: flex-start;
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
	min-width: 0;
}

.livre-du-moment__pastille,
.collection-une__couverture {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
}

/* La couverture entière, à sa proportion, bornée : elle ne prend jamais plus
   que sa colonne, ni plus de 24 rem. */
.livre-du-moment__couverture,
.collection-une__couverture {
	max-width: min(100%, 24rem);
	width: 100%;
}

.auteur-une__portrait {
	min-width: 0;
}

.auteur-une__image {
	display: block;
	height: auto;
	max-width: 100%;
}

.devise {
	overflow: hidden;
	white-space: nowrap;
}

@media (min-width: 48rem) {
	.livre-du-moment,
	.collection-une {
		align-items: center;
		grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
	}

	.auteur-une {
		align-items: start;
		grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
	}

	.auteur-une--sans-portrait {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* -------------------------------------------------------------------------
 * Mouvement réduit — § 12.3
 * ---------------------------------------------------------------------- */

/*
 * Le visiteur qui a demandé à réduire les animations n'obtient ni défilement
 * doux ni transition. L'accrochage est neutralisé avec : sur un défilement
 * instantané, scroll-snap produit des sauts secs d'une entrée à l'autre, ce qui
 * est précisément le genre de mouvement que le réglage cherche à éviter.
 */
@media (prefers-reduced-motion: reduce) {
	.accueil-flux *,
	.accueil-flux *::before,
	.accueil-flux *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
		transition-duration: 0.01ms !important;
	}

	.bandeau__piste,
	.bloc-piste {
		scroll-snap-type: none;
	}
}

/* -------------------------------------------------------------------------
 * Accroche sous l'intitulé — 29 octobre (suivi § 2.116)
 *
 * Saisie pour les nouveautés, extraite de la présentation pour une collection
 * en rangée. En italique éditorial, en texte atténué ; une forme la règle sur
 * son aplat. Vide, elle n'est pas rendue.
 * ---------------------------------------------------------------------- */
.bloc__accroche {
	color: var(--text-muted);
	font-family: var(--font-editorial);
	font-size: var(--font-size-l);
	font-style: italic;
	line-height: var(--leading-snug);
	margin-top: var(--space-2xs);
	max-width: var(--reading-width);
}

.bloc__accroche p {
	margin: 0;
}
