/**
 * Bloc oniti-core/collection-01 — squelette « grille ↔ carrousel ».
 *
 * Aucun design de carte ici : ce fichier ne place que les enfants. L'apparence d'une
 * carte appartient au thème enfant.
 *
 * Toute la mise en page passe par des custom properties posées sur le wrapper et lues
 * par le viewport : une seule règle décrit les trois présentations, chaque mode ne
 * faisant que réaffecter ces propriétés.
 *
 * L'état de base est le CARROUSEL, la grille s'obtenant dans une requête de conteneur.
 * Ce n'est pas esthétique : le seuil d'une @container ne peut pas être une custom
 * property, donc render.php écrit les règles d'après les seuils de l'auteur. Partir du
 * carrousel évite d'avoir à annuler `overflow`, `scroll-snap-type`, le plein cadre et
 * les marges du masonry.
 *
 * La bascule suit la largeur du CONTENEUR, pas de la fenêtre : le bloc se comporte donc
 * correctement dans une colonne étroite ou une sidebar.
 */

/* ==========================================================================
   1. Valeurs par défaut — l'état « carrousel »
   ========================================================================== */

/*
 * Sur le VIEWPORT et non sur le wrapper : une @container ne style que les descendants
 * de son conteneur, or c'est le wrapper qui porte `container-type`. Les réglages de
 * l'auteur, eux, restent sur le wrapper et descendent par héritage.
 *
 * Dans :where(), donc à spécificité nulle : ces valeurs perdent contre la règle de
 * bascule, et coupent l'héritage quand une collection est imbriquée dans une autre.
 */
:where( .oniti-collection-01__viewport ) {
	--oniti-collection-01-display: flex;
	--oniti-collection-01-multicol: auto;
	/* `hidden` et non `clip` : voir l'amélioration progressive en fin de section 2. */
	--oniti-collection-01-overflow: auto hidden;
	--oniti-collection-01-snap: x mandatory;
	--oniti-collection-01-gutter: var( --oniti-collection-01-focus-gutter );

	/*
	 * Plein cadre : la piste sort du conteneur de contenu, ce qui fait couper la carte
	 * suivante par le bord de l'écran et non par la marge de la page. Réserve de
	 * l'idiome `calc(50% - 50vw)` : `vw` inclut la barre de défilement classique, donc
	 * un carrousel forcé sur un desktop Windows peut déborder de quelques pixels —
	 * neutralisable par `--oniti-collection-01-bleed: 0` depuis le thème enfant.
	 */
	--oniti-collection-01-bleed: calc( 50% - 50vw );

	/* Côté départ le dégagement voulu, côté fin juste de quoi ne pas rogner le focus. */
	--oniti-collection-01-inset: var( --oniti-collection-01-edge )
		var( --oniti-collection-01-focus-gutter );

	/* Inerte en carrousel, faute de largeur maximale ; la grille passe en `content-box`. */
	--oniti-collection-01-box: border-box;

	/* Largeur maximale de la piste : libre en carrousel, ramenée en grille au choix de
	   l'auteur. C'est le bloc qui porte sa limite et non le conteneur qui l'héberge —
	   sinon une collection en pleine largeur s'étalerait sur toute la fenêtre. */
	--oniti-collection-01-max: none;

	--oniti-collection-01-item-snap: start;
	--oniti-collection-01-item-break: auto;
	--oniti-collection-01-item-space: 0;
}

.oniti-collection-01 {
	/* Réglages exposés au thème enfant et écrits par render.php. */
	--oniti-collection-01-columns: 3;
	--oniti-collection-01-gap: var( --wp--style--block-gap, 1.5rem );

	/* Cartes visibles dans la piste. Une valeur fractionnaire fait dépasser la
	   suivante : c'est ce débord qui signale qu'il y a de quoi faire défiler. */
	--oniti-collection-01-visible: 2.4;

	/* Sans ce dégagement, `overflow` rogne les anneaux de focus au ras de la carte —
	   RGAA 3.2 / WCAG 2.4.11 exigent un focus visible. */
	--oniti-collection-01-focus-gutter: 0.25rem;

	/* Bord de départ de la piste en carrousel. À brancher sur le palier d'espacement
	   du site depuis le thème enfant. */
	--oniti-collection-01-edge: 1rem;

	/* Contexte de requête de conteneur pour la bascule. */
	container: oniti-collection-01 / inline-size;
}

