/**
 * Oktimus Offcanvas (content/offcanvas).
 * Two decoupled parts, both wrapped in `.oktimus-offcanvas`:
 *  - the TRIGGER (block `oktimus/offcanvas` or a Block link) → `.oktimus-offcanvas__trigger`
 *    / burger; the view-script adds `is-open` to its wrapper (burger morph);
 *  - the DRAWER (CPT `oktoffcanvas`, rendered once in the footer) → a native
 *    `<dialog class="oktimus-offcanvas__panel" id="oktimus-offcanvas-<id>">` opened via
 *    showModal() → top layer (native focus trap, Esc, background inert and ::backdrop).
 * A closed <dialog> is `display:none`, so its content stays out of tab order / AT.
 * Closing is a Block link inside the content (`data-okt-offcanvas-close`), the backdrop
 * or Esc.
 */

.oktimus-offcanvas {
	display: inline-block;
}

/* Le bouton EST la racine du bloc : les couleurs / bordure / rayon / marges / typo
   viennent des supports natifs (réglages du bloc). Aucun style imposé par défaut —
   juste la mise en flex icône↔label + le gap réglable. */
.oktimus-offcanvas__trigger {
	display: inline-flex;
	align-items: center;
	gap: var( --okt-oc-gap, 0.5em );
	padding: 0;
	font: inherit;
	color: inherit;
	cursor: pointer;
	background: none;
	border: 0;
}

/* Alignement du bloc (support align) : le bouton étant en ligne, on le centre /
   pousse via une marge auto plutôt que par un float. */
.oktimus-offcanvas__trigger.aligncenter {
	display: flex;
	width: fit-content;
	margin-inline: auto;
}

.oktimus-offcanvas__trigger.alignright {
	display: flex;
	width: fit-content;
	margin-inline-start: auto;
}

.oktimus-offcanvas__trigger.alignleft {
	display: flex;
	width: fit-content;
	margin-inline-end: auto;
}

.oktimus-offcanvas__icon {
	display: block;
}

/* Dimensionne le SVG du déclencheur. Les icônes du registre (sets par défaut /
   marques / bibliothèque) et les SVG collés n'ont qu'un `viewBox` (pas de
   `width`/`height`) : sans taille explicite, un SVG en conteneur flex se réduit à
   zéro et l'icône disparaît. 1.5em = même gabarit que le burger animé. */
.oktimus-offcanvas__icon svg {
	display: block;
	width: 1.5em;
	height: 1.5em;
}

/* Position du texte par rapport à l'icône (gauche / droite / dessous). */
.oktimus-offcanvas__trigger.is-label-right {
	flex-direction: row;
}

.oktimus-offcanvas__trigger.is-label-left {
	flex-direction: row-reverse;
}

.oktimus-offcanvas__trigger.is-label-below {
	flex-direction: column;
}

/* Burger animé : 3 barres qui se transforment en ✕ quand `.is-open` est posée
   sur la racine (par le store IAPI). Identique éditeur/front. */
.oktimus-offcanvas__burger {
	position: relative;
	display: inline-block;
	flex: none;
	width: 1.5em;
	height: 1.5em;
	color: inherit;
}

.oktimus-offcanvas__burger > span {
	position: absolute;
	right: 15%;
	left: 15%;
	height: 0.125em;
	margin-top: -0.0625em;
	background: currentColor;
	border-radius: 2px;
	transition: top 0.3s ease, transform 0.3s ease, opacity 0.2s ease;
}

.oktimus-offcanvas__burger > span:nth-child( 1 ) {
	top: 30%;
}

.oktimus-offcanvas__burger > span:nth-child( 2 ) {
	top: 50%;
}

.oktimus-offcanvas__burger > span:nth-child( 3 ) {
	top: 70%;
}

