/* ==========================================================================
   Easy Key Access : accueil en mouvement
   Hero en couches + scène pinnée « deux façons d'ouvrir ».
   Méthode ScrollCraft : un seul scroll pilote des variables CSS (--hp, --a, --o, --m),
   tout le reste est du transform/opacity. Aucun JS = composition finale statique.
   ========================================================================== */

:root {
  --ease-out: cubic-bezier(.23, 1, .32, 1);
  --navy-ink: #04101a;
}

/* ---------------------------------------------------------------- HERO --- */
.hero--depth {
  --hp: 0; --px: 0; --py: 0;
  min-height: min(calc(100svh - 72px), 860px);
  display: flex; align-items: center;
  padding: clamp(40px, 6vw, 72px) 0 clamp(56px, 7vw, 88px);
  isolation: isolate;
}
.hero--depth .container {
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(16px, 3vw, 48px); align-items: center;
}
.hero--depth h1 { font-size: clamp(2rem, 4vw, 3.25rem); line-height: 1.06; letter-spacing: -.03em; text-wrap: balance; }
.hero--depth .lead { max-width: 30em; text-wrap: pretty; }
.hero--depth .hero-cta { margin-bottom: 0; }

.hd-copy > * { animation: hd-rise .8s var(--ease-out) both; }
.hd-copy > :nth-child(2) { animation-delay: .06s; }
.hd-copy > :nth-child(3) { animation-delay: .12s; }
.hd-copy > :nth-child(4) { animation-delay: .18s; }
@keyframes hd-rise { from { opacity: 0; translate: 0 18px; } to { opacity: 1; translate: 0 0; } }

/* ======================================================================================
   HERO : « Deux façons d'ouvrir ». Une scène par produit (S50 puis S5), jouée à l'arrivée,
   qui bascule d'elle-même ; les onglets permettent de choisir.
   Tout se mesure en cqw dans un « rig » (la serrure et son outil) : le geste tombe juste à toutes les tailles.
   Les états de base sont les états FINAUX ; les animations viennent de « from », donc sans mouvement
   (ou sans JS) on voit directement la scène terminée.
   ====================================================================================== */
.hs-wrap { position: relative; min-width: 0; }
.hs { position: relative; width: min(100%, calc((100svh - 250px) * 1.08)); aspect-ratio: 100 / 92; margin-inline: auto; container-type: inline-size; }
.hs > * { position: absolute; }
.hs-L { position: absolute; inset: 0; will-change: transform; pointer-events: none; }
.hs-L > * { position: absolute; }
.hs-L0 { transform: translate3d(calc(var(--px) * 6px), calc(var(--hp) * -22px + var(--py) * 4px), 0); }
.hs-L1 { transform: translate3d(calc(var(--px) * -12px), calc(var(--hp) * -46px + var(--py) * -8px), 0); }
.hs-L3 { transform: translate3d(calc(var(--px) * -24px), calc(var(--hp) * -84px + var(--py) * -14px), 0); }

/* décor commun */
.hs-halo { inset: -8% -12% -4% -4%; border-radius: 50%; background: radial-gradient(closest-side, rgba(41, 182, 227, .30), rgba(41, 182, 227, .08) 58%, transparent 74%); animation: hs-breathe 9s ease-in-out infinite alternate; }
@keyframes hs-breathe { from { scale: 1; opacity: .85; } to { scale: 1.07; opacity: 1; } }
.hs-dust { inset: -50% 0 auto 0; height: 200%; opacity: .4; animation: hs-dust 46s linear infinite;
  background-image: radial-gradient(circle, rgba(255, 255, 255, .8) 0 1px, transparent 1.6px), radial-gradient(circle, rgba(120, 214, 245, .7) 0 1.2px, transparent 2px);
  background-size: 96px 120px, 163px 190px; background-position: 0 0, 40px 60px;
  -webkit-mask-image: radial-gradient(closest-side at 50% 50%, #000 20%, transparent 80%); mask-image: radial-gradient(closest-side at 50% 50%, #000 20%, transparent 80%); }
@keyframes hs-dust { to { translate: 0 -25%; } }
.hs-floor { left: 6%; right: 2%; bottom: 8%; height: 14%; background: radial-gradient(closest-side, rgba(2, 10, 18, .6), transparent 78%); }

.hs-kick { left: 2%; top: 1.5%; height: 1.4em; font-size: clamp(.7rem, 2.1cqw, .82rem); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--teal); pointer-events: none; }
.hs-kick span { position: absolute; left: 0; top: 0; white-space: nowrap; opacity: 0; translate: 0 6px; transition: opacity .5s var(--ease-out), translate .5s var(--ease-out); }
.hs-kick span.is-on { opacity: 1; translate: 0 0; }

/* scènes */
.hs-scene { inset: 0; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .55s ease, visibility 0s .55s; }
.hs-scene.is-active { opacity: 1; visibility: visible; transition-delay: 0s; }

/* le rig : serrure + outil, tout en cqw du rig */
.hs-rig { position: absolute; container-type: inline-size; }
.hs-rig--s50 { left: 17%; top: 15%; width: 82%; aspect-ratio: 1100 / 874; }
.hs-rig--s5 { left: 16%; top: 24%; width: 82%; aspect-ratio: 894 / 600; }
.hs-lock { position: absolute; inset: 0; z-index: 1; }
.hs-lock img { display: block; width: 100%; height: auto; max-width: none; filter: drop-shadow(0 3cqw 3.4cqw rgba(2, 10, 18, .55)); }
.hs-glow { position: absolute; inset: -10% -8%; z-index: 0; border-radius: 50%; background: radial-gradient(closest-side, rgba(41, 182, 227, .38), rgba(41, 182, 227, .1) 60%, transparent 76%); }

/* reflet qui balaie le produit : le masque est la silhouette du produit elle-même */
.hs-lock::after, .hs-phone::after { content: ""; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: soft-light;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .95) 50%, transparent 62%) no-repeat; background-size: 280% 100%; background-position: 130% 0;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.hs-rig--s50 .hs-lock::after { -webkit-mask-image: url(../img/home/s50-cylindre-porte.webp); mask-image: url(../img/home/s50-cylindre-porte.webp); }
.hs-rig--s5 .hs-lock::after { -webkit-mask-image: url(../img/home/s5-cylindre-porte.webp); mask-image: url(../img/home/s5-cylindre-porte.webp); }
.hs-phone::after { -webkit-mask-image: url(../img/home/s50-telephone.webp); mask-image: url(../img/home/s50-telephone.webp); }
@keyframes hs-glint { 0%, 8% { background-position: 130% 0; } 38%, 100% { background-position: -30% 0; } }

/* ondes d'ouverture au point de contact */
.hs-ripple { position: absolute; z-index: 3; width: 30cqw; aspect-ratio: 1; margin: -15cqw 0 0 -15cqw; border-radius: 50%; border: 2px solid rgba(95, 210, 245, .95); opacity: 0; scale: .2; pointer-events: none; }
.hs-rig--s50 .hs-ripple { left: 17%; top: 70%; }
.hs-rig--s5 .hs-ripple { left: 11%; top: 80%; }