/* ==========================================================================
   2. Le viewport — une seule règle pour les trois présentations
   ========================================================================== */

.oniti-collection-01__viewport {
	display: var( --oniti-collection-01-display );
	gap: var( --oniti-collection-01-gap );

	/* Largeur d'une carte en carrousel : la place disponible moins les écarts, divisée
	   par le nombre de cartes visibles. Un nombre fractionnaire laisse donc
	   naturellement dépasser la suivante. */
	--oniti-collection-01-item-width: calc(
		( 100% - ( var( --oniti-collection-01-visible ) - 1 ) * var( --oniti-collection-01-gap ) )
		/ var( --oniti-collection-01-visible )
	);

	/* Inertes hors de leur mode — `grid-template-columns` est ignorée par un conteneur
	   flex ou block, `columns` par une grille. Les laisser évite de les annuler dans
	   la règle générée. */
	grid-template-columns: repeat( var( --oniti-collection-01-columns ), minmax( 0, 1fr ) );
	columns: var( --oniti-collection-01-multicol );

	overflow: var( --oniti-collection-01-overflow );

	/* `--bleed: auto` centre la grille ; `content-box` fait porter la largeur maximale
	   sur les cartes, qui s'alignent alors sur les blocs voisins. */
	box-sizing: var( --oniti-collection-01-box );

	max-inline-size: var( --oniti-collection-01-max );
	margin-inline: var( --oniti-collection-01-bleed );
	padding-block: var( --oniti-collection-01-gutter );
	padding-inline: var( --oniti-collection-01-inset );

	/* Le même retrait en `scroll-padding`, sinon il ne tient pas : en défilement
	   magnétique le navigateur cale la carte sur le bord du scrollport — donc sous le
	   padding — dès le chargement. */
	scroll-padding-inline: var( --oniti-collection-01-inset );

	scroll-snap-type: var( --oniti-collection-01-snap );

	/* Le défilement horizontal ne déclenche pas celui de la page. */
	overscroll-behavior-x: contain;

	/* Barre masquée : le débord de la carte suivante et les contrôles signalent déjà
	   qu'il y a à faire défiler. Le défilement lui-même reste entier — tactile,
	   molette, clavier. */
	scrollbar-width: none;
}

.oniti-collection-01__viewport::-webkit-scrollbar {
	display: none;
}

.oniti-collection-01__viewport > * {
	scroll-snap-align: var( --oniti-collection-01-item-snap );

	/* Largeur déduite du nombre de cartes visibles. `flex` est ignoré en grille comme
	   en masonry. */
	flex: 0 0 var( --oniti-collection-01-item-width );

	/* Utiles au seul masonry, inertes ailleurs (`break-inside`) ou nulles. */
	break-inside: var( --oniti-collection-01-item-break );
	margin-block-end: var( --oniti-collection-01-item-space );
}

/*
 * `clip` ne crée pas de conteneur de défilement sur son axe, ce qui autorise à élargir
 * le bord de rognage : les ombres portées ne sont plus coupées au ras du conteneur.
 * `auto hidden` reste le défaut, la panne inverse étant bien pire — un `overflow` non
 * compris met la page entière à défiler.
 */
@supports ( overflow: clip ) {
	:where( .oniti-collection-01__viewport ) {
		--oniti-collection-01-overflow: auto clip;
	}

	.oniti-collection-01__viewport {
		overflow-clip-margin: var( --oniti-collection-01-clip-margin, 1.5rem );
	}
}

/*
 * Le viewport devient une tabulation quand il défile réellement (WCAG 2.1.1) : view.js
 * pose alors `tabindex`, lui seul sachant si le contenu déborde. D'où le filtre
 * `[tabindex]` — sans lui l'anneau cerclerait toute la grille dès que le conteneur
 * reçoit le focus, ce qui arrive dans l'éditeur.
 */