/* squeeze (défaut) — les barres externes se croisent, la médiane s'efface. */
.oktimus-offcanvas__trigger.is-open .is-anim-squeeze > span:nth-child( 1 ) {
	top: 50%;
	transform: rotate( 45deg );
}
.oktimus-offcanvas__trigger.is-open .is-anim-squeeze > span:nth-child( 2 ) {
	opacity: 0;
}
.oktimus-offcanvas__trigger.is-open .is-anim-squeeze > span:nth-child( 3 ) {
	top: 50%;
	transform: rotate( -45deg );
}

/* spin — l'icône pivote de 180° en se croisant. */
.oktimus-offcanvas__burger.is-anim-spin {
	transition: transform 0.4s ease;
}
.oktimus-offcanvas__trigger.is-open .is-anim-spin {
	transform: rotate( 180deg );
}
.oktimus-offcanvas__trigger.is-open .is-anim-spin > span:nth-child( 1 ) {
	top: 50%;
	transform: rotate( 45deg );
}
.oktimus-offcanvas__trigger.is-open .is-anim-spin > span:nth-child( 2 ) {
	opacity: 0;
}
.oktimus-offcanvas__trigger.is-open .is-anim-spin > span:nth-child( 3 ) {
	top: 50%;
	transform: rotate( -45deg );
}

/* elastic — croisement avec rebond (easing à dépassement). */
.oktimus-offcanvas__burger.is-anim-elastic > span {
	transition-timing-function: cubic-bezier( 0.68, -0.55, 0.27, 1.55 );
}
.oktimus-offcanvas__trigger.is-open .is-anim-elastic > span:nth-child( 1 ) {
	top: 50%;
	transform: rotate( 135deg );
}
.oktimus-offcanvas__trigger.is-open .is-anim-elastic > span:nth-child( 2 ) {
	opacity: 0;
	transform: scale( 0 );
}
.oktimus-offcanvas__trigger.is-open .is-anim-elastic > span:nth-child( 3 ) {
	top: 50%;
	transform: rotate( -135deg );
}

/* collapse — les barres externes rejoignent le centre, puis se croisent. */
.oktimus-offcanvas__burger.is-anim-collapse > span {
	transition: top 0.2s ease 0.2s, transform 0.2s ease, opacity 0.15s ease;
}
.oktimus-offcanvas__trigger.is-open .is-anim-collapse > span {
	transition: top 0.2s ease, transform 0.2s ease 0.2s, opacity 0.15s ease;
}
.oktimus-offcanvas__trigger.is-open .is-anim-collapse > span:nth-child( 1 ) {
	top: 50%;
	transform: rotate( 45deg );
}
.oktimus-offcanvas__trigger.is-open .is-anim-collapse > span:nth-child( 2 ) {
	opacity: 0;
}
.oktimus-offcanvas__trigger.is-open .is-anim-collapse > span:nth-child( 3 ) {
	top: 50%;
	transform: rotate( -45deg );
}

/* slant — croisement pendant que la barre médiane glisse hors champ. */
.oktimus-offcanvas__trigger.is-open .is-anim-slant > span:nth-child( 1 ) {
	top: 50%;
	transform: rotate( 45deg );
}
.oktimus-offcanvas__trigger.is-open .is-anim-slant > span:nth-child( 2 ) {
	opacity: 0;
	transform: translateX( 100% );
}
.oktimus-offcanvas__trigger.is-open .is-anim-slant > span:nth-child( 3 ) {
	top: 50%;
	transform: rotate( -45deg );
}

/* arrow — se mue en flèche gauche (la médiane = la hampe). */
.oktimus-offcanvas__trigger.is-open .is-anim-arrow > span:nth-child( 1 ) {
	top: 50%;
	transform-origin: left center;
	transform: rotate( 45deg ) scaleX( 0.55 );
}
.oktimus-offcanvas__trigger.is-open .is-anim-arrow > span:nth-child( 3 ) {
	top: 50%;
	transform-origin: left center;
	transform: rotate( -45deg ) scaleX( 0.55 );
}