/* ----------------------------- S50 : le smartphone arrive et la serrure s'ouvre */
.hs-phone { position: absolute; z-index: 2; left: 0; top: 0; height: 64cqw; aspect-ratio: 620 / 1232; translate: -19cqw 13cqw; rotate: -4deg; }
.hs-phone > img { display: block; width: 100%; height: 100%; max-width: none; filter: drop-shadow(0 2.6cqw 3cqw rgba(0, 0, 0, .55)); }
.hs-ok { position: absolute; left: 49.1%; top: 44.5%; width: 60%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 35% 30%, #6bbf6a, #3f8f4e 70%); box-shadow: 0 0 0 .8cqw rgba(255, 255, 255, .18), 0 1.4cqw 3cqw rgba(20, 70, 30, .45); }
.hs-ok svg { width: 52%; height: 52%; color: #fff; }
.hs-nfc { position: absolute; z-index: 3; left: 14cqw; top: 26cqw; width: 12cqw; height: auto; overflow: visible; }
.hs-nfc path { fill: none; stroke: var(--teal); stroke-width: 3.6; stroke-linecap: round; opacity: .55; }

/* ----------------------------- S5 : la clé s'engage dans le trou, la lame disparaît dans la serrure */
.hs-keyclip { position: absolute; inset: 0; z-index: 2; pointer-events: none; clip-path: polygon(-78.4% -186.4%, 100.4% 346.5%, -167.6% 546.2%, -346.4% 13.3%); }
.hs-key { position: absolute; left: 0; top: 0; max-width: none; height: 44cqw; width: auto; translate: -4.7cqw 35.1cqw; rotate: -116.6deg; transform-origin: 50% 50%; filter: drop-shadow(0 2.4cqw 2.6cqw rgba(0, 0, 0, .55)); }

/* ----------------------------- couche avant : photo réelle + état */
.hs-inset { margin: 0; right: 2%; bottom: 6%; width: 26%; aspect-ratio: 4 / 5; border-radius: 1.8cqw; overflow: hidden; rotate: 3deg;
  border: 1px solid rgba(255, 255, 255, .22); box-shadow: 0 2.4cqw 4.6cqw -1.2cqw rgba(0, 0, 0, .7); }
.hs-inset img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hs-pill { left: 2%; bottom: 2.5%; display: block; height: 11.4cqw; min-width: 36cqw; font-weight: 700; font-size: clamp(.78rem, 2.5cqw, .95rem); }
.hs-pill > span { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 1.6cqw; padding: 0 3.4cqw; border-radius: 999px; white-space: nowrap; }
.hs-pill .off { background: rgba(255, 255, 255, .09); color: var(--slate-100); border: 1px solid rgba(255, 255, 255, .2); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); opacity: 0; }
.hs-pill .on { background: var(--white); color: var(--navy-900); box-shadow: 0 1.8cqw 4cqw -1.2cqw rgba(0, 0, 0, .6); }
.hs-pill svg { width: 1.2em; height: 1.2em; flex: none; }
.hs-pill .on svg { color: #12907f; }
.hs-pill-sizer { visibility: hidden; padding: 0 3.4cqw; white-space: nowrap; }

/* ----------------------------- chorégraphie (JOUÉE : seulement dans la scène active) */
@media (prefers-reduced-motion: no-preference) {
  .hs-scene.is-active .hs-lock { animation: hs-lock-in .9s .02s var(--ease-out) both, hs-click .55s var(--t-open, 2s) var(--ease-out) both; }
  .hs-scene.is-active .hs-lock::after, .hs-scene.is-active .hs-phone::after { animation: hs-glint 2.6s var(--t-glint, 1s) ease-in-out both; }
  .hs-scene.is-active .hs-glow { animation: hs-glow-in .9s var(--t-open, 2s) ease-out both; }
  .hs-scene.is-active .hs-ripple { animation: hs-ripple 1.2s var(--t-open, 2s) var(--ease-out) forwards; }
  .hs-scene.is-active .hs-ripple--2 { animation-delay: calc(var(--t-open, 2s) + .2s); }
  .hs-scene.is-active .hs-pill .off { animation: hs-off 1.2s calc(var(--t-open, 2s) - .95s) ease both; }
  .hs-scene.is-active .hs-pill .on { animation: hs-on .6s var(--t-open, 2s) var(--ease-out) both; }
  .hs-scene.is-active .hs-inset { animation: hs-inset-in .8s calc(var(--t-open, 2s) + .35s) var(--ease-out) both; }

  .hs-scene--s50.is-active .hs-phone { animation: hs-phone-in 1.1s .15s cubic-bezier(.2, .9, .2, 1) both, hs-float 6s 2s ease-in-out infinite alternate; }
  .hs-scene--s50.is-active .hs-ok { animation: hs-ok-in .55s var(--t-open, 2s) var(--ease-out) both; }
  .hs-scene--s50.is-active .hs-nfc path { animation: hs-wave 1.5s calc(var(--t-open, 2s) - .45s) ease-in-out 2 both; }
  .hs-scene--s50.is-active .hs-nfc path:nth-child(2) { animation-delay: calc(var(--t-open, 2s) - .27s); }
  .hs-scene--s50.is-active .hs-nfc path:nth-child(3) { animation-delay: calc(var(--t-open, 2s) - .09s); }
  .hs-scene--s5.is-active .hs-key { animation: hs-key-in 1.8s .25s both; }
  .hs-scene--s5.is-active .hs-lock { animation-name: hs-lock-in-r, hs-click; }
}
.hs-scene--s50 { --t-open: 1.4s; --t-glint: .7s; }
.hs-scene--s5 { --t-open: 2.1s; --t-glint: 1s; }

@keyframes hs-lock-in { from { opacity: 0; translate: 0 5cqw; filter: blur(10px); } to { opacity: 1; translate: 0 0; filter: blur(0); } }
@keyframes hs-lock-in-r { from { opacity: 0; translate: 6cqw 0; filter: blur(10px); } to { opacity: 1; translate: 0 0; filter: blur(0); } }
@keyframes hs-click { 0% { scale: 1; } 35% { scale: 1.03; } 100% { scale: 1; } }
@keyframes hs-glow-in { from { opacity: 0; scale: .8; } to { opacity: 1; scale: 1; } }
@keyframes hs-ripple { 0% { opacity: .95; scale: .2; } 100% { opacity: 0; scale: 2.4; } }
@keyframes hs-off { 0% { opacity: 0; translate: 0 10px; } 22%, 78% { opacity: 1; translate: 0 0; } 100% { opacity: 0; translate: 0 0; } }
@keyframes hs-on { 0% { opacity: 0; scale: .86; } 45% { opacity: 1; scale: 1.08; } 100% { opacity: 1; scale: 1; } }
@keyframes hs-inset-in { from { opacity: 0; translate: 0 5cqw; rotate: 9deg; scale: .9; } to { opacity: 1; translate: 0 0; rotate: 3deg; scale: 1; } }
@keyframes hs-phone-in { 0% { opacity: 0; translate: -36cqw 30cqw; rotate: -20deg; scale: .9; } 35% { opacity: 1; } 100% { opacity: 1; translate: -19cqw 13cqw; rotate: -4deg; scale: 1; } }
@keyframes hs-float { from { transform: translateY(0) rotate(0); } to { transform: translateY(-1.6cqw) rotate(.7deg); } }
@keyframes hs-ok-in { 0% { opacity: 0; scale: .4; } 60% { opacity: 1; scale: 1.12; } 100% { opacity: 1; scale: 1; } }
@keyframes hs-wave { 0% { opacity: 0; } 40% { opacity: 1; } 100% { opacity: .5; } }
@keyframes hs-key-in {
  0%   { opacity: 0; translate: -19cqw 58cqw; rotate: -82deg; animation-timing-function: cubic-bezier(.2, .8, .3, 1); }
  26%  { opacity: 1; }
  52%  { opacity: 1; translate: -24cqw 45cqw; rotate: -113deg; animation-timing-function: ease-in-out; }
  74%  { translate: -17.2cqw 41.4cqw; rotate: -116.6deg; animation-timing-function: ease-in; }
  88%  { translate: -9.2cqw 37.3cqw; rotate: -116.6deg; animation-timing-function: cubic-bezier(.3, 0, .2, 1); }
  100% { opacity: 1; translate: -4.7cqw 35.1cqw; rotate: -116.6deg; }
}

/* onglets */
.hs-tabs { display: flex; align-items: stretch; gap: 10px; width: min(100%, calc((100svh - 250px) * 1.08)); margin: 14px auto 0; }
.hs-tab { flex: 1 1 0; min-width: 0; position: relative; display: flex; flex-direction: column; gap: 9px; padding: 10px 4px 0; background: none; border: 0; cursor: pointer; text-align: left; color: var(--slate-300); font: inherit; font-weight: 700; font-size: .92rem; transition: color .25s; }
.hs-tab small { display: block; font-weight: 500; font-size: .8rem; color: var(--slate-500); transition: color .25s; }
.hs-tab .bar { order: -1; display: block; height: 3px; border-radius: 3px; background: rgba(255, 255, 255, .16); overflow: hidden; }
.hs-tab .bar i { display: block; height: 100%; background: var(--teal); transform-origin: 0 50%; transform: scaleX(0); }
.hs-tab[aria-selected="true"] { color: var(--white); }
.hs-tab[aria-selected="true"] small { color: var(--slate-300); }
.hs-tab[aria-selected="true"] .bar i { transform: scaleX(1); }
.hs-tab.is-run .bar i { animation: hs-prog var(--hs-dur, 5s) linear forwards; }
.hs.is-held ~ .hs-tabs .hs-tab .bar i, .hs-wrap.is-held .hs-tab .bar i { animation-play-state: paused; }
@keyframes hs-prog { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@media (hover: hover) and (pointer: fine) { .hs-tab:hover { color: var(--white); } }
.hs-pp { flex: none; align-self: flex-end; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .22); background: rgba(255, 255, 255, .06); color: var(--white); cursor: pointer; transition: background-color .2s; }
.hs-pp:hover { background: rgba(255, 255, 255, .14); }
.hs-pp svg { width: 14px; height: 14px; }
.hs-pp .i-play { display: none; }
.hs-pp[aria-pressed="true"] .i-pause { display: none; }
.hs-pp[aria-pressed="true"] .i-play { display: block; }

/* titre : les mots se lèvent derrière un masque */
.hero--depth h1 .w { display: inline-block; overflow: hidden; vertical-align: top; padding: 0 .02em .14em; margin-bottom: -.14em; }
.hero--depth h1 .w > i { display: inline-block; font-style: normal; transform: translateY(0); }
@media (prefers-reduced-motion: no-preference) {
  .hero--depth h1 .w > i { animation: hs-word .95s calc(.15s + var(--i) * .055s) cubic-bezier(.2, .9, .2, 1) both; }
}
@keyframes hs-word { from { transform: translateY(108%); } to { transform: translateY(0); } }
.hd-copy > h1 { animation: none; }

/* bandeau de réassurance sous le hero */
.trust-strip { background: var(--navy-950); border-top: 1px solid rgba(255, 255, 255, .06); border-bottom: 1px solid rgba(255, 255, 255, .06); }
.trust-strip ul { list-style: none; margin: 0; padding: 18px 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 36px; color: var(--slate-100); font-size: .95rem; }
.trust-strip li { display: flex; align-items: center; gap: 8px; }
.trust-strip svg { width: 18px; height: 18px; color: var(--green); flex: none; }

@media (max-width: 900px) {
  .hero--depth { min-height: 0; padding-top: 36px; }
  .hero--depth .container { grid-template-columns: 1fr; gap: 8px; }
  .hs-wrap { max-width: 480px; margin-inline: auto; width: 100%; }
  .hs, .hs-tabs { width: 100%; }
}

/* ------------------------------------------------- SCÈNE : DEUX FAÇONS --- */
.duo {
  --p: 0; --a: 1; --o: 1; --m: 0;
  position: relative; background: var(--navy-ink); color: var(--slate-100);
  background-image:
    radial-gradient(900px 520px at 50% 0, rgba(41, 182, 227, .12), transparent 70%),
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px);
  background-size: auto, 56px 56px, 56px 56px;
}
.duo.is-live { height: 175svh; --a: 0; --o: 0; --m: 0; }
.duo__stage {
  position: relative; min-height: 100svh; padding: clamp(28px, 5vw, 56px) 0;
  display: grid; grid-template-rows: auto 1fr auto; overflow: hidden;
}
.duo.is-live .duo__stage { position: sticky; top: 72px; height: calc(100svh - 72px); min-height: 0; padding: clamp(14px, 2.4vh, 28px) 0 clamp(14px, 2.4vh, 26px); }

.duo__head { text-align: center; padding: 0 20px; z-index: 3; }
.duo__head h2 { color: var(--white); font-size: clamp(1.5rem, 3vw, 2.4rem); margin: 0 0 .35em; text-wrap: balance; }
.duo__caps { position: relative; min-height: 3.4em; max-width: 44rem; margin: 0 auto; }
.duo__caps p { margin: 0; color: var(--slate-300); font-size: clamp(.98rem, 1.25vw, 1.1rem); text-wrap: balance; }
.duo.is-live .duo__caps p { position: absolute; inset: 0 0 auto 0; opacity: 0; transform: translateY(8px); transition: opacity .45s var(--ease-out), transform .45s var(--ease-out); }
.duo.is-live[data-phase="1"] .duo__caps p:nth-child(1),
.duo.is-live[data-phase="2"] .duo__caps p:nth-child(2),
.duo.is-live[data-phase="3"] .duo__caps p:nth-child(3) { opacity: 1; transform: none; }
.duo:not(.is-live) .duo__caps p:not(:last-child) { display: none; }

.duo__sides { position: relative; display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; width: 100%; max-width: 1560px; margin: 0 auto; padding: 0 20px; min-height: 0; }
.duo__side { position: relative; display: grid; grid-template-rows: 1fr auto; min-width: 0; transform: translate3d(calc(var(--m) * var(--shift, 0px)), 0, 0); }
.duo__side--s50 { --shift: 3.2vw; }
.duo__side--s5  { --shift: -3.2vw; }

.duo__scene { position: relative; min-height: 0; container-type: size; }

/* Le « rig » regroupe la serrure et l'outil : tout s'y mesure en cqw (1 % de la largeur du rig),
   donc le geste tombe juste quelle que soit la taille de l'écran. Il est borné par la hauteur de la scène. */
.duo__rig { position: absolute; right: 3%; top: 43%; translate: 0 -50%; width: min(62cqw, 104cqh); aspect-ratio: 1100 / 874; container-type: inline-size; }
.duo__side--s5 .duo__rig { aspect-ratio: 894 / 600; width: min(62cqw, 128cqh); }
.duo__rig > img { position: absolute; left: 0; top: 0; max-width: none; height: auto; }
.duo__lock { z-index: 1; width: 100%; filter: drop-shadow(0 26px 30px rgba(0, 0, 0, .5)); transition: filter .6s var(--ease-out); }
.duo.is-open .duo__lock { filter: drop-shadow(0 26px 30px rgba(0, 0, 0, .5)) drop-shadow(0 0 26px rgba(41, 182, 227, .55)); }
.duo__tool { z-index: 2; filter: drop-shadow(0 calc(26px - var(--a) * 18px) calc(28px - var(--a) * 16px) rgba(0, 0, 0, .55)); will-change: transform; transform-origin: 50% 50%; }

/* S50 : le téléphone arrive du bas gauche, dans l'axe de la serrure, et se pose contre le bouton extérieur */
.duo__side--s50 .duo__tool {
  height: 64cqw; width: auto;
  translate: calc(-19cqw - (1 - var(--a)) * 30cqw) calc(13cqw + (1 - var(--a)) * 8cqw);
  rotate: calc(-4deg - (1 - var(--a)) * 10deg);
}
/* S5 : la clé arrive dans l'axe du cylindre, lame vers le trou de clé, et s'y engage */
.duo__side--s5 .duo__tool {
  height: 44cqw; width: auto;
  translate: calc(-4.7cqw - (1 - var(--a)) * 28.6cqw) calc(35.1cqw + (1 - var(--a)) * 14.3cqw);
  rotate: calc(-116.6deg + (1 - var(--a)) * 8deg);
}

/* ondes NFC du S50, entre le téléphone et la serrure */
.duo__nfc { z-index: 3; position: absolute; left: 14cqw; top: 26cqw; width: 12cqw; height: auto; overflow: visible; opacity: var(--o); }
.duo__nfc path { fill: none; stroke: var(--teal); stroke-width: 3.4; stroke-linecap: round; animation: hd-fade 1.2s ease-in-out infinite alternate; }
.duo__nfc path:nth-child(2) { animation-delay: .25s; } .duo__nfc path:nth-child(3) { animation-delay: .5s; }

/* état de la serrure : verrouillé puis ouvert */
.duo__state {
  z-index: 4; position: absolute; left: 50%; bottom: 0; translate: -50% 0;
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  font-weight: 700; font-size: .92rem; padding: 10px 16px; border-radius: 999px;
  background: rgba(255, 255, 255, .08); color: var(--slate-100); border: 1px solid rgba(255, 255, 255, .14);
  transition: background .35s var(--ease-out), color .35s var(--ease-out), border-color .35s var(--ease-out);
}
.duo__state svg { width: 17px; height: 17px; }
.duo__state .on, .duo__state .off { display: inline-flex; align-items: center; gap: 8px; }
.duo__state .on { display: none; }
.duo.is-open .duo__state, .duo:not(.is-live) .duo__state { background: var(--white); color: var(--navy-900); border-color: transparent; }
.duo.is-open .duo__state .off, .duo:not(.is-live) .duo__state .off { display: none; }
.duo.is-open .duo__state .on,  .duo:not(.is-live) .duo__state .on  { display: inline-flex; }
.duo__state .on svg { color: #12907f; }

.duo__copy { padding: 6px 4px 0; max-width: 28rem; justify-self: center; text-align: center; }
.duo__copy .tag { font-size: .74rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--teal); }
.duo__copy h3 { color: var(--white); font-size: clamp(1.15rem, 1.8vw, 1.5rem); margin: .25em 0 .35em; }
.duo__copy p { color: var(--slate-300); font-size: .97rem; margin: 0 0 .5em; }
.duo__copy a { font-weight: 700; color: var(--teal); }

/* le diviseur : il porte l'état de la scène, puis il se retire */
.duo__divider {
  position: absolute; left: 50%; top: 2%; bottom: 14%; width: 1px; z-index: 2; pointer-events: none;
  background: linear-gradient(transparent, rgba(255, 255, 255, .28) 14%, rgba(255, 255, 255, .28) 86%, transparent);
  transform: scaleY(calc(1 - var(--m))); opacity: calc(1 - var(--m));
}
.duo__bridge {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 22px;
  margin: 10px auto 0; padding: 0 20px; text-align: center; color: var(--slate-100); font-size: .95rem;
  opacity: var(--m); transform: translate3d(0, calc((1 - var(--m)) * 18px), 0);
}
.duo__bridge strong { color: var(--white); font-size: 1.05rem; }
.duo__bridge span:not(.btn) + span::before { content: "·"; margin-right: 22px; color: var(--teal); }
.duo:not(.is-live) .duo__bridge { opacity: 1; transform: none; margin-top: 28px; }
.duo.is-live:not(.is-merged) .duo__bridge .btn { pointer-events: none; }

@media (max-width: 860px) {
  .duo.is-live { height: 188svh; }
  .duo__sides { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; padding: 0 16px; gap: 0; }
  .duo__divider { left: 8%; right: 8%; top: 50%; bottom: auto; width: auto; height: 1px; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .28) 14%, rgba(255, 255, 255, .28) 86%, transparent); transform: scaleX(calc(1 - var(--m))); }
  .duo__side { grid-template-rows: 1fr auto; --shift: 0px; }
  .duo__scene { min-height: 120px; }
  .duo__rig { right: 3%; top: 41%; width: min(66cqw, 84cqh); }
  .duo__side--s5 .duo__rig { width: min(66cqw, 112cqh); }
  .duo__copy .tag { display: none; }
  .duo__copy { padding-top: 26px; }
  .duo__copy { max-width: none; padding: 0 2px; }
  .duo__copy p { display: none; }
  .duo__copy h3 { font-size: 1.05rem; margin: .1em 0 .2em; }
  .duo__copy .tag { font-size: .68rem; }
  .duo__state { bottom: -6px; font-size: .8rem; padding: 7px 12px; }
  .duo__head h2 { font-size: 1.3rem; }
  .duo__caps p { font-size: .9rem; }
  .duo__caps { min-height: 4.2em; }
  .duo__bridge { font-size: .85rem; gap: 6px 14px; }
  .duo__bridge span:not(.btn) + span::before { margin-right: 14px; }
}
/* écran bas : on ne montre que l'essentiel de chaque face */
@media (max-height: 700px) and (min-width: 861px) { .duo__copy p { display: none; } }