.oniti-collection-01__viewport[tabindex]:focus-visible {
	outline: var( --oniti-collection-01-focus-width, 2px ) solid
		var( --oniti-collection-01-focus-color, currentColor );
	outline-offset: var( --oniti-collection-01-focus-offset, 2px );
}

/* ==========================================================================
   3. La bascule
   ==========================================================================
   Rien ici : la règle de passage en grille est écrite par render.php, dépendant du
   seuil en pixels de l'auteur. Elle a cette forme :

     @container oniti-collection-01 ( width >= 782px ) {
         .oniti-collection-01--c782-600-1_2 .oniti-collection-01__viewport { … }
     }

   Le descendant n'est pas cosmétique : une @container ne style QUE les descendants de
   son conteneur. Viser la classe seule ne s'appliquerait à rien, et le bloc resterait
   indéfiniment en carrousel.

   Les sélecteurs générés pèsent (0,2,0) et (0,3,0) là où le socle de la section 1 est
   en :where() (0,0,0) : la bascule gagne quel que soit l'ordre d'arrivée des feuilles,
   ce qui compte puisque le <style> est émis dans le corps de la page.
   ========================================================================== */

/* Le masonry empile ses cartes par des marges : la dernière laisse un blanc en bas de
   chaque colonne, dont le viewport se rétracte. */
.oniti-collection-01--masonry .oniti-collection-01__viewport {
	margin-block-end: calc( -1 * var( --oniti-collection-01-item-space ) );
}

/* ==========================================================================
   4. Navigation
   ==========================================================================
   Le bloc `nav` arrive masqué du serveur et n'est révélé par view.js que si le
   contenu déborde vraiment : pas de contrôle inerte en grille, ni sans JavaScript
   (où le défilement tactile et la molette restent opérants).
   ========================================================================== */

.oniti-collection-01__nav:not( [hidden] ) {
	display: flex;
	align-items: center;
	justify-content: var( --oniti-collection-01-nav-justify, flex-end );
	gap: var( --oniti-collection-01-nav-gap, 0.5rem );
	margin-block-start: var( --oniti-collection-01-nav-space, 1rem );

	/*
	 * Les contrôles restent dans la colonne de lecture avec le même dégagement que les
	 * cartes : la piste débordant sur toute la fenêtre, les flèches iraient sinon se
	 * coller au bord de l'écran. `border-box` comme la piste, sans quoi la largeur
	 * maximale porterait sur la boîte de contenu et les flèches dépasseraient le bord
	 * droit des cartes de deux dégagements.
	 */
	box-sizing: border-box;

	max-inline-size: var( --oniti-collection-01-max-width, none );
	margin-inline: auto;
	padding-inline: var( --oniti-collection-01-edge );
}

.oniti-collection-01__nav--start {
	--oniti-collection-01-nav-justify: flex-start;
}

.oniti-collection-01__nav--center {
	--oniti-collection-01-nav-justify: center;
}

.oniti-collection-01__nav--end {
	--oniti-collection-01-nav-justify: flex-end;
}

.oniti-collection-01__arrow,
.oniti-collection-01__dot {
	/* Taille dessinée, au choix de l'auteur. En rem, jamais en px, pour suivre le zoom
	   texte (RGAA). */
	inline-size: var( --oniti-collection-01-nav-size, 2.75rem );
	block-size: var( --oniti-collection-01-nav-size, 2.75rem );

	/* Débord de la cible de chaque côté du dessin : moitié du manque, ou zéro. */
	--oniti-collection-01-nav-reach: max(
		0px,
		(
			var( --oniti-collection-01-nav-target, 2.75rem ) -
				var( --oniti-collection-01-nav-size, 2.75rem )
		) / 2
	);

	/* Réserve dans le flux la place où le pseudo-élément déborde — lui est hors flux et
	   ne pousse rien. Sans cette marge, deux contrôles dessinés petits voient leurs
	   zones se recouvrir et c'est le dernier dans l'ordre du DOM qui capte le clic. */
	margin: var( --oniti-collection-01-nav-reach );

	display: grid;
	place-items: center;
	position: relative;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	cursor: pointer;

	/*
	 * Indispensable : un <button> n'hérite pas de `color` et retomberait sur le noir de
	 * l'agent utilisateur, alors que le rond plein s'appuie sur `currentColor`. Et
	 * `inherit` plutôt qu'une couleur choisie, sinon le fond prendrait la teinte du
	 * glyphe — le choix de l'auteur se pose un niveau plus bas.
	 */
	color: inherit;
}

