/* ═════════════════════════════════════════════════════════════════
   Ophtapod : effets visuels partagés
   Chargés sur tout le site, utilisables par n'importe quel modèle.
   Tout est neutralisé sous prefers-reduced-motion et sans JavaScript.

   1. Révélation d'image par masque (.op-reveal)
   2. Parallaxe douce (.op-parallax)
   3. Zoom au survol (.op-zoom)
   4. Cadres d'image (.op-frame et ses variantes)
   5. Placeholder illustré (.op-img-placeholder)
   6. Filet qui se trace (.op-rule)
   ═════════════════════════════════════════════════════════════════ */

/* ── 1. Révélation d'image par masque ─────────────────────────────── */
/* L'image se dévoile du bas vers le haut pendant qu'un léger zoom se
   résorbe : le mouvement vient de l'image elle-même, pas d'un fondu. */

.op-js .op-reveal {
	clip-path: inset(0 0 100% 0);
	transition: clip-path 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

.op-js .op-reveal.is-visible {
	clip-path: inset(0 0 0 0);
}

.op-js .op-reveal img {
	transform: scale(1.12);
	transition: transform 1.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.op-js .op-reveal.is-visible img {
	transform: scale(1);
}

/* Variante : ouverture latérale, pour les images posées en bord de page. */
.op-js .op-reveal--left {
	clip-path: inset(0 100% 0 0);
}

.op-js .op-reveal--left.is-visible {
	clip-path: inset(0 0 0 0);
}

/* ── 2. Parallaxe douce ───────────────────────────────────────────── */
/* Le conteneur masque le débordement, l'image est plus haute que lui et
   se déplace lentement. Le décalage est posé par effets.js. */

.op-parallax {
	position: relative;
	overflow: hidden;
}

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

.op-js .op-parallax--actif img {
	height: 118%;
	will-change: transform;
}

/* ── 3. Zoom au survol ────────────────────────────────────────────── */

.op-zoom {
	overflow: hidden;
}

.op-zoom img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.op-zoom:hover img,
.op-zoom:focus-within img {
	transform: scale(1.06);
}

/* ── 4. Cadres d'image ────────────────────────────────────────────── */
/* Un léger décalage coloré derrière l'image donne de la profondeur sans
   ombre portée, que la charte interdit. */

.op-frame {
	position: relative;
}

.op-frame::before {
	content: '';
	position: absolute;
	inset: 18px -18px -18px 18px;
	background: var(--c-blue-pale);
	z-index: -1;
}

.op-frame--gold::before {
	background: var(--grad-gold);
	opacity: 0.18;
}

.op-frame > * {
	position: relative;
	z-index: 1;
}

/* ── 5. Placeholder illustré ──────────────────────────────────────── */
/* Remplace le rectangle gris quand aucune image n'est encore choisie :
   un dégradé discret et un motif d'iris dessiné en CSS, pour que les
   pages en cours de remplissage ne fassent pas « site inachevé ». */

.op-img-placeholder {
	position: relative;
	display: block;
	width: 100%;
	height: 100%;
	min-height: 180px;
	background:
		radial-gradient(circle at 50% 50%, rgba(222, 172, 23, 0.16) 0%, transparent 42%),
		linear-gradient(140deg, var(--c-blue-pale) 0%, #E2EBEF 100%);
	overflow: hidden;
}

.op-img-placeholder::before,
.op-img-placeholder::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	border-radius: 999px;
	transform: translate(-50%, -50%);
}

/* Iris */
.op-img-placeholder::before {
	width: 84px;
	height: 84px;
	border: 2px solid rgba(21, 39, 63, 0.18);
}

/* Pupille */
.op-img-placeholder::after {
	width: 26px;
	height: 26px;
	background: rgba(21, 39, 63, 0.16);
}

/* ── 6. Filet qui se trace ────────────────────────────────────────── */

.op-rule {
	position: relative;
	height: 1px;
	background: var(--c-gray-light);
}

.op-js .op-rule {
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}

.op-js .op-rule.is-visible {
	transform: scaleX(1);
}

/* ── Neutralisation ───────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	.op-js .op-reveal,
	.op-js .op-reveal--left {
		clip-path: none;
	}
	.op-js .op-reveal img,
	.op-js .op-parallax--actif img {
		transform: none;
		height: 100%;
	}
	.op-zoom:hover img,
	.op-zoom:focus-within img {
		transform: none;
	}
	.op-js .op-rule {
		transform: none;
	}
}

html.op-a11y-reduire-anim .op-reveal,
html.op-a11y-reduire-anim .op-reveal--left {
	clip-path: none !important;
}

html.op-a11y-reduire-anim .op-reveal img,
html.op-a11y-reduire-anim .op-parallax--actif img {
	transform: none !important;
	height: 100% !important;
}

html.op-a11y-reduire-anim .op-rule {
	transform: none !important;
}