/* mouvement réduit : composition finale, sans pin ni parallaxe */
@media (prefers-reduced-motion: reduce) {
  .hd-copy > *, .hs-halo, .hs-dust { animation: none !important; }
  .duo__nfc path { animation: none; }
}
@media (prefers-reduced-motion: no-preference) { .duo__nfc { transition: opacity .3s; } }

/* ----------------- fiches solutions : vraies photos produits détourées ---- */
.product-card .media--photo { padding: 18px; }
.product-card .media--photo img { object-fit: contain; filter: drop-shadow(0 18px 20px rgba(0, 0, 0, .45)); }
.product-card .media--photo img.is-tall { width: auto; height: 100%; }

/* --------------------------------------------------------- film animé ---- */
.film { position: relative; max-width: 1000px; margin: 0 auto 56px; }
.film video { width: 100%; height: auto; aspect-ratio: 16 / 9; border-radius: 20px; background: var(--navy-ink); box-shadow: 0 30px 60px -24px rgba(0, 0, 0, .6); border: 1px solid rgba(255, 255, 255, .1); }
.film figcaption { margin-top: 12px; text-align: center; color: var(--slate-300); font-size: .92rem; }

/* ==========================================================================
   SECTIONS SUIVANTES : une scène par section, jamais deux fois le même geste.
   .mo = JS actif et mouvement autorisé ; .is-live = la scène est pilotée au scroll.
   Sans cela, chaque section reste une mise en page statique complète.
   ========================================================================== */
.sp { position: fixed; left: 0; top: 0; width: 100%; height: 3px; z-index: 60; pointer-events: none; transform-origin: 0 50%; transform: scaleX(var(--sp, 0)); background: linear-gradient(90deg, var(--teal), var(--green)); }
.ben, .sol, .how, .sec { scroll-margin-top: 72px; }

/* ----------------------------------------- 1. BÉNÉFICES : liste qui s'allume */
.ben { background: var(--white); }
.ben__wrap { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: clamp(32px, 6vw, 104px); align-items: start; }
.ben__lead { position: sticky; top: calc(72px + clamp(24px, 9vh, 96px)); }
.ben__lead h2 { font-size: clamp(1.9rem, 3.5vw, 2.8rem); text-wrap: balance; }
.ben__lead p { color: var(--muted); font-size: 1.08rem; text-wrap: pretty; }
.ben__bar { margin-top: 28px; height: 4px; width: min(100%, 260px); border-radius: 4px; background: var(--slate-100); overflow: hidden; }
.ben__bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--teal), var(--green)); transform-origin: 0 50%; transform: scaleX(var(--bp, 1)); }
.ben__list { list-style: none; margin: 0; padding: 0; }
.ben__item { display: grid; grid-template-columns: 64px minmax(0, 1fr); column-gap: 24px; padding: clamp(28px, 9vh, 88px) 0; border-top: 1px solid var(--slate-100); }
.ben__item:last-child { border-bottom: 1px solid var(--slate-100); }
.ben__item .icon { grid-row: 1 / span 2; width: 64px; height: 64px; border-radius: 18px; margin: 0; }
.ben__item .icon svg { width: 30px; height: 30px; }
.ben__item h3 { font-size: clamp(1.3rem, 2.1vw, 1.75rem); margin: 4px 0 .3em; }
.ben__item p { margin: 0; color: var(--muted); font-size: 1.05rem; max-width: 34em; text-wrap: pretty; }
.ben.is-live .ben__item { opacity: .32; transition: opacity .45s var(--ease-out); }
.ben.is-live .ben__item.is-on { opacity: 1; }
.ben.is-live .ben__item .icon { transition: transform .45s var(--ease-out), background-color .3s, color .3s; }
.ben.is-live .ben__item.is-on .icon { transform: scale(1.07); background: var(--teal); color: var(--navy-950); }
@media (max-width: 900px) {
  .ben__wrap { grid-template-columns: 1fr; gap: 28px; }
  .ben__lead { position: static; }
  .ben__item { padding: 26px 0; grid-template-columns: 52px minmax(0, 1fr); column-gap: 18px; }
  .ben__item .icon { width: 52px; height: 52px; }
}