/*
 * Cible tactile garantie quelle que soit la taille dessinée : une zone centrée
 * invisible reçoit les clics, en débordant dans la marge réservée ci-dessus. 44px =
 * WCAG 2.5.5 (AAA) et usage RGAA ; le minimum AA de 2.5.8 est 24px. `max( 100%, … )`
 * laisse la zone couvrir un dessin plus grand que la cible.
 */
.oniti-collection-01__arrow::after,
.oniti-collection-01__dot::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	translate: -50% -50%;
	inline-size: max( 100%, var( --oniti-collection-01-nav-target, 2.75rem ) );
	block-size: max( 100%, var( --oniti-collection-01-nav-target, 2.75rem ) );
}

/* Glyphe et icône sont dimensionnés en `em` : une taille de police proportionnelle au
   bouton les fait suivre son échelle, sans second réglage à exposer. */
.oniti-collection-01__arrow {
	font-size: calc( var( --oniti-collection-01-nav-size, 2.75rem ) * 0.5 );
}

/*
 * Habillage des flèches — deux réglages indépendants, donc quatre combinaisons. Aucune
 * couleur en dur, et sélecteurs à deux classes pour gagner sur la règle de base quel
 * que soit l'ordre du fichier.
 *
 * Bague : la couleur choisie par l'auteur, sinon celle de l'icône, sinon celle du texte.
 * Un thème enfant qui épingle `--oniti-collection-01-nav-ring` court-circuite les deux
 * derniers ; le choix de l'auteur reste au-dessus, arrivant en style en ligne.
 */
.oniti-collection-01__arrow.oniti-collection-01__arrow--outline {
	border: var( --oniti-collection-01-nav-stroke, 2px ) solid
		var( --oniti-collection-01-nav-ring, var( --oniti-collection-01-nav-glyph, currentColor ) );
}

.oniti-collection-01__arrow.oniti-collection-01__arrow--filled {
	background: var( --oniti-collection-01-nav-fill, currentColor );
}

/* La couleur se pose sur le glyphe et non sur le bouton : là, `color` et
   `background: currentColor` cohabiteraient dans la même règle, `currentColor` se
   résoudrait sur l'élément lui-même et le rond prendrait la couleur du glyphe. */
.oniti-collection-01__arrow-glyph,
.oniti-collection-01__arrow-icon {
	color: var( --oniti-collection-01-nav-glyph, inherit );
}

/* Rond plein sans couleur de glyphe explicite : le glyphe passe en négatif. `Canvas`
   est la couleur de fond de page du système, donc suit le mode sombre. */
.oniti-collection-01__arrow--filled .oniti-collection-01__arrow-glyph,
.oniti-collection-01__arrow--filled .oniti-collection-01__arrow-icon {
	color: var( --oniti-collection-01-nav-glyph, var( --oniti-collection-01-nav-on-fill, Canvas ) );
}

/*
 * Chevron dessiné en CSS, quand aucune icône n'est choisie : le squelette n'a alors
 * aucune dépendance à une bibliothèque propre à chaque site.
 *
 * Le recentrage porte sur le TRACÉ et non sur la boîte : le chevron n'est peint que sur
 * deux côtés du carré, et après rotation ces bords tiennent dans la moitié droite d'une
 * boîte que `place-items: center` centre pourtant en entier. On le ramène du quart de la
 * diagonale, soit taille × √2 / 4 ≈ 0.354.
 *
 * `transform` plutôt que les propriétés `rotate` et `translate` : celles-ci s'appliquent
 * dans un ordre imposé — translate d'abord — donc le décalage serait tourné.
 */