/* Panneau = `<dialog>` natif, ouvert via showModal() → rendu dans le TOP LAYER :
   insensible aux `transform`/`will-change`/`contain` des ancêtres (sinon le
   `position:fixed` serait capturé, ex. par l'animation « auto-entrance »). État
   ouvert = attribut natif `[open]` ; arrière-plan = `::backdrop` (plus d'overlay). */
.oktimus-offcanvas__panel {
	position: fixed;
	z-index: 99999;
	max-width: 100%;
	max-height: 100%;
	margin: 0;
	padding: 0;
	overflow: auto;
	/* Distance de glissement « hors champ » par côté = 100 % (propre largeur/hauteur)
	   + la marge externe de ce côté, pour que le tiroir se cache ENTIÈREMENT même
	   détaché des bords (sinon un liseré de la largeur de la marge resterait visible
	   pendant l'animation). Marges à 0 (défaut) → calc(100% + 0px) = 100 %, comportement
	   d'origine strictement préservé. */
	--okt-oc-slide-right: calc( 100% + var( --okt-offcanvas-m-right, 0px ) );
	--okt-oc-slide-left: calc( -100% - var( --okt-offcanvas-m-left, 0px ) );
	--okt-oc-slide-top: calc( -100% - var( --okt-offcanvas-m-top, 0px ) );
	--okt-oc-slide-bottom: calc( 100% + var( --okt-offcanvas-m-bottom, 0px ) );
	/* Couleurs par défaut du tiroir : surcharge d'instance (--okt-offcanvas-fg/bg,
	   réglages du CPT) sinon palette du thème. */
	color: var( --okt-offcanvas-fg, var( --wp--preset--color--contrast, inherit ) );
	background: var( --okt-offcanvas-bg, var( --wp--preset--color--base, #fff ) );
	/* Bordure du panneau (panneau natif BorderBoxControl) : 4 côtés résolus par PHP
	   (Render::markup) en shorthand complet, chacun avec son propre fallback « 0 »
	   (pas de bordure) — pas de cascade de var() à plusieurs niveaux. */
	border-top: var( --okt-offcanvas-border-top, 0 );
	border-right: var( --okt-offcanvas-border-right, 0 );
	border-bottom: var( --okt-offcanvas-border-bottom, 0 );
	border-left: var( --okt-offcanvas-border-left, 0 );
	border-radius: var( --okt-offcanvas-border-radius, 0 );
	box-shadow: var( --okt-offcanvas-shadow, 0 0 40px rgba( 0, 0, 0, 0.2 ) );
	/* On anime `transform` ; `display`/`overlay` en discret pour que le panneau
	   RESTE rendu (top layer) pendant le glissement de SORTIE. */
	transition: transform var( --okt-offcanvas-dur, 0.3s ) ease,
		opacity var( --okt-offcanvas-dur, 0.3s ) ease,
		display var( --okt-offcanvas-dur, 0.3s ) allow-discrete,
		overlay var( --okt-offcanvas-dur, 0.3s ) allow-discrete;
}

/* Position fermée (hors champ), par côté — sert d'état de SORTIE. Les marges externes
   (`--okt-offcanvas-m-*`, défaut 0px) sont intégrées à l'`inset` : le tiroir se détache
   alors des bords de l'écran (effet « carte flottante »). */
.oktimus-offcanvas.is-side-right .oktimus-offcanvas__panel {
	inset: var( --okt-offcanvas-m-top, 0px ) var( --okt-offcanvas-m-right, 0px )
		var( --okt-offcanvas-m-bottom, 0px ) auto;
	width: var( --okt-offcanvas-width, min( 400px, 90vw ) );
	transform: translateX( var( --okt-oc-slide-right ) );
}

.oktimus-offcanvas.is-side-left .oktimus-offcanvas__panel {
	inset: var( --okt-offcanvas-m-top, 0px ) auto
		var( --okt-offcanvas-m-bottom, 0px ) var( --okt-offcanvas-m-left, 0px );
	width: var( --okt-offcanvas-width, min( 400px, 90vw ) );
	transform: translateX( var( --okt-oc-slide-left ) );
}

.oktimus-offcanvas.is-side-top .oktimus-offcanvas__panel {
	inset: var( --okt-offcanvas-m-top, 0px ) var( --okt-offcanvas-m-right, 0px )
		auto var( --okt-offcanvas-m-left, 0px );
	width: auto;
	max-height: 85vh;
	transform: translateY( var( --okt-oc-slide-top ) );
}

.oktimus-offcanvas.is-side-bottom .oktimus-offcanvas__panel {
	inset: auto var( --okt-offcanvas-m-right, 0px )
		var( --okt-offcanvas-m-bottom, 0px ) var( --okt-offcanvas-m-left, 0px );
	width: auto;
	max-height: 85vh;
	transform: translateY( var( --okt-oc-slide-bottom ) );
}

/* Tiroirs latéraux (gauche/droite) : pleine hauteur, étirée par l'`inset` haut+bas
   (marges incluses). `height:auto` (au lieu de 100%) est nécessaire pour surpasser le
   `height:fit-content` UA du <dialog> ET laisser haut+bas définir la hauteur — sinon un
   contenu court ne remplit pas la hauteur. Haut/bas restent en hauteur de contenu. */
.oktimus-offcanvas.is-side-left .oktimus-offcanvas__panel,
.oktimus-offcanvas.is-side-right .oktimus-offcanvas__panel {
	height: auto;
}

/* Ouvert : en place. Sélecteurs PAR CÔTÉ pour surpasser la spécificité de la
   position fermée `.is-side-*` (sinon le panneau resterait hors champ). */
.oktimus-offcanvas.is-side-right .oktimus-offcanvas__panel[ open ],
.oktimus-offcanvas.is-side-left .oktimus-offcanvas__panel[ open ],
.oktimus-offcanvas.is-side-top .oktimus-offcanvas__panel[ open ],
.oktimus-offcanvas.is-side-bottom .oktimus-offcanvas__panel[ open ] {
	transform: none;
}

/* Entrée : partir hors champ (par côté, marge externe incluse) → glisse vers
   `transform:none`. Mêmes vars de glissement que l'état fermé (sinon l'entrée d'un
   tiroir détaché démarrerait avec un liseré déjà visible). */
@starting-style {
	.oktimus-offcanvas.is-side-right .oktimus-offcanvas__panel[ open ] {
		transform: translateX( var( --okt-oc-slide-right ) );
	}
	.oktimus-offcanvas.is-side-left .oktimus-offcanvas__panel[ open ] {
		transform: translateX( var( --okt-oc-slide-left ) );
	}
	.oktimus-offcanvas.is-side-top .oktimus-offcanvas__panel[ open ] {
		transform: translateY( var( --okt-oc-slide-top ) );
	}
	.oktimus-offcanvas.is-side-bottom .oktimus-offcanvas__panel[ open ] {
		transform: translateY( var( --okt-oc-slide-bottom ) );
	}
}

/* Voile = `::backdrop` natif du <dialog> (top layer). Le déclencheur reste en
   empilement NORMAL, donc sous le voile. Couleur + opacité réglables (vars), défaut
   clair (noir 35 %) pour que le bouton reste perceptible. Le backdrop capte aussi
   le clic « hors panneau » (→ fermeture, view.js). Fondu via `@starting-style`. */
.oktimus-offcanvas__panel::backdrop {
	background: color-mix(
		in srgb,
		var( --okt-offcanvas-overlay-color, #000 )
			calc( var( --okt-offcanvas-overlay-op, 0.35 ) * 100% ),
		transparent
	);
	opacity: 0;
	transition: opacity var( --okt-offcanvas-dur, 0.3s ) ease,
		display var( --okt-offcanvas-dur, 0.3s ) allow-discrete,
		overlay var( --okt-offcanvas-dur, 0.3s ) allow-discrete;
}

.oktimus-offcanvas__panel[ open ]::backdrop {
	opacity: 1;
}

@starting-style {
	.oktimus-offcanvas__panel[ open ]::backdrop {
		opacity: 0;
	}
}

/* Flou du voile (verre dépoli), activé seulement si un flou est réglé (has-okt-blur)
   → évite le coût de compositing du filtre quand il n'est pas voulu. */
.oktimus-offcanvas.has-okt-blur .oktimus-offcanvas__panel::backdrop {
	backdrop-filter: blur( var( --okt-offcanvas-overlay-blur, 0 ) );
	-webkit-backdrop-filter: blur( var( --okt-offcanvas-overlay-blur, 0 ) );
}

/* Effet « fade » : le panneau apparaît en fondu (sans glisser). Placé APRÈS les
   transforms par côté pour les neutraliser (source order, spécificité égale). */
.oktimus-offcanvas.is-effect-fade .oktimus-offcanvas__panel {
	transform: none;
	opacity: 0;
}
.oktimus-offcanvas.is-effect-fade .oktimus-offcanvas__panel[ open ] {
	opacity: 1;
}
@starting-style {
	.oktimus-offcanvas.is-effect-fade .oktimus-offcanvas__panel[ open ] {
		opacity: 0;
	}
}

/* Effet « push » : la page se décale pour laisser place au tiroir (qui glisse
   comme « slide »). Le décalage (--okt-push-x/y) et la durée sont posés sur le
   <body> par view.js à l'ouverture. Le panneau (top layer) n'est pas décalé. */
body.oktimus-offcanvas-push > *:not( script ):not( style ) {
	transform: translate( var( --okt-push-x, 0 ), var( --okt-push-y, 0 ) );
	transition: transform var( --okt-push-dur, 0.3s ) ease;
}

/* Déclencheur flottant (FAB) : le bloc se fixe dans un coin de l'écran. */
.oktimus-offcanvas__trigger.is-floating {
	position: fixed;
	z-index: 9999;
}
.oktimus-offcanvas__trigger.is-floating.is-float-bottom-right {
	right: 1rem;
	bottom: 1rem;
}
.oktimus-offcanvas__trigger.is-floating.is-float-bottom-left {
	left: 1rem;
	bottom: 1rem;
}
.oktimus-offcanvas__trigger.is-floating.is-float-top-right {
	right: 1rem;
	top: 1rem;
}
.oktimus-offcanvas__trigger.is-floating.is-float-top-left {
	left: 1rem;
	top: 1rem;
}

/* Marges internes (padding) du contenu : réglables par côté (panneau natif
   Dimensions → vars posées par Render), chacune retombant sur le défaut historique
   (large) quand elle n'est pas réglée. Régler un côté à 0 est donc bien pris en compte. */
/* Conteneur de requête sans réglage : les seuils « Conteneur » de la Visibilité
   responsive (`@container`) mesurent la largeur du tiroir, pas celle de l'écran. */
.oktimus-offcanvas__content {
	container-type: inline-size;
	padding-top: var(
		--okt-offcanvas-pad-top,
		var( --wp--preset--spacing--large, 2rem )
	);
	padding-right: var(
		--okt-offcanvas-pad-right,
		var( --wp--preset--spacing--large, 2rem )
	);
	padding-bottom: var(
		--okt-offcanvas-pad-bottom,
		var( --wp--preset--spacing--large, 2rem )
	);
	padding-left: var(
		--okt-offcanvas-pad-left,
		var( --wp--preset--spacing--large, 2rem )
	);
}

/* Tiroirs latéraux : le contenu occupe toute la hauteur du panneau (colonne flex).
   Sans cela il est dimensionné par son contenu : pas de pied collé en bas, hauteurs
   en % mortes sur les blocs racine. Les blocs racine gardent leur hauteur de contenu ;
   l'espace libre va au bloc racine UNIQUE, ou à celui portant `okt-oc-fill`. Le
   panneau a une hauteur définie (inset haut+bas) ; haut/bas gardent la hauteur de leur
   contenu, donc ne sont pas concernés (aucun risque pour les flottants à la racine). */
.oktimus-offcanvas.is-side-left .oktimus-offcanvas__content,
.oktimus-offcanvas.is-side-right .oktimus-offcanvas__content {
	box-sizing: border-box; /* le padding du tiroir est COMPRIS dans les 100 %. */
	display: flex;
	flex-direction: column;
	min-height: 100%;
}

.oktimus-offcanvas.is-side-left .oktimus-offcanvas__content > *,
.oktimus-offcanvas.is-side-right .oktimus-offcanvas__content > * {
	flex: 0 0 auto;
}

.oktimus-offcanvas.is-side-left .oktimus-offcanvas__content > :only-child,
.oktimus-offcanvas.is-side-right .oktimus-offcanvas__content > :only-child,
.oktimus-offcanvas__content > .okt-oc-fill {
	flex: 1 1 auto;
	min-height: 0;
}

/* Colle un bloc en bas de la colonne qui le contient (marge `auto` = 0 hors flex). */
.oktimus-offcanvas__content .okt-oc-bottom {
	margin-top: auto;
}

/* Couleur de lien du tiroir — appliquée seulement si une couleur est réglée
   (classe has-okt-link), pour ne pas écraser la couleur de lien du thème. */
.oktimus-offcanvas.has-okt-link .oktimus-offcanvas__content a {
	color: var( --okt-offcanvas-link );
}

/* Bouton d'édition (crayon) — révélé au survol/focus du panneau, réservé aux
   utilisateurs autorisés (rendu serveur conditionnel). Coin haut-gauche pour ne pas
   gêner un bouton de fermeture placé en haut-droite dans le contenu. */
.oktimus-offcanvas__edit {
	position: absolute;
	top: 0.5rem;
	left: 0.5rem;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	color: inherit;
	background: rgba( 0, 0, 0, 0.06 );
	border-radius: 50%;
	opacity: 0;
	transition: opacity 0.15s ease;
	pointer-events: none;
}

.oktimus-offcanvas__panel:hover .oktimus-offcanvas__edit,
.oktimus-offcanvas__panel:focus-within .oktimus-offcanvas__edit {
	opacity: 1;
	pointer-events: auto;
}

@media ( prefers-reduced-motion: reduce ) {
	.oktimus-offcanvas__edit {
		transition: none;
	}
}

.oktimus-offcanvas__close {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	color: inherit;
	cursor: pointer;
	background: transparent;
	border: 0;
	border-radius: 50%;
	transition: background 0.15s ease;
}

.oktimus-offcanvas__close:hover,
.oktimus-offcanvas__close:focus-visible {
	background: rgba( 0, 0, 0, 0.08 );
}

/* Verrou de défilement pendant l'ouverture. On réserve la gouttière de scrollbar
   EN AMONT (uniquement sur les pages qui utilisent réellement le bloc), pour que
   masquer la scrollbar à l'ouverture ne décale pas la page horizontalement. */
html:has( .oktimus-offcanvas ) {
	scrollbar-gutter: stable;
}

body.oktimus-offcanvas-open {
	overflow: hidden;
}

@media ( prefers-reduced-motion: reduce ) {
	.oktimus-offcanvas__panel,
	.oktimus-offcanvas__panel::backdrop,
	.oktimus-offcanvas__burger,
	.oktimus-offcanvas__burger > span,
	.oktimus-offcanvas__close,
	body.oktimus-offcanvas-push > *:not( script ):not( style ) {
		transition: none;
	}
}