/* ----------------------------- 2. SOLUTIONS : rail horizontal piloté au scroll */
.sol { padding: 0; }
.sol:not(.is-live) { padding: clamp(64px, 9vw, 112px) 0; }
.sol__rail { display: flex; flex-wrap: wrap; gap: 24px; justify-content: center; max-width: var(--max); margin: 0 auto; padding: 0 20px; }
.sol__intro { flex: 1 1 100%; max-width: none; margin: 0 0 24px; text-align: center; }
.sol__intro h2, .sol__intro p { max-width: 40em; margin-inline: auto; }
.sol__intro h2 { color: var(--white); text-wrap: balance; }
.sol__intro p { color: var(--slate-300); font-size: 1.1rem; }
.sol__card { flex: 1 1 300px; max-width: 420px; }
.sol__end { flex: 1 1 100%; text-align: center; padding-top: 12px; }
.sol__end h3 { color: var(--white); }
.sol__end p { color: var(--slate-300); max-width: 34em; margin-inline: auto; }
.sol .product-card { background: var(--navy-800); border-color: rgba(255, 255, 255, .09); box-shadow: 0 30px 50px -30px rgba(0, 0, 0, .7); }
.sol .product-card .media { aspect-ratio: 16 / 9; }
.sol .product-card .tag, .sol .product-card .more { color: var(--teal); }
.sol .product-card p, .sol .product-card ul { color: var(--slate-300); }
.sol .product-card h3 { color: var(--white); }
.sol .product-card:hover { transform: none; }
.sol .media img { translate: calc(var(--cp, 0) * -28px) 0; }

.sol.is-live .sol__stage { position: sticky; top: 72px; height: calc(100svh - 72px); overflow: hidden; display: flex; align-items: center; }
.sol.is-live .sol__rail { flex-wrap: nowrap; justify-content: flex-start; flex: none; width: max-content; max-width: none; margin: 0; gap: clamp(20px, 2.6vw, 40px); padding: 0 max(20px, calc((100vw - var(--max)) / 2 + 20px)); will-change: transform; align-items: center; }
.sol.is-live .sol__intro { flex: 0 0 clamp(280px, 30vw, 440px); margin: 0; text-align: left; }
.sol.is-live .sol__intro h2, .sol.is-live .sol__intro p { margin-inline: 0; }
.sol.is-live .sol__card { flex: 0 0 clamp(290px, 31vw, 460px); max-width: none; }
.sol.is-live .sol__end { flex: 0 0 clamp(270px, 26vw, 380px); text-align: left; padding: 0; }
.sol.is-live .sol__end p { margin-inline: 0; }
@media (max-width: 700px) {
  .sol.is-live .sol__intro { flex-basis: 82vw; }
  .sol.is-live .sol__card { flex-basis: 82vw; }
  .sol.is-live .sol__end { flex-basis: 78vw; }
}
@media (max-height: 780px) {
  .sol .product-card .media { aspect-ratio: 16 / 7; }
  .sol .product-card ul { display: none; }
}

/* -------------------------------- 3. MÉTHODE : la ligne se dessine, les étapes s'allument */
.how__track { position: relative; }
.how__steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px; counter-reset: how; position: relative; }
.how__step { position: relative; padding-top: 76px; counter-increment: how; }
.how__step::before {
  content: counter(how); position: absolute; top: 0; left: 0; z-index: 1; width: 48px; height: 48px; border-radius: 50%;
  display: grid; place-items: center; font-weight: 800; font-size: 1.1rem;
  background: var(--teal); color: var(--navy-950); box-shadow: 0 0 0 8px rgba(41, 182, 227, .18);
  transition: background-color .35s var(--ease-out), color .35s, box-shadow .35s, transform .45s var(--ease-out), border-color .35s;
}
.how__step h3 { font-size: 1.3rem; margin-bottom: .4em; }
.how__step p { color: var(--muted); margin: 0; }
.how__line { position: absolute; left: 24px; right: 24px; top: 22px; height: 4px; border-radius: 4px; background: var(--slate-100); overflow: hidden; }
.how__line i { display: block; width: 100%; height: 100%; background: linear-gradient(90deg, var(--teal), var(--green)); transform-origin: 0 50%; }
.how.is-live .how__line i { transform: scaleX(var(--lp, 0)); }
.how.is-live .how__step::before { background: var(--white); color: var(--slate-500); box-shadow: none; border: 2px solid var(--slate-300); }
.how.is-live .how__step.is-on::before { background: var(--teal); color: var(--navy-950); border-color: var(--teal); box-shadow: 0 0 0 8px rgba(41, 182, 227, .18); transform: scale(1.08); }
.how.is-live .how__step h3, .how.is-live .how__step p { transition: opacity .45s var(--ease-out), translate .45s var(--ease-out); }
.how.is-live .how__step:not(.is-on) h3, .how.is-live .how__step:not(.is-on) p { opacity: .35; translate: 0 6px; }
@media (max-width: 900px) {
  .how__steps { grid-template-columns: 1fr; gap: 6px; }
  .how__step { padding: 4px 0 28px 76px; }
  .how__step::before { top: 0; }
  .how__line { left: 22px; right: auto; top: 24px; bottom: 24px; width: 4px; height: auto; }
  .how__line i { transform-origin: 50% 0; }
  .how.is-live .how__line i { transform: scaleY(var(--lp, 0)); }
}

/* ------------------------------- 4. SECTEURS : index typographique + aperçu photo */
.sec__head { max-width: 720px; margin: 0 0 40px; }
.sec__head p { color: var(--muted); font-size: 1.12rem; }
.sec__body { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr); gap: clamp(28px, 5vw, 80px); align-items: start; }
.idx { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--slate-100); }
.idx__row { position: relative; display: grid; grid-template-columns: 40px minmax(0, 1fr) 28px; gap: 4px 18px; align-items: center; padding: 22px 6px; border-bottom: 1px solid var(--slate-100); }
.idx__row::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--teal); transform: scaleX(0); transform-origin: 0 50%; transition: transform .5s var(--ease-out); }
.idx__row.is-active::after { transform: scaleX(1); }
.idx__icon { color: var(--teal-600); display: grid; place-items: center; }
.idx__icon svg { width: 28px; height: 28px; }
.idx__txt h3 { margin: 0; font-size: clamp(1.2rem, 2vw, 1.6rem); transition: translate .4s var(--ease-out), color .25s; }
.idx__txt p { margin: .15em 0 .3em; color: var(--muted); font-size: .98rem; }
.idx__link { font-size: .9rem; font-weight: 700; color: var(--teal-600); }
.idx__link::after { content: ""; position: absolute; inset: 0; }
.idx__link:hover { text-decoration: none; }
.idx__go { color: var(--teal-600); opacity: .55; transition: translate .4s var(--ease-out), opacity .25s; }
.idx__go svg { width: 24px; height: 24px; }
.idx__row.is-active .idx__txt h3 { translate: 8px 0; color: var(--teal-600); }
.idx__row.is-active .idx__go { translate: 6px 0; opacity: 1; }
.idx__row:focus-within { outline: 3px solid var(--teal); outline-offset: -3px; }
.idx__link:focus-visible { outline: none; }
.idx__stage { position: sticky; top: calc(72px + 28px); aspect-ratio: 4 / 5; border-radius: 24px; overflow: hidden; background: var(--navy-900); box-shadow: var(--shadow); }
.idx__stage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; scale: 1.07; transition: opacity .55s var(--ease-out), scale .9s var(--ease-out); }
.idx__stage img.is-active { opacity: 1; scale: 1; }
@media (max-width: 900px) {
  .sec__body { grid-template-columns: 1fr; }
  .idx__stage { display: none; }
}

/* ---------------------------------- 5. GALERIE : colonnes décalées, parallaxe */
.gallery--float { align-items: start; gap: 20px; padding-bottom: 56px; }
.gallery--float figure { aspect-ratio: 3 / 4; translate: 0 var(--py, 0px); }
.gallery--float figure:nth-child(2) { margin-top: 56px; }
.gallery--float figure:nth-child(3) { margin-top: 22px; }
.gallery--float figure:nth-child(4) { margin-top: 84px; }
@media (max-width: 860px) {
  .gallery--float { padding-bottom: 20px; }
  .gallery--float figure:nth-child(n) { margin-top: 0; }
  .gallery--float figure:nth-child(even) { margin-top: 36px; }
}

/* ------------------------------------------------------------ 6. À PROPOS --- */
.mo .wipe { clip-path: inset(0 0 100% 0 round 16px); transition: clip-path 1.1s var(--ease-out); }
.mo .wipe.is-in { clip-path: inset(0 0 0 0 round 16px); }

/* ---------------------------------------------------------------- 7. FAQ ---- */
.faq details summary { transition: color .2s; }
.faq details summary:hover, .faq details[open] summary { color: var(--teal-600); }
.faq details[open] p { animation: faq-in .5s var(--ease-out) both; }
@keyframes faq-in { from { opacity: 0; translate: 0 -10px; } to { opacity: 1; translate: 0 0; } }

/* ------------------------------------- 8. CTA : scène de clôture, spotlight + aimant */
.cta-scene {
  --mx: 50%; --my: 40%;
  position: relative; overflow: hidden; isolation: isolate; text-align: center; color: var(--slate-100);
  padding: clamp(88px, 13vw, 170px) 0; background: var(--navy-950);
  background-image: linear-gradient(rgba(255, 255, 255, .035) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .035) 1px, transparent 1px);
  background-size: 56px 56px;
}
.cta-scene::before { content: ""; position: absolute; inset: 0; z-index: -1; background: radial-gradient(520px 380px at var(--mx) var(--my), rgba(41, 182, 227, .26), transparent 70%); }
.cta-scene__in { position: relative; z-index: 2; max-width: 760px; }
.cta-scene h2 { color: var(--white); font-size: clamp(2.1rem, 5vw, 3.7rem); line-height: 1.05; letter-spacing: -.03em; text-wrap: balance; }
.cta-scene p { color: var(--slate-300); font-size: 1.15rem; max-width: 34em; margin: 0 auto 1.4em; text-wrap: pretty; }
.cta-scene .btn { padding: 18px 34px; font-size: 1.1rem; }
.cta-scene__obj { position: absolute; z-index: 1; pointer-events: none; height: auto; max-width: none; translate: 0 var(--py, 0px); filter: drop-shadow(0 30px 34px rgba(0, 0, 0, .55)); }
.cta-scene__obj--lock { right: max(2%, calc(50% - 820px)); top: 15%; width: clamp(160px, 21vw, 300px); opacity: .92; }
.cta-scene__obj--phone { left: max(3%, calc(50% - 800px)); top: 9%; width: clamp(100px, 11.5vw, 170px); rotate: -9deg; }
.cta-scene__obj--key { right: max(19%, calc(50% - 560px)); bottom: 7%; width: clamp(56px, 6.5vw, 92px); rotate: 32deg; }
@media (max-width: 760px) {
  .cta-scene__obj { opacity: .22; }
  .cta-scene__obj--lock { display: none; }
  .cta-scene__obj--phone { left: -6%; top: 4%; }
  .cta-scene__obj--key { left: auto; right: 4%; bottom: 3%; }
}
[data-magnet] { translate: var(--mgx, 0px) var(--mgy, 0px); }
@media (prefers-reduced-motion: reduce) { .sp { display: none; } }