.oniti-collection-01__arrow-glyph {
	--oniti-collection-01-chevron: 0.5em;

	inline-size: var( --oniti-collection-01-chevron );
	block-size: var( --oniti-collection-01-chevron );
	border-block-start: var( --oniti-collection-01-nav-stroke, 2px ) solid currentColor;
	border-inline-end: var( --oniti-collection-01-nav-stroke, 2px ) solid currentColor;
	transform: translateX( calc( var( --oniti-collection-01-chevron ) * -0.354 ) )
		rotate( 45deg );
}

/* Le même fichier sert aux deux flèches : « précédent » est le miroir de « suivant ».
   Une icône déjà orientée donne donc la paire juste, sans second réglage. */
.oniti-collection-01__arrow-icon {
	display: inline-flex;
	inline-size: var( --oniti-collection-01-nav-icon-size, 1.1em );
	line-height: 0;
}

/* Sélecteur descendant volontaire : il gagne sur `.oniti-icon__svg`, que porte le SVG
   de l'aperçu de l'éditeur et qui le dimensionnerait à la taille du bloc Icône. */
.oniti-collection-01__arrow-icon svg {
	inline-size: 100%;
	block-size: auto;
	color: inherit;
}

/* Miroir du précédent : la pointe passe à gauche, le recentrage change de signe. */
.oniti-collection-01__arrow--prev .oniti-collection-01__arrow-glyph {
	transform: translateX( calc( var( --oniti-collection-01-chevron ) * 0.354 ) )
		rotate( -135deg );
}

.oniti-collection-01__arrow--prev .oniti-collection-01__arrow-icon {
	scale: -1 1;
}

.oniti-collection-01__dots {
	display: flex;
	align-items: center;
	gap: var( --oniti-collection-01-dots-gap, 0 );
	margin: 0;
	padding: 0;
	list-style: none;
}

/* La pastille visible, au centre d'un bouton plus grand qu'elle. La couleur se pose
   ici, donc `currentColor` la reprend sur ce même pseudo-élément — contrairement au
   bouton, il ne porte aucun fond. */
.oniti-collection-01__dot::before {
	content: "";
	color: var( --oniti-collection-01-nav-glyph, inherit );
	inline-size: var( --oniti-collection-01-dot-size, 0.625rem );
	block-size: var( --oniti-collection-01-dot-size, 0.625rem );
	border: 1px solid currentColor;
	border-radius: 50%;
	background: transparent;
}

.oniti-collection-01__dot[aria-current="true"]::before {
	background: currentColor;
}

/* Flèche en bout de course. `aria-disabled` et non `disabled` : le bouton reste
   focusable, donc l'utilisateur au clavier ne perd pas sa position en arrivant à
   l'extrémité. C'est view.js qui pose l'attribut. */
.oniti-collection-01__arrow[aria-disabled="true"] {
	opacity: var( --oniti-collection-01-nav-disabled-opacity, 0.35 );
	cursor: default;
}

.oniti-collection-01__arrow:focus-visible,
.oniti-collection-01__dot:focus-visible {
	outline: var( --oniti-collection-01-focus-width, 2px ) solid
		var( --oniti-collection-01-focus-color, currentColor );
	outline-offset: var( --oniti-collection-01-focus-offset, 2px );
}

/* ==========================================================================
   5. Éditeur
   ========================================================================== */

/* La navigation y est une maquette inerte : sur le site elle n'apparaît que si le
   contenu déborde, or l'auteur doit voir l'effet de ses réglages en les choisissant. */
.oniti-collection-01__nav--preview {
	pointer-events: none;
	opacity: 0.5;
}

/* Le bouton d'ajout de bloc est un enfant du viewport comme les autres : sans cette
   remise à zéro, il occuperait la largeur d'une carte et se ferait emporter dans une
   colonne du masonry. */
.oniti-collection-01__viewport > .block-list-appender {
	flex: 0 0 auto;
	break-inside: auto;
	margin-block-end: 0;
}