/* ==================================================== CORRECTIFS DE CADRAGE ==== */
/* Fiches solutions : le visuel a une hauteur explicite et se centre en entier (contain), jamais rogné. */
.sol .product-card .media { aspect-ratio: auto; height: clamp(170px, 27vh, 260px); padding: 14px 22px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.sol .product-card .media img { flex: 0 1 auto; min-width: 0; min-height: 0; width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; transform: none; translate: calc(var(--cp, 0) * -12px) 0; filter: drop-shadow(0 16px 18px rgba(0, 0, 0, .45)); }
.sol .product-card:hover .media img { transform: none; }
.sol .product-card .media--photo { padding: 12px 18px; }
.sol .product-card .media svg { display: none; }
.sol.is-live .sol__rail { align-items: stretch; }
.sol.is-live .sol__intro, .sol.is-live .sol__end { align-self: center; }
.sol .product-card .body { padding: 22px 26px 26px; }
@media (max-height: 780px) { .sol .product-card .media { height: clamp(140px, 22vh, 190px); } }

/* Sections suivantes : recadrage des photos (point focal) */
.gallery--float img { object-position: 50% 40%; }
.gallery--float img[src$="intervention-site-sensible.jpg"] { object-position: 52% 22%; }
.gallery--float img[src$="cle-iloq-clavier.jpg"] { object-position: 46% 50%; }
.gallery--float img[src$="porte-cle-iloq.jpg"] { object-position: 50% 35%; }
.gallery--float img[src$="cle-iloq-exterieur.jpg"] { object-position: 62% 50%; }
.idx__stage img[src$="site-isole-cadenas-smartphone.jpg"] { object-position: 62% 50%; }
.idx__stage img[src$="copropriete-key-fob-porte.jpg"] { object-position: 38% 50%; }
.idx__stage img[src$="porte-cle-iloq.jpg"] { object-position: 50% 40%; }
.idx__stage img[src$="batiment-public-cle-lecteur.jpg"] { object-position: 74% 50%; }
.idx__stage img[src$="logistique-serrure-smartphone.jpg"] { object-position: 70% 55%; }
.idx__stage img[src$="local-securise-key-fob.jpg"] { object-position: 62% 50%; }
.idx__stage img[src$="cle-iloq-clavier.jpg"] { object-position: 45% 50%; }
.idx__stage img[src$="smartphone-cle-iloq.jpg"] { object-position: 40% 50%; }
.about-img { object-position: 50% 40%; }

@media (max-height: 760px) and (min-width: 861px) {
  .duo__rig { top: 40%; width: min(58cqw, 92cqh); }
  .duo__side--s5 .duo__rig { width: min(58cqw, 112cqh); }
  .duo__state { transform: scale(.92); }
}

/* ----------------------------------------------- scène S50/S5 : effets d'ouverture --- */
.duo__side--s50 .duo__rig { --rx: 17%; --ry: 70%; }
.duo__side--s5 .duo__rig { --rx: 11%; --ry: 80%; }
.duo__rig::before, .duo__rig::after {
  content: ""; position: absolute; z-index: 3; left: var(--rx); top: var(--ry); width: 30cqw; aspect-ratio: 1;
  margin: -15cqw 0 0 -15cqw; border-radius: 50%; border: 2px solid rgba(41, 182, 227, .95);
  opacity: 0; scale: .2; pointer-events: none;
}
.duo.is-open .duo__rig::before { animation: duo-ripple 1.15s var(--ease-out) both; }
.duo.is-open .duo__rig::after { animation: duo-ripple 1.15s .2s var(--ease-out) both; }
@keyframes duo-ripple { 0% { opacity: .95; scale: .2; } 100% { opacity: 0; scale: 2.3; } }
.duo.is-open .duo__lock { animation: duo-click .55s var(--ease-out); }
@keyframes duo-click { 0% { scale: 1; } 35% { scale: 1.028; } 100% { scale: 1; } }
.duo.is-open .duo__state { animation: duo-pop .6s var(--ease-out); }
@keyframes duo-pop { 0% { scale: .86; } 45% { scale: 1.08; } 100% { scale: 1; } }
.duo.is-open .duo__divider { box-shadow: 0 0 14px rgba(41, 182, 227, .35); }
@media (prefers-reduced-motion: reduce) {
  .duo.is-open .duo__rig::before, .duo.is-open .duo__rig::after, .duo.is-open .duo__lock, .duo.is-open .duo__state { animation: none; }
}

/* La clé S5 s'engage dans le trou : tout ce qui dépasse le plan du trou (perpendiculaire à l'axe du cylindre)
   est rogné, donc la lame disparaît dans la serrure au lieu de la traverser. Coordonnées en % du rig (L = 100, H = 67,1). */
.duo__keyclip { position: absolute; inset: 0; z-index: 2; pointer-events: none;
  clip-path: polygon(-78.4% -186.4%, 100.4% 346.5%, -167.6% 546.2%, -346.4% 13.3%); }
.duo__keyclip .duo__tool { position: absolute; left: 0; top: 0; max-width: none; }

/* ==================================================== VIDÉOS : deux films à la une ==== */
#videos .section-head { margin-bottom: 44px; max-width: 880px; }
.vfeat { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2.6vw, 36px); max-width: 1180px; margin: 0 auto; }
.vcard { display: flex; flex-direction: column; gap: 18px; }
.vcard__frame {
  position: relative; aspect-ratio: 16 / 9; border-radius: 22px; overflow: hidden; background: var(--navy-950);
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: 0 34px 60px -28px rgba(0, 0, 0, .75), 0 0 0 1px rgba(41, 182, 227, .0);
  transition: transform .5s var(--ease-out), box-shadow .5s var(--ease-out), border-color .3s;
}
.vcard--main .vcard__frame { border-color: rgba(41, 182, 227, .45); box-shadow: 0 34px 60px -28px rgba(0, 0, 0, .75), 0 0 46px -12px rgba(41, 182, 227, .45); }
@media (hover: hover) and (pointer: fine) { .vcard:hover .vcard__frame { transform: translateY(-4px); border-color: rgba(41, 182, 227, .6); } }
.vcard__video { display: block; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border: 0; border-radius: 0; background: var(--navy-950); }
.vcard__txt { padding: 0 6px; }
.vcard__k { display: inline-block; font-size: .74rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--teal); margin-bottom: 8px; }
.vcard__txt h3 { color: var(--white); font-size: clamp(1.2rem, 1.9vw, 1.5rem); margin: 0 0 .25em; }
.vcard__txt p { color: var(--slate-300); margin: 0; font-size: 1rem; }

/* bouton de lecture posé sur la vidéo de présentation (créé par le script) :
   en pastille, en bas à gauche, pour ne jamais recouvrir le texte de l'affiche */
.vcard__btn {
  position: absolute; inset: 0; z-index: 2; display: flex; align-items: flex-end; justify-content: flex-start; border: 0; padding: clamp(14px, 2vw, 24px); cursor: pointer;
  background: linear-gradient(180deg, rgba(4, 16, 26, 0) 45%, rgba(4, 16, 26, .62)); color: var(--navy-950);
  transition: opacity .35s var(--ease-out), visibility .35s;
}
.vcard__btn span {
  display: inline-flex; align-items: center; gap: 12px; padding: 8px 20px 8px 8px; border-radius: 999px;
  background: var(--white); color: var(--navy-900); font-weight: 800; font-size: 1rem;
  box-shadow: 0 16px 34px -12px rgba(0, 0, 0, .65);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
.vcard__btn i { display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 0 6px rgba(41, 182, 227, .25); }
.vcard__btn svg { width: 18px; height: 18px; margin-left: 2px; color: var(--navy-950); }
@media (hover: hover) and (pointer: fine) { .vcard__btn:hover span { transform: translateY(-2px) scale(1.03); } }
.vcard__btn:active span { transform: scale(.97); }
.vcard.is-playing .vcard__btn { opacity: 0; visibility: hidden; }

#videos .shorts { max-width: 880px; margin-inline: auto; margin-top: 8px; }
#videos .subhead { max-width: 880px; margin-inline: auto; }
@media (max-width: 860px) {
  .vfeat { grid-template-columns: 1fr; gap: 34px; }
}

.hs-scene--s5 .hs-pill { left: 24%; bottom: 3.5%; }

@media (max-width: 560px) {
  .hero--depth .lead { display: none; }
  .hero--depth .hero-cta { margin: 20px 0 6px; }
}

/* ================================================== FICHES SOLUTIONS : visuels vivants ====
   Chaque visuel joue sa boucle (6 s) quand la fiche est au centre de l'écran, au survol ou au focus.
   L'état de base est l'état FINAL : sans mouvement ou hors écran, on voit la scène terminée. */
.sol .product-card .media.cv { position: relative; container-type: size; padding: 0; display: block; }
.sol .product-card .media.cv img { position: static; display: block; width: 100%; height: 100%; max-width: none; max-height: none; flex: none; min-width: 0; min-height: 0; translate: none; filter: none; object-fit: contain; }
.cv-rig { position: absolute; top: 50%; translate: 0 -50%; container-type: inline-size; }
.cv-rig--s50 { height: 90cqh; aspect-ratio: 1100 / 874; left: 30%; }
.cv-rig--s5 { height: 84cqh; aspect-ratio: 894 / 600; left: 24%; }
.cv-lock { position: absolute; inset: 0; z-index: 1; }
.cv-lock img { filter: drop-shadow(0 3cqw 3.4cqw rgba(2, 10, 18, .55)); }
.cv-glow { position: absolute; inset: -12% -8%; z-index: 0; border-radius: 50%; opacity: 1; background: radial-gradient(closest-side, rgba(41, 182, 227, .38), rgba(41, 182, 227, .1) 60%, transparent 76%); }
.cv-ripple { position: absolute; z-index: 3; width: 30cqw; aspect-ratio: 1; margin: -15cqw 0 0 -15cqw; border-radius: 50%; border: 2px solid rgba(95, 210, 245, .95); opacity: 0; scale: .2; pointer-events: none; }
.cv-rig--s50 .cv-ripple { left: 17%; top: 70%; }
.cv-rig--s5 .cv-ripple { left: 11%; top: 80%; }

.cv-phone { position: absolute; z-index: 2; left: 0; top: 0; height: 64cqw; aspect-ratio: 620 / 1232; translate: -19cqw 13cqw; rotate: -4deg; }
.cv-phone img { filter: drop-shadow(0 2.6cqw 3cqw rgba(0, 0, 0, .55)); }
.cv-ok { position: absolute; left: 49.1%; top: 44.5%; width: 60%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 35% 30%, #6bbf6a, #3f8f4e 70%); box-shadow: 0 0 0 .8cqw rgba(255, 255, 255, .18), 0 1.4cqw 3cqw rgba(20, 70, 30, .45); }
.cv-ok svg { width: 52%; height: 52%; color: #fff; }
.cv-nfc { position: absolute; z-index: 3; left: 14cqw; top: 26cqw; width: 12cqw; height: auto; overflow: visible; }
.cv-nfc path { fill: none; stroke: var(--teal); stroke-width: 3.6; stroke-linecap: round; opacity: .5; }

.cv-keyclip { position: absolute; inset: 0; z-index: 2; pointer-events: none; clip-path: polygon(-78.4% -186.4%, 100.4% 346.5%, -167.6% 546.2%, -346.4% 13.3%); }
.cv-keyw { position: absolute; left: 0; top: 0; height: 44cqw; aspect-ratio: 520 / 1260; translate: -4.7cqw 35.1cqw; rotate: -116.6deg; filter: drop-shadow(0 2.4cqw 2.6cqw rgba(0, 0, 0, .55)); }

.cv-chip { position: absolute; left: 12px; bottom: 10px; z-index: 5; display: block; height: 30px; min-width: 124px; font-weight: 700; font-size: .78rem; }
.cv-chip > span { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 0 12px; border-radius: 999px; white-space: nowrap; }
.cv-chip svg { width: 1.15em; height: 1.15em; flex: none; }
.cv-chip .off { background: rgba(255, 255, 255, .1); color: var(--slate-100); border: 1px solid rgba(255, 255, 255, .2); opacity: 0; }
.cv-chip .on { background: var(--white); color: var(--navy-900); box-shadow: 0 8px 18px -8px rgba(0, 0, 0, .6); }
.cv-chip .on svg { color: #12907f; }

/* manager */
.cv-mgr { position: absolute; left: 50%; top: 50%; translate: -50% -50%; height: 100%; width: auto; max-width: 100%; overflow: visible; }
.cv-mgr * { transform-box: fill-box; }
.cv-trk { fill: #2c4a62; }
.cv-knob { fill: #a9b8c5; transform: translateX(-16px); transform-box: view-box; }
.cv-chk { stroke-dasharray: 20; stroke-dashoffset: 0; }

@media (prefers-reduced-motion: no-preference) {
  .sol__card:is(.is-on, :hover, :focus-within) .cv-phone { animation: cv-phone 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-ok { animation: cv-ok 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-glow { animation: cv-glow 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-lock { animation: cv-click50 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-ripple { animation: cv-ripple50 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-ripple--2 { animation-delay: .2s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-nfc path { animation: cv-wave 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-nfc path:nth-child(2) { animation-delay: .09s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-nfc path:nth-child(3) { animation-delay: .18s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-chip .off { animation: cv-off50 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s50 .cv-chip .on { animation: cv-on50 6s infinite both; }

  .sol__card:is(.is-on, :hover, :focus-within) .cv-keyw { animation: cv-key 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s5 .cv-glow { animation: cv-glow5 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s5 .cv-lock { animation: cv-click5 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s5 .cv-ripple { animation: cv-ripple5 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s5 .cv-ripple--2 { animation-delay: .2s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s5 .cv-chip .off { animation: cv-off5 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--s5 .cv-chip .on { animation: cv-on5 6s infinite both; }

  .sol__card:is(.is-on, :hover, :focus-within) .cv-trk { animation: cv-trk 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-knob { animation: cv-knob 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-rev { animation: cv-rev 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-sec { animation: cv-sec 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-chk { animation: cv-chk 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-row { animation: cv-row 6s infinite both; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-row2 { animation-delay: .1s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-row3 { animation-delay: .2s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv-row4 { animation-delay: .3s; }
}

@keyframes cv-phone {
  0% { opacity: 0; translate: -36cqw 30cqw; rotate: -20deg; scale: .9; }
  15% { opacity: 1; translate: -19cqw 13cqw; rotate: -4deg; scale: 1; }
  88% { opacity: 1; translate: -19cqw 13cqw; rotate: -4deg; scale: 1; }
  97%, 100% { opacity: 0; translate: -30cqw 22cqw; rotate: -12deg; scale: .95; }
}
@keyframes cv-ok { 0%, 26% { opacity: 0; scale: .4; } 33% { opacity: 1; scale: 1.12; } 38%, 88% { opacity: 1; scale: 1; } 96%, 100% { opacity: 0; scale: 1; } }
@keyframes cv-glow { 0%, 26% { opacity: 0; } 36%, 88% { opacity: 1; } 98%, 100% { opacity: 0; } }
@keyframes cv-click50 { 0%, 26%, 38%, 100% { scale: 1; } 31% { scale: 1.03; } }
@keyframes cv-ripple50 { 0%, 27% { opacity: .95; scale: .2; } 47%, 100% { opacity: 0; scale: 2.4; } }
@keyframes cv-wave { 0%, 18% { opacity: 0; } 25% { opacity: 1; } 45%, 88% { opacity: .5; } 98%, 100% { opacity: 0; } }
@keyframes cv-off50 { 0%, 22% { opacity: 1; } 28%, 100% { opacity: 0; } }
@keyframes cv-on50 { 0%, 27% { opacity: 0; scale: .86; } 33% { opacity: 1; scale: 1.08; } 38%, 90% { opacity: 1; scale: 1; } 97%, 100% { opacity: 0; scale: 1; } }

@keyframes cv-key {
  0% { opacity: 0; translate: -19cqw 58cqw; rotate: -82deg; }
  8% { opacity: 1; translate: -19cqw 58cqw; rotate: -82deg; animation-timing-function: cubic-bezier(.2, .8, .3, 1); }
  28% { opacity: 1; translate: -24cqw 45cqw; rotate: -113deg; animation-timing-function: ease-in-out; }
  44% { translate: -17.2cqw 41.4cqw; rotate: -116.6deg; animation-timing-function: ease-in; }
  52% { translate: -9.2cqw 37.3cqw; rotate: -116.6deg; animation-timing-function: cubic-bezier(.3, 0, .2, 1); }
  58%, 88% { opacity: 1; translate: -4.7cqw 35.1cqw; rotate: -116.6deg; }
  95% { opacity: 1; translate: -14cqw 40cqw; rotate: -116.6deg; }
  99%, 100% { opacity: 0; translate: -19cqw 58cqw; rotate: -100deg; }
}
@keyframes cv-glow5 { 0%, 56% { opacity: 0; } 66%, 88% { opacity: 1; } 97%, 100% { opacity: 0; } }
@keyframes cv-click5 { 0%, 56%, 68%, 100% { scale: 1; } 61% { scale: 1.03; } }
@keyframes cv-ripple5 { 0%, 58% { opacity: .95; scale: .2; } 78%, 100% { opacity: 0; scale: 2.4; } }
@keyframes cv-off5 { 0%, 52% { opacity: 1; } 57%, 100% { opacity: 0; } }
@keyframes cv-on5 { 0%, 57% { opacity: 0; scale: .86; } 63% { opacity: 1; scale: 1.08; } 68%, 90% { opacity: 1; scale: 1; } 97%, 100% { opacity: 0; scale: 1; } }

@keyframes cv-trk { 0%, 30% { fill: #29b6e3; } 36%, 88% { fill: #2c4a62; } 94%, 100% { fill: #29b6e3; } }
@keyframes cv-knob { 0%, 30% { transform: translateX(0); fill: #071521; } 36%, 88% { transform: translateX(-16px); fill: #a9b8c5; } 94%, 100% { transform: translateX(0); fill: #071521; } }
@keyframes cv-rev { 0%, 28% { opacity: 0; translate: -24px 10px; scale: .92; } 34% { opacity: 1; translate: 0 0; scale: 1.04; } 38%, 88% { opacity: 1; translate: 0 0; scale: 1; } 96%, 100% { opacity: 0; translate: -10px 4px; scale: .96; } }
@keyframes cv-sec { 0%, 42% { opacity: 0; translate: 12px -8px; scale: .92; } 50%, 88% { opacity: 1; translate: 0 0; scale: 1; } 96%, 100% { opacity: 0; translate: 6px -4px; scale: .96; } }
@keyframes cv-chk { 0%, 50% { stroke-dashoffset: 20; } 58%, 100% { stroke-dashoffset: 0; } }
@keyframes cv-row { 0% { opacity: 0; translate: 10px 0; } 8%, 92% { opacity: 1; translate: 0 0; } 100% { opacity: 1; translate: 0 0; } }

@media (max-height: 780px) { .cv-chip { height: 26px; min-width: 112px; font-size: .72rem; } }
.sol .product-card .media.cv svg { display: block; }
.sol .product-card .media.cv .cv-mgr { display: block; }
/* les règles génériques « .product-card .media svg » (largeur 42 %) sont plus spécifiques : on les écrase ici */
.sol .product-card .media.cv .cv-chip svg { width: 1.15em; height: 1.15em; }
.sol .product-card .media.cv .cv-ok svg { width: 52%; height: 52%; }
.sol .product-card .media.cv svg.cv-nfc { width: 12cqw; height: auto; }
.sol .product-card .media.cv svg.cv-mgr { width: auto; height: 100%; max-width: 100%; color: inherit; }
.sol .product-card .media.cv .cv-chip { left: auto; right: 12px; }
.cv--mgr .cv-mgr { height: 108%; }

/* ============================ correctifs et améliorations des visuels de fiches ============================ */
/* BUG corrigé : l'onde d'ouverture était visible (petit cercle) AVANT l'ouverture, car son image-clé de départ était opaque. */
@keyframes cv-ripple50 { 0%, 26.9% { opacity: 0; scale: .2; } 27% { opacity: .95; scale: .2; } 47%, 100% { opacity: 0; scale: 2.4; } }
@keyframes cv-ripple5 { 0%, 57.9% { opacity: 0; scale: .2; } 58% { opacity: .95; scale: .2; } 78%, 100% { opacity: 0; scale: 2.4; } }

/* reflet qui balaie la serrure au moment de l'ouverture (le masque est la silhouette du produit) */
.cv-lock::after { content: ""; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: soft-light; opacity: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .95) 50%, transparent 62%) no-repeat; background-size: 280% 100%; background-position: 130% 0;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.cv--s50 .cv-lock::after { -webkit-mask-image: url(../img/home/s50-cylindre-porte.webp); mask-image: url(../img/home/s50-cylindre-porte.webp); }
.cv--s5 .cv-lock::after { -webkit-mask-image: url(../img/home/s5-cylindre-porte.webp); mask-image: url(../img/home/s5-cylindre-porte.webp); }
@keyframes cv-glint50 { 0%, 26% { opacity: 0; background-position: 130% 0; } 27% { opacity: 1; background-position: 130% 0; } 46%, 100% { opacity: 1; background-position: -30% 0; } }
@keyframes cv-glint5 { 0%, 57% { opacity: 0; background-position: 130% 0; } 58% { opacity: 1; background-position: 130% 0; } 77%, 100% { opacity: 1; background-position: -30% 0; } }

/* profondeur : les visuels suivent légèrement le pointeur (souris uniquement) */
.cv-rig, .cv-mrig { transform: perspective(700px) rotateY(calc(var(--tx, 0) * 5deg)) rotateX(calc(var(--ty, 0) * -4deg)); transition: transform .35s var(--ease-out); }

/* ============================ iLOQ Manager : « programmer une serrure puis une clé » (boucle de 5,5 s) ============================
   Portable (photo iLOQ) en haut à gauche ; dock (photo iLOQ) en bas à droite ; la serrure est posée debout sur la plaque du dock,
   capuchon vers le haut (même point de vue que le dock) ; la clé est posée à plat sur le lecteur, au bout du câble.
   Les états de base sont les états FINAUX : sans mouvement ou hors écran, la scène terminée s'affiche. */
.cv-mrig::before { content: ""; position: absolute; left: 6%; right: 0; bottom: -2%; height: 30%; z-index: 0; pointer-events: none; border-radius: 50%; background: radial-gradient(closest-side, rgba(41, 182, 227, .2), rgba(41, 182, 227, .06) 60%, transparent 78%); }
.sol .product-card .media.cv .cv-mrig { position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: min(96cqw, 154cqh); max-height: none; aspect-ratio: 100 / 62; container-type: inline-size; }
.m8-laptop { position: absolute; left: 0; top: 16%; width: 62%; aspect-ratio: 900 / 523; }
.m8-prog { position: absolute; left: 41.5%; bottom: 2.0%; width: 57.5%; aspect-ratio: 1644 / 764; }
.sol .product-card .media.cv .m8-laptop img, .sol .product-card .media.cv .m8-prog > img { position: absolute; max-width: none; max-height: none; }
.sol .product-card .media.cv .m8-laptop > img { inset: 0; width: 100%; height: 100%; filter: brightness(.9) saturate(.95) drop-shadow(0 2cqw 2.4cqw rgba(2, 10, 18, .5)); }
.sol .product-card .media.cv .m8-laptop svg, .sol .product-card .media.cv .m8-prog > svg { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; overflow: visible; pointer-events: none; }
.sol .product-card .media.cv .m8-dock { z-index: 1; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 2cqw 2.4cqw rgba(2, 10, 18, .6)); }
.m8-under { z-index: 2; } .m8-over { z-index: 5; }
.sol .product-card .media.cv .m8-lock { z-index: 3; left: 9.53%; top: -47.83%; width: 19.62%; height: 106.99%; transform-origin: 50% 100%; filter: drop-shadow(0 .8cqw .9cqw rgba(0, 0, 0, .55)); }
.m8-keyw { position: absolute; z-index: 4; left: 28.83%; top: 79.37%; width: 29.10%; transform-origin: 50% 50%; }
.sol .product-card .media.cv .m8-keyw img { position: static; display: block; width: 100%; height: auto; max-width: none; filter: drop-shadow(0 .6cqw .6cqw rgba(0, 0, 0, .55)); }
.m8-bar { fill: #8ee3ff; transform-box: fill-box; transform-origin: 0 50%; opacity: 0; }
.m8-tile { fill: rgba(41, 182, 227, .16); stroke: #29b6e3; stroke-width: 3; }
.m8-click, .m8-ring, .m8-prog-ring { fill: none; stroke: #5fd2f5; stroke-width: 4; opacity: 0; }
.m8-prog-ring { stroke-width: 7; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; stroke: #8ee3ff; opacity: .5; }
.m8-click, .m8-ring, .m8-prog-ring, .m8-bglow, .m8-shadow, .m8-kshadow, .m8-pglow, .m8-led { transform-box: fill-box; transform-origin: center; }
.m8-scan { position: absolute; z-index: 4; left: 9.53%; width: 19.62%; top: 56.96%; aspect-ratio: 3.4 / 1; border-radius: 50%; border: .45cqw solid rgba(160, 230, 255, .95); box-shadow: 0 0 1.4cqw rgba(41, 182, 227, .9), inset 0 0 1.1cqw rgba(41, 182, 227, .55); opacity: 0; pointer-events: none; }
.m8-cursor { opacity: 0; transform-origin: 0 0; }
.m8-cursor path { fill: #fff; stroke: #071521; stroke-width: 2.5; stroke-linejoin: round; filter: drop-shadow(0 4px 4px rgba(0, 0, 0, .4)); }
.cv-toast { position: absolute; z-index: 7; display: flex; align-items: center; gap: 1.1cqw; padding: .9cqw 1.9cqw .9cqw 1cqw; border-radius: 999px;
  background: #fff; color: #13222f; font-weight: 700; font-size: 2.86cqw; line-height: 1; white-space: nowrap; box-shadow: 0 2cqw 4cqw -1.4cqw rgba(0, 0, 0, .6); }
.cv-toast i { display: grid; place-items: center; width: 4.6cqw; aspect-ratio: 1; border-radius: 50%; flex: none; }
.cv-toast--good i { background: #e0f6f1; color: #12907f; }
.sol .product-card .media.cv .cv-toast svg { width: 58%; height: 58%; }
.cv--mgr .cv-toast svg path { stroke-dasharray: 24; stroke-dashoffset: 0; }
.cv--mgr .cv-toast1 { top: 2%; left: 54cqw; }
.cv--mgr .cv-toast2 { top: 13.5%; left: 66cqw; }

@media (prefers-reduced-motion: no-preference) {
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr :is(.cv-mrig, .m8-laptop, .m8-dock, .m8-cursor, .m8-tile, .m8-click, .m8-bar, .m8-scan, .m8-lock, .m8-keyw, .m8-shadow, .m8-kshadow, .m8-bglow, .m8-pglow, .m8-led, .m8-ring, .m8-prog-ring, .cv-toast, .cv-toast svg path) { animation-duration: 5.5s; animation-iteration-count: infinite; animation-fill-mode: both; animation-timing-function: linear; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .cv-mrig { animation-name: m8-rig; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-laptop { animation-name: m8-laptop; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-dock { animation-name: m8-dock; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-cursor { animation-name: m8-cursor; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-tileL { animation-name: m8-tileL; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-tileK { animation-name: m8-tileK; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-clickL { animation-name: m8-clickL; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-clickK { animation-name: m8-clickK; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-lock { animation-name: m8-lock; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-barL { animation-name: m8-barL; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-barK { animation-name: m8-barK; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-scan { animation-name: m8-scan; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-shadow { animation-name: m8-shadow; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-kshadow { animation-name: m8-kshadow; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-bglow { animation-name: m8-bglow; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-led { animation-name: m8-led; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-dring { animation-name: m8-dring; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-ring2 { animation-delay: .22s; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-keyw { animation-name: m8-key; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-pglow { animation-name: m8-pglow; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-pring { animation-name: m8-pring; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .m8-prog-ring { animation-name: m8-progress; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .cv-toast1 { animation-name: m8-toast1; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .cv-toast2 { animation-name: m8-toast2; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .cv-toast1 svg path { animation-name: m8-chk1; }
  .sol__card:is(.is-on, :hover, :focus-within) .cv--mgr .cv-toast2 svg path { animation-name: m8-chk2; }
}
@keyframes m8-rig { 0% { opacity: 0; } 3%, 94% { opacity: 1; } 99%, 100% { opacity: 0; } }
@keyframes m8-laptop { 0% { opacity: 0; translate: -4cqw 2cqw; } 6%, 100% { opacity: 1; translate: 0 0; animation-timing-function: ease-out; } }
@keyframes m8-dock { 0% { opacity: 0; translate: 4cqw 3cqw; } 7%, 100% { opacity: 1; translate: 0 0; animation-timing-function: ease-out; } }
@keyframes m8-cursor {
  0%, 4% { opacity: 0; translate: 90px 480px; scale: 1; }
  6% { opacity: 1; translate: 90px 480px; animation-timing-function: cubic-bezier(.4, 0, .2, 1); }
  15.5% { opacity: 1; translate: 232px 362px; scale: 1; }
  16.5% { translate: 232px 362px; scale: .8; }
  18%, 40% { opacity: 1; translate: 232px 362px; scale: 1; animation-timing-function: cubic-bezier(.4, 0, .2, 1); }
  45% { opacity: 1; translate: 382px 149px; scale: 1; }
  46% { translate: 382px 149px; scale: .8; }
  47.5%, 58% { opacity: 1; translate: 382px 149px; scale: 1; }
  64%, 100% { opacity: 0; translate: 382px 149px; scale: 1; }
}
@keyframes m8-tileL { 0%, 16.4% { opacity: 0; } 16.5% { opacity: 1; } 40%, 94% { opacity: .9; } 99%, 100% { opacity: 0; } }
@keyframes m8-tileK { 0%, 45.9% { opacity: 0; } 46% { opacity: 1; } 58%, 94% { opacity: .9; } 99%, 100% { opacity: 0; } }
@keyframes m8-clickL { 0%, 16.4% { opacity: 0; scale: .3; } 16.5% { opacity: .9; scale: .3; } 27%, 100% { opacity: 0; scale: 2.4; } }
@keyframes m8-clickK { 0%, 45.9% { opacity: 0; scale: .3; } 46% { opacity: .9; scale: .3; } 56%, 100% { opacity: 0; scale: 2.4; } }
/* la serrure descend, légèrement inclinée, se redresse et se pose sur la plaque du dock */
@keyframes m8-lock {
  0%, 18% { opacity: 0; translate: 0 -14cqw; rotate: -7deg; animation-timing-function: cubic-bezier(.5, 0, .85, .55); }
  21% { opacity: 1; translate: 0 -10cqw; rotate: -5deg; animation-timing-function: cubic-bezier(.5, 0, .85, .55); }
  30% { opacity: 1; translate: 0 0; rotate: 0deg; animation-timing-function: ease-out; }
  32% { translate: 0 .3cqw; scale: 1.03 .95; animation-timing-function: ease-out; }
  35% { translate: 0 -.6cqw; scale: .99 1.015; animation-timing-function: ease-in-out; }
  38%, 94% { opacity: 1; translate: 0 0; rotate: 0deg; scale: 1 1; }
  99%, 100% { opacity: 0; translate: 0 0; rotate: 0deg; scale: 1 1; }
}
@keyframes m8-shadow { 0%, 22% { opacity: 0; scale: 1.8; } 30.5%, 94% { opacity: 1; scale: 1; } 99%, 100% { opacity: 0; scale: 1; } }
@keyframes m8-bglow { 0%, 29% { opacity: 0; scale: .6; } 37%, 92% { opacity: 1; scale: 1; } 98%, 100% { opacity: 0; scale: 1; } }
@keyframes m8-led { 0%, 30% { opacity: 0; scale: .6; } 33%, 41% { opacity: 1; scale: 1.7; } 46%, 93% { opacity: .75; scale: 1; } 98%, 100% { opacity: 0; scale: 1; } }
@keyframes m8-dring { 0%, 30.4% { opacity: 0; scale: .5; } 30.5% { opacity: .95; scale: .5; } 44%, 100% { opacity: 0; scale: 2.2; } }
/* la clé tombe du dessus sur le lecteur (plus grande au départ, elle se pose en tournant puis rebondit) */
@keyframes m8-key {
  0%, 47.5% { opacity: 0; translate: 4cqw -19cqw; scale: 1.35; rotate: 24deg; animation-timing-function: cubic-bezier(.4, 0, .9, .6); }
  50% { opacity: 1; translate: 3cqw -14cqw; scale: 1.28; rotate: 20deg; animation-timing-function: cubic-bezier(.5, 0, .85, .55); }
  57.5% { opacity: 1; translate: 0 0; scale: 1; rotate: -3deg; animation-timing-function: ease-out; }
  59% { translate: 0 .4cqw; scale: 1.05 .93; rotate: 0deg; animation-timing-function: ease-out; }
  61.5% { translate: 0 -.9cqw; scale: .99 1.02; animation-timing-function: ease-in-out; }
  64%, 94% { opacity: 1; translate: 0 0; scale: 1; rotate: 0deg; }
  99%, 100% { opacity: 0; translate: 0 0; scale: 1; rotate: 0deg; }
}
@keyframes m8-barL { 0%, 17% { opacity: 0; transform: scaleX(0); } 18% { opacity: 1; transform: scaleX(0); } 29% { opacity: 1; transform: scaleX(1); } 33% { opacity: 1; transform: scaleX(1); } 36%, 100% { opacity: 0; transform: scaleX(1); } }
@keyframes m8-barK { 0%, 46.5% { opacity: 0; transform: scaleX(0); } 47.5% { opacity: 1; transform: scaleX(0); } 58% { opacity: 1; transform: scaleX(1); } 62% { opacity: 1; transform: scaleX(1); } 65%, 100% { opacity: 0; transform: scaleX(1); } }
/* anneau de balayage : il monte le long de la serrure, se resserre sur le corps et s'élargit sous le capuchon */
@keyframes m8-scan {
  0%, 34% { opacity: 0; translate: 0 0; scale: 1; }
  35.5% { opacity: 1; translate: 0 0; scale: 1; animation-timing-function: ease-in-out; }
  39% { opacity: 1; translate: 0 -8.8cqw; scale: .66; animation-timing-function: ease-in-out; }
  43% { opacity: 1; translate: 0 -21cqw; scale: .72; animation-timing-function: ease-in; }
  45%, 100% { opacity: 0; translate: 0 -25.3cqw; scale: 1.05; }
}
@keyframes m8-kshadow { 0%, 49% { opacity: 0; scale: 1.6; } 58%, 94% { opacity: 1; scale: 1; } 99%, 100% { opacity: 0; scale: 1; } }
@keyframes m8-pglow { 0%, 58% { opacity: 0; scale: .6; } 66%, 92% { opacity: 1; scale: 1; } 98%, 100% { opacity: 0; scale: 1; } }
@keyframes m8-pring { 0%, 59.4% { opacity: 0; scale: .5; } 59.5% { opacity: .95; scale: .5; } 72%, 100% { opacity: 0; scale: 2.3; } }
@keyframes m8-progress { 0%, 61% { opacity: 0; stroke-dashoffset: 1; scale: 1; } 62% { opacity: 1; stroke-dashoffset: 1; } 74% { opacity: 1; stroke-dashoffset: 0; scale: 1; } 76% { opacity: 1; scale: 1.14; } 79%, 92% { opacity: .55; stroke-dashoffset: 0; scale: 1; } 98%, 100% { opacity: 0; stroke-dashoffset: 0; scale: 1; } }
@keyframes m8-toast1 { 0%, 40% { opacity: 0; translate: 0 10px; scale: .9; } 45% { opacity: 1; translate: 0 0; scale: 1.06; } 48%, 94% { opacity: 1; translate: 0 0; scale: 1; } 99%, 100% { opacity: 0; translate: 0 0; scale: 1; } }
@keyframes m8-toast2 { 0%, 75% { opacity: 0; translate: 0 10px; scale: .9; } 80% { opacity: 1; translate: 0 0; scale: 1.06; } 83%, 94% { opacity: 1; translate: 0 0; scale: 1; } 99%, 100% { opacity: 0; translate: 0 0; scale: 1; } }
@keyframes m8-chk1 { 0%, 42% { stroke-dashoffset: 24; } 48%, 100% { stroke-dashoffset: 0; } }
@keyframes m8-chk2 { 0%, 77% { stroke-dashoffset: 24; } 83%, 100% { stroke-dashoffset: 0; } }

/* ==================================================== MARQUE EASY KEY ACCESS ====
   Signature de la société : bandeau sous le hero des pages intérieures, signature de clôture, pied de page.
   Réutilise le logo animé de l'en-tête (.brand-mark) : il « lit » une clé toutes les 6 s. */
.eka-sign { background: var(--navy-950); border-top: 1px solid rgba(255, 255, 255, .07); border-bottom: 1px solid rgba(255, 255, 255, .07); position: relative; overflow: hidden; }
.eka-sign::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(420px 120px at 12% 50%, rgba(41, 182, 227, .16), transparent 70%); }
.eka-sign__in { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 14px 40px; padding: 18px 20px; }
.eka-sign__brand { display: flex; align-items: center; color: var(--white); }
.eka-sign ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 30px; color: var(--slate-100); font-size: .95rem; }
.eka-sign li { display: flex; align-items: center; gap: 8px; }
.eka-sign li svg { width: 18px; height: 18px; color: var(--green); flex: none; }
.eka-sign li strong { color: var(--white); }
@media (prefers-reduced-motion: no-preference) {
  .eka-sign__brand, .eka-sign li { animation: eka-sign-in .8s var(--ease-out) both; }
  .eka-sign li:nth-child(1) { animation-delay: .15s; } .eka-sign li:nth-child(2) { animation-delay: .27s; } .eka-sign li:nth-child(3) { animation-delay: .39s; }
}
@keyframes eka-sign-in { from { opacity: 0; translate: 0 10px; } to { opacity: 1; translate: 0 0; } }
@media (max-width: 760px) { .eka-sign__in { flex-direction: column; gap: 12px; } .eka-sign ul { flex-direction: column; align-items: flex-start; gap: 6px; } }

.cta-scene .cta-sign { display: flex; width: fit-content; max-width: 100%; align-items: center; justify-content: center; margin: 34px auto 0; color: var(--slate-300); font-weight: 600; font-size: .98rem; letter-spacing: .01em; position: relative; z-index: 2; }
.cta-scene .cta-sign .brand-mark { width: 58px; height: 22px; margin-right: 22px; }
.cta-scene .cta-sign b { color: var(--white); font-weight: 800; }

/* Téléphone : les fiches solutions s'empilent (pas de rail horizontal) ; on allège chaque fiche pour raccourcir le défilement.
   Le détail (liste à coches) reste sur la page de chaque produit. */
@media (max-width: 760px) {
  .sol:not(.is-live) .product-card ul { display: none; }
  .sol:not(.is-live) .product-card .body { padding: 18px 20px 22px; }
  .sol:not(.is-live) .sol__rail { gap: 16px; }
  .sol:not(.is-live) .sol__intro { margin-bottom: 8px; }
  .sol:not(.is-live) .sol__end { padding-top: 6px; }
}
@media (max-width: 760px) {
  /* la fiche est plus large que haute : on recale les gestes pour qu'ils tiennent dans le cadre */
  .sol:not(.is-live) .cv-rig--s50 { height: 80cqh; left: 23%; }
  .sol:not(.is-live) .cv-rig--s5 { height: 74cqh; left: 16%; }
}

/* ===== Scène « Deux façons d'ouvrir » sur téléphone : faces empilées (pas de pin), lisibles, chacune joue son approche à l'entrée ===== */
.duo.is-stack .duo__state { background: rgba(255, 255, 255, .08); color: var(--slate-100); border-color: rgba(255, 255, 255, .14); }
.duo.is-stack .duo__state .on { display: none; } .duo.is-stack .duo__state .off { display: inline-flex; }
.duo.is-stack .duo__side.is-open .duo__state { background: var(--white); color: var(--navy-900); border-color: transparent; }
.duo.is-stack .duo__side.is-open .duo__state .off { display: none; } .duo.is-stack .duo__side.is-open .duo__state .on { display: inline-flex; }
.duo.is-stack .duo__side.is-open .duo__lock { filter: drop-shadow(0 26px 30px rgba(0, 0, 0, .5)) drop-shadow(0 0 26px rgba(41, 182, 227, .55)); }
.duo.is-stack .duo__nfc { opacity: var(--a); }
@media (max-width: 860px) {
  .duo.is-stack .duo__stage { display: block; min-height: 0; padding: 44px 0 48px; }
  .duo.is-stack .duo__caps { min-height: 0; }
  .duo.is-stack .duo__sides { display: grid; grid-template-columns: 1fr; grid-template-rows: none; gap: 34px; margin-top: 30px; padding: 0 16px; }
  .duo.is-stack .duo__divider { display: none; }
  .duo.is-stack .duo__side { grid-template-rows: auto auto; background: rgba(255, 255, 255, .03); border: 1px solid rgba(255, 255, 255, .08); border-radius: 22px; padding: 14px 14px 20px; }
  .duo.is-stack .duo__scene { height: min(72vw, 300px); min-height: 0; }
  .duo.is-stack .duo__rig { top: 47%; right: 5%; width: min(64cqw, 118cqh); }
  .duo.is-stack .duo__side--s5 .duo__rig { width: min(64cqw, 150cqh); }
  .duo.is-stack .duo__state { bottom: 4px; font-size: .84rem; padding: 8px 14px; }
  .duo.is-stack .duo__copy { max-width: none; padding: 18px 6px 0; }
  .duo.is-stack .duo__copy .tag { display: block; font-size: .7rem; }
  .duo.is-stack .duo__copy h3 { font-size: 1.2rem; margin: .2em 0 .35em; }
  .duo.is-stack .duo__copy p { display: block; font-size: .95rem; }
  .duo.is-stack .duo__bridge { margin-top: 30px; opacity: 1; transform: none; }
}
@media (max-width: 860px) {
  /* ligne « iLOQ Manager » : le titre seul, puis des pastilles (plus de séparateur qui se retrouve en début de ligne) */
  .duo.is-stack .duo__bridge { gap: 8px; }
  .duo.is-stack .duo__bridge strong { flex-basis: 100%; }
  .duo.is-stack .duo__bridge span:not(.btn) + span::before { display: none; }
  .duo.is-stack .duo__bridge span:not(.btn) { padding: 3px 12px; border: 1px solid rgba(255, 255, 255, .16); border-radius: 999px; font-size: .82rem; }
  .duo.is-stack .duo__bridge .btn { margin-top: 10px; }
}
@media (max-width: 860px) {
  /* visuels centrés dans leur carte : le téléphone (à gauche du rig) et la clé comptent dans l'encombrement du groupe */
  .duo.is-stack .duo__side--s50 .duo__rig { left: 24%; right: auto; width: min(64cqw, 118cqh); }
  .duo.is-stack .duo__side--s5 .duo__rig { left: 23%; right: auto; width: min(66cqw, 150cqh); }
}
