/* Motion design — Paul Informatique — Niveau A (CSS vanilla)
   Ajout additif uniquement : ne modifie aucune règle existante du thème. */

/* Accessibilité : coupe toutes les animations/transitions si l'utilisateur le demande.
   S'applique aussi aux animations AOS déjà présentes sur la page. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Micro-interaction boutons principaux : relief au survol, GPU-friendly.
   Le hover ne touche que box-shadow (pas transform) pour ne pas entrer en
   conflit avec l'effet magnétique JS (desktop) qui, lui, pilote translate(x,y). */
.default-btn {
  transition: box-shadow 0.25s ease, transform 0.15s ease;
}

.default-btn:hover,
.default-btn:focus-visible {
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, 0.35);
}

.default-btn:active {
  transform: scale(0.97);
}

/* Hint navigateur pour les formes décoratives animées en parallax (desktop, voir motion.js) */
.shape-image [class^="inner-shape-"] {
  will-change: transform;
}

/* ==========================================================================
   Hero — fond photo Pau / Béarn / Pyrénées (1er slide uniquement)

   Remplacement posé entièrement en CSS, en surchargeant le style inline
   existant du thème (!important) : AUCUNE modification du HTML/DOM du hero.
   C'est délibéré — une tentative précédente d'insertion de nœuds DOM dans
   le hero avait provoqué une erreur d'hydratation React sur cet export
   Next.js. Ici, on ne touche à aucun enfant, aucune structure : juste des
   propriétés CSS sur des éléments déjà existants. Zéro risque équivalent.

   Portée strictement limitée au premier slide via le sélecteur structurel
   :first-child (position dans le DOM, stable, indépendant de l'état actif
   du carousel) — les slides 2 et 3 gardent leur fond d'origine.
   ========================================================================== */

.hero-slider-init-one .swiper-slide:first-child .slide-bg {
  background-image: url("/assets/img/hero/hero-pau-pyrenees-cyber.webp") !important;
  background-position: center 54% !important;
  background-size: cover !important;
  background-color: #07111e;
  background-blend-mode: normal;
  /* Le thème applique nativement un zoom "Ken Burns" (transform:scale(1.2),
     transition 10s) sur .slide-bg, qui recadre les Pyrénées hors champ même
     avec le bon background-position. Neutralisé ici, 1er slide uniquement :
     les slides 2 et 3 gardent l'effet natif intact. */
  transform: none !important;
  /* Photo plus vivante : reglages moderes pour ne pas cramer le ciel ni
     rendre les couleurs artificielles (juste un leger coup de peps). */
  filter: none;
}

/* Photo principale au premier plan : sa hauteur est légèrement inférieure à
   celle du hero pour conserver davantage de rivière, de ville et de
   profondeur. Le fond en cover ci-dessus remplit les côtés sur les écrans
   ultra-larges, sans bande vide ni déformation. */
.hero-slider-init-one .swiper-slide:first-child .slide-bg::after {
  content: "";
  position: absolute;
  inset: auto !important;
  top: 52% !important;
  left: 50% !important;
  width: auto !important;
  height: 96% !important;
  aspect-ratio: 1821 / 864;
  transform: translate(-50%, -50%) !important;
  z-index: 0 !important;
  background-image: url("/assets/img/hero/hero-pau-pyrenees-cyber.webp") !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: 100% 100% !important;
  filter: brightness(1.07) contrast(1.03) saturate(1.05) !important;
  -webkit-mask-image:
    linear-gradient(
      90deg,
      transparent 0%,
      rgba(0, 0, 0, 0.35) 7%,
      #000 18%,
      #000 82%,
      rgba(0, 0, 0, 0.35) 93%,
      transparent 100%
    ),
    linear-gradient(
      180deg,
      transparent 0%,
      #000 5%,
      #000 95%,
      transparent 100%
    );
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(
      90deg,
      transparent 0%,
      rgba(0, 0, 0, 0.35) 7%,
      #000 18%,
      #000 82%,
      rgba(0, 0, 0, 0.35) 93%,
      transparent 100%
    ),
    linear-gradient(
      180deg,
      transparent 0%,
      #000 5%,
      #000 95%,
      transparent 100%
    );
  mask-composite: intersect;
  /* Loop 0 reprise : le calque central était identifiable en ultra-wide
     malgré son masque. La photo est désormais portée par un seul fond. */
  display: none;
}

/* Overlay dégradé : concentré derrière le texte, la ville reste vivante
   au-delà. Round I (retour "photo trop assombrie côté gauche") : pic
   allégé (0.62→0.5) et falloff étalé sur davantage de stops/distance
   (38%→62%, au lieu de 50%) pour une transition plus progressive, sans
   perdre le contraste nécessaire à la lisibilité du texte (jamais 0 avant
   62%). */
.hero-slider-init-one .swiper-slide:first-child .slide-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    100deg,
    rgba(6, 14, 26, 0.38) 0%,
    rgba(6, 14, 26, 0.23) 18%,
    rgba(6, 14, 26, 0.09) 34%,
    rgba(6, 14, 26, 0.02) 50%,
    rgba(6, 14, 26, 0) 60%
  );
}

/* Neutralisation de l'illustration isométrique générique — 1er slide
   uniquement. L'espace libéré laisse simplement voir la photo en dessous :
   c'est la nouvelle composition de droite, sans élément ajouté. */
.hero-slider-init-one .swiper-slide:first-child .img-wrapper img {
  display: none;
}

/* Le texte reste toujours au-dessus du fond photo + overlay */
.item-slider .auto-container {
  position: relative;
  z-index: 2;
}

/* Loop 0 reprise : rapprocher le hero du ratio natif de la photo
   (1821/864 = 2.1076) tant que cette hauteur tient dans le viewport.
   Sur un écran ultra-wide, 100vh devient le plafond : la photo reste
   beaucoup plus complète qu'avec l'ancien bandeau de 820px, sans rendre
   le hero plus haut que l'écran. */
@media (min-width: 992px) {
  .hero-slider.two .swiper .swiper-wrapper {
    height: min(100vh, calc(100vw * 864 / 1821));
  }

  .hero-slider.two .swiper .swiper-wrapper .item-slider {
    height: 100%;
  }
}

@media (max-width: 991px) {
  .hero-slider-init-one .swiper-slide:first-child .slide-bg {
    /* Mobile conservé à l'identique pendant la Loop 0. */
    background-position: center 0% !important;
  }
  .hero-slider-init-one .swiper-slide:first-child .slide-bg::after {
    display: none;
  }
  /* Sur mobile le texte occupe toute la largeur : overlay vertical uniforme
     plutôt que le dégradé horizontal desktop. */
  .hero-slider-init-one .swiper-slide:first-child .slide-bg::before {
    background: linear-gradient(
      180deg,
      rgba(6, 14, 26, 0.9) 0%,
      rgba(6, 14, 26, 0.72) 55%,
      rgba(6, 14, 26, 0.55) 100%
    );
  }
}

/* Icônes décoratives flottantes du thème (bouclier, empreinte, anneau,
   engrenage, cube, etc.) — masquées uniquement dans le hero. La classe
   ".shape-image" est réutilisée telle quelle dans 8 AUTRES sections de la
   page (contact, blog, devis...) : le sélecteur est donc volontairement
   scopé via l'ancêtre unique ".hero-slider" pour ne toucher qu'à
   l'occurrence du hero et laisser les 8 autres intactes. */
.hero-slider .shape-image {
  display: none;
}

/* ==========================================================================
   Hero — réseau animé, bouclier, cartes services (1er slide uniquement)

   Tous les éléments ci-dessous (.hero-network, .hero-shield,
   .hero-service-cards) sont CRÉÉS EN JS, après window.load + délai, jamais
   en HTML statique — seule méthode qui évite l'erreur d'hydratation React
   déjà rencontrée sur cet export Next.js quand on modifie le DOM du hero
   trop tôt. Ces règles CSS stylent des éléments qui n'existent pas encore
   au chargement de la page : c'est normal et sans risque, le CSS ne fait
   qu'attendre que motion.js les insère.
   ========================================================================== */

.item-slider {
  position: relative;
}

/* --- Conteneur dynamique (réseau + bouclier) — V2 navigation/mode ---
   Attaché en JS au wrapper interne stable (.swiper-fade.swiper-initialized
   > .swiper-wrapper, jamais recréé par Swiper lors des changements de
   slide) plutôt qu'à .item-slider (un par slide) : le réseau/bouclier
   restent donc visibles sur les 3 slides sans être reconstruits à chaque
   changement. Ce wrapper porte aussi le z-index:9 natif du thème qui forme
   le contexte d'empilement de tout le carousel — y attacher réseau/
   bouclier/cartes (plutôt qu'à .hero-slider-init-one, un niveau au-dessus,
   qui serait un FRÈRE de ce contexte et se retrouverait peint derrière lui
   quel que soit son propre z-index) est nécessaire pour que les z-index
   d'origine (1 sous le texte, 3 au-dessus) restent valides. Positionné en
   absolute+inset:0, relatif à ce même wrapper (position:relative natif).
   La classe hero-mode-* (posée/mise à jour par motion.js selon le slide
   actif) pilote les variations d'intensité ci-dessous — un seul réseau/
   bouclier, pas trois systèmes séparés. --- */
.hero-dynamic-extras {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

/* --- Réseau SVG animé --- */
.hero-network {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}

/* Calque étiré exactement sur le hero (100% x 100%) : chaque coordonnée du
   SVG correspond directement à un % de largeur/hauteur du hero, ce qui
   permet de répartir les points du réseau sur toute la ville (et pas dans
   un coin) avec un mapping prévisible. Léger étirement du SVG accepté
   (aspect ratio non préservé) : négligeable sur du simple trait/icônes. */
.hero-network__svg {
  position: absolute;
  inset: 0;
  /* Round G/H/I : opacité globale du calque (lignes + points + halos
     ensemble, un seul chiffre donc aucune animation JS par <path> cassée)
     abaissée par étapes 0.95→0.8→0.72→0.58 (retour "le réseau domine
     encore trop la zone droite"). Note : le fichier SVG lui-même contient
     un cluster de points côté droit resté à pleine opacité (contrairement
     aux 3 autres groupes, déjà atténués individuellement) — un correctif
     ciblé sur CE cluster précis nécessiterait d'éditer
     hero-network-overlay-v2.svg, hors du périmètre autorisé ce round
     (assets/img/hero/*.webp uniquement) : la réduction ci-dessous, plus
     globale, reste le levier disponible dans ce round. */
  opacity: 0.58;
}

/* Loop 2 — les anciens cercles SVG et les petites liaisons d'essai Round L
   sont neutralisés. Les cinq .flow-path et #flow-halos restent intacts. */
.hero-network__svg .legacy-static-nodes,
.hero-network__svg .legacy-round-l-links {
  display: none;
}

/* Loop 3 — l'ancien maillage secondaire reste présent dans le SVG pour un
   rollback immédiat, mais n'est plus affiché : ses anciennes destinations
   ont été neutralisées en Loop 2 et plusieurs traits étaient orphelins. */
.hero-network__svg .legacy-network-mesh {
  display: none;
}

/* Loop 3 — liaisons précises, secondaires par rapport aux points premium.
   Ce calque occupe le hero complet (même repère que Loop 2), indépendamment
   du calque réseau plafonné à droite en ultra-wide. */
.hero-premium-links {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}

.hero-premium-links__svg,
.hero-premium-links__svg > svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.hero-premium-links .premium-link-set {
  display: none;
  fill: none;
  stroke: #48dfff;
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: url("#premium-link-glow");
}

.hero-premium-links .premium-link-set--desktop {
  display: none;
}

.hero-mode-cyber
  .hero-premium-links
  .premium-link-set--desktop.premium-link-set--audit {
  display: inline;
  opacity: 0.28;
}

.hero-mode-pentest
  .hero-premium-links
  .premium-link-set--desktop.premium-link-set--pentest {
  display: inline;
  opacity: 0.31;
}

.hero-mode-infra
  .hero-premium-links
  .premium-link-set--desktop.premium-link-set--infra {
  display: inline;
  opacity: 0.22;
}

@media (min-width: 1600px) and (min-aspect-ratio: 2/1) {
  .hero-mode-cyber
    .hero-premium-links
    .premium-link-set--desktop.premium-link-set--audit,
  .hero-mode-pentest
    .hero-premium-links
    .premium-link-set--desktop.premium-link-set--pentest,
  .hero-mode-infra
    .hero-premium-links
    .premium-link-set--desktop.premium-link-set--infra {
    display: none;
  }

  .hero-mode-cyber
    .hero-premium-links
    .premium-link-set--ultrawide.premium-link-set--audit {
    display: inline;
    opacity: 0.28;
  }

  .hero-mode-pentest
    .hero-premium-links
    .premium-link-set--ultrawide.premium-link-set--pentest {
    display: inline;
    opacity: 0.31;
  }

  .hero-mode-infra
    .hero-premium-links
    .premium-link-set--ultrawide.premium-link-set--infra {
    display: inline;
    opacity: 0.22;
  }
}

/* Loop 2 — nœuds premium issus exclusivement de l'image WebP fournie.
   Le conteneur suit le même repère que le réseau, les pictos et le bouclier.
   La visibilité dépend uniquement de hero-mode-* déjà piloté par Round K. */
.hero-premium-nodes {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}

.hero-premium-node {
  position: absolute;
  display: block;
  width: 26px;
  height: 26px;
  object-fit: contain;
  transform: translate(-50%, -50%);
  opacity: 0;
  visibility: hidden;
  filter: drop-shadow(0 0 6px rgba(41, 211, 255, 0.42));
  transition: opacity 0.3s ease, visibility 0.3s ease;
  user-select: none;
}

.hero-premium-node--sm {
  width: 26px;
  height: 26px;
  --premium-node-opacity: 0.62;
}

.hero-premium-node--md {
  width: 42px;
  height: 42px;
  --premium-node-opacity: 0.76;
}

.hero-premium-node--lg {
  width: 64px;
  height: 64px;
  --premium-node-opacity: 0.9;
}

.hero-mode-cyber .hero-premium-node--audit,
.hero-mode-pentest .hero-premium-node--pentest,
.hero-mode-infra .hero-premium-node--infra {
  opacity: var(--premium-node-opacity);
  visibility: visible;
}

/* Audit : ville, rivière, routes et château, hors texte/CTA/bouclier. */
.hero-premium-node--audit-city { left: 86%; top: 55%; }
.hero-premium-node--audit-river { left: 57%; top: 62%; }
.hero-premium-node--audit-castle { left: 78%; top: 39%; }
.hero-premium-node--audit-road { left: 89%; top: 67%; }
.hero-premium-node--audit-urban { left: 62%; top: 46%; }
.hero-premium-node--audit-east { left: 94%; top: 45%; }
.hero-premium-node--audit-bridge { left: 69%; top: 61%; }
.hero-premium-node--audit-south { left: 76%; top: 71%; }
.hero-premium-node--audit-castle-east { left: 91%; top: 34%; }
.hero-premium-node--audit-road-east { left: 84%; top: 72%; }
.hero-premium-node--audit-north { left: 53%; top: 32%; }

/* Pentest : bâtiments et axes techniques, sans recouvrir laptop/caméra. */
.hero-premium-node--pentest-city { left: 84%; top: 58%; }
.hero-premium-node--pentest-river { left: 55%; top: 68%; }
.hero-premium-node--pentest-east { left: 90%; top: 55%; }
.hero-premium-node--pentest-urban { left: 64%; top: 38%; }
.hero-premium-node--pentest-west { left: 48%; top: 44%; }
.hero-premium-node--pentest-bridge { left: 61%; top: 57%; }
.hero-premium-node--pentest-castle { left: 79%; top: 35%; }
.hero-premium-node--pentest-road { left: 94%; top: 68%; }
.hero-premium-node--pentest-south { left: 70%; top: 72%; }
.hero-premium-node--pentest-north { left: 87%; top: 31%; }

/* Infogérance : serveur, cloud, bâtiments et routes urbaines. */
.hero-premium-node--infra-city { left: 52%; top: 58%; }
.hero-premium-node--infra-river { left: 59%; top: 68%; }
.hero-premium-node--infra-castle { left: 82%; top: 42%; }
.hero-premium-node--infra-east { left: 91%; top: 59%; }
.hero-premium-node--infra-urban { left: 65%; top: 39%; }
.hero-premium-node--infra-west { left: 48%; top: 49%; }
.hero-premium-node--infra-bridge { left: 70%; top: 64%; }
.hero-premium-node--infra-south { left: 78%; top: 72%; }
.hero-premium-node--infra-north-east { left: 93%; top: 36%; }
.hero-premium-node--infra-road { left: 86%; top: 70%; }

@media (min-width: 1600px) and (min-aspect-ratio: 2/1) {
  .hero-premium-node--sm {
    width: 36px;
    height: 36px;
  }

  .hero-premium-node--md {
    width: 58px;
    height: 58px;
  }

  .hero-premium-node--lg {
    width: 86px;
    height: 86px;
  }
}

@media (max-width: 991px) {
  /* Le hero mobile validé reste strictement inchangé pendant Loop 2. */
  .hero-premium-nodes,
  .hero-premium-links {
    display: none;
  }
}
/* V2 : le SVG reseau n'est plus charge en arriere-plan CSS mais injecte en
   inline par motion.js (fetch + innerHTML), pour permettre l'animation des
   halos via getPointAtLength() sur les <path> individuels. Le <svg> injecte
   est dimensionne en JS (width/height 100%, position absolute/inset 0) ;
   ce conteneur ne fait plus que porter l'opacite globale. */

/* --- Bouclier / cadenas — point de convergence du réseau (voir
   hero-network-overlay.svg, lignes de convergence calées sur ~847,351 qui
   correspond au centre réel de ce calque : top:34% right:7% 240x296px).
   Taille plafonnée volontairement (240x296, pas plus) pour rester lisible
   sans écraser la ville — limite validée explicitement. --- */
.hero-shield {
  /* Bouclier premium (image WebP) : devient l'élément visuel principal du
     slide Audit/cybersécurité. Remplace l'ancien SVG (hero-shield-overlay
     -v2.svg, conservé sur le serveur, non supprimé), zéro déformation avec
     background-size:contain quel que soit le fichier utilisé (les 3
     boucliers ci-dessous ont des ratios proches de la boîte).

     Round H (calage sur maquette fournie) : trois fichiers dédiés par
     slide désormais (hero-img-shield-audit / -pentest / -infra, ce dernier
     réutilisant le fichier déjà en place faute de source dédiée), voir
     background-image de base + overrides par mode ci-dessous. Position
     recalée depuis la maquette : dans la référence, le château reste
     visible des DEUX côtés du bouclier (pas collé au bord droit comme
     avant) — déplacé vers le centre (right 12%→20%), hauteur/largeur quasi
     inchangées. Cette boîte (position/taille) reste partagée par les 3
     slides, seuls background-image et opacity changent par mode : un seul
     bouclier, pas trois systèmes séparés. */
  position: absolute;
  top: 26%;
  right: 20%;
  width: 220px;
  height: 270px;
  /* z-index explicite (2, au-dessus des icônes secondaires ci-dessous qui
     vivent dans le contexte d'empilement propre à .hero-network, ancré à
     1) : garantit que le bouclier reste visuellement AU-DESSUS des icônes
     qui empiètent légèrement sur sa zone (ex. laptop en mode infra), sans
     dépendre de l'ordre d'insertion DOM comme c'était le cas implicitement
     avant ce round — le bouclier doit rester l'élément dominant/lisible en
     toute circonstance sur le slide Audit. */
  z-index: 2;
  pointer-events: none;
  /* Bouclier "Audit" par défaut (mode neutre = cyber, 1er slide chargé).
     Voir .hero-mode-pentest / .hero-mode-infra ci-dessous pour les 2
     autres fichiers dédiés. */
  background-image: url("/assets/img/hero/bouclier-loupe-verte-normalized.webp");
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  opacity: 0.8;
  /* Round I (retour "ressemble encore trop à une photo + calques, pas à
     une scène augmentée") : léger halo cyan cohérent avec le glow déjà
     présent sur les points du réseau (filtre SVG node-glow), pour que le
     bouclier semble baigner dans la même lumière que la ville plutôt que
     posé en sticker plat par-dessus. Filter n'affecte ni la géométrie ni
     le ratio (aucun risque de déformation), purement additif. */
  filter: drop-shadow(0 0 12px rgba(51, 229, 255, 0.4));
  /* Round J (retour "désynchronisation" : diagnostic = pas un mauvais
     index/mode, mais un fondu de 0.7s trop long qui laisse un bouclier à
     une opacité intermédiaire pendant ~0.7s après un changement de slide,
     perçu comme "en retard"). Aligné sur la vitesse réelle de la
     transition Swiper (300ms) : le bouclier atteint sa valeur finale au
     même moment que le nouveau texte devient pleinement visible. */
  transition: opacity 0.3s ease;
}

/* ==========================================================================
   Mode visuel par slide (V2) — un seul réseau + un seul bouclier, juste des
   variations d'intensité/opacité selon le slide actif (classe hero-mode-*
   posée sur .hero-dynamic-extras par motion.js, voir setupHeroModeWatcher).
   Pas de duplication de système : .flow-path et .hero-shield existent une
   seule fois dans le DOM, ces règles ne font que moduler leur rendu.

   - cyber ("Audit cybersécurité", 1er slide) : réglages de base ci-dessus,
     inchangés — bouclier fort, réseau actif, ambiance protection.
   - infra ("Assistance et Maintenance" / infogérance, 3e slide) : bouclier
     quasi invisible (l'accent n'est plus la protection mais la continuité
     de service — pas d'effet cybersécurité agressif), réseau très atténué
     (flux ralentis côté JS, voir startNetworkHalos) pour une ambiance
     infrastructure/supervision calme qui ne parasite pas le texte.
   - pentest ("Tests d'intrusion", 2e slide) : bouclier présent mais
     discret, réseau plus contrasté/ciblé (flux accélérés côté JS, ici une
     opacité et une épaisseur de trait accrues) pour une ambiance
     scan/détection plus affirmée. ========================================================================== */
.flow-path {
  /* Round J : même correctif que .hero-shield ci-dessus, 0.7s→0.3s. */
  transition: opacity 0.3s ease, stroke-width 0.3s ease;
}

.hero-mode-infra .hero-shield {
  /* Round G : très discret (0.08). Round I (retour "beaucoup trop
     transparent, le bouclier Infogérance doit être visible pas
     fantomatique") : remonté à 0.52, dans la fourchette 0.45-0.60
     demandée. Fichier dédié "infra" toujours non fourni dans le lot
     d'icônes propres : fallback explicite sur le bouclier déjà en place
     (hero-img-shield.webp, l'ancien fichier générique), conformément à la
     consigne. */
  background-image: url("/assets/img/hero/hero-img-shield.webp");
  opacity: 0.62;
}

.hero-mode-infra .flow-path {
  opacity: 0.22;
}

.hero-mode-pentest .hero-shield {
  /* Round H : fichier dédié pentest (croix de visée + terminal + rupture),
     distinct du bouclier Audit — confirmé correct par inspection directe
     du fichier ET de getComputedStyle en live. Round I (retour "semble
     afficher un symbole audit/loupe/coche") : diagnostic = pas un bug de
     fichier, mais un problème de LISIBILITÉ — à 0.35 les détails distinc-
     tifs (croix, terminal) étaient trop faibles pour se distinguer d'une
     forme générique. Remonté à 0.55 pour que l'identité propre du
     bouclier Pentest soit clairement perceptible, tout en restant sous
     le 0.85 du bouclier Audit (principal) — cohérent avec "discret mais
     réellement distinct". */
  background-image: url("/assets/img/hero/bouclier-fissure-rouge-normalized.webp");
  opacity: 0.63;
}

.hero-mode-pentest .flow-path {
  opacity: 0.78;
  stroke-width: 1.9px;
}

/* ==========================================================================
   Icônes secondaires premium (WebP) — remplacent les petits pictogrammes
   vectoriels dessinés dans hero-network-overlay-v2.svg (cloud, cadenas,
   serveur, wifi, cylindre) par des images premium fournies. Les LIGNES et
   POINTS du réseau (SVG, animation des halos) restent inchangés — seuls
   les pictogrammes de destination sont remplacés/enrichis.

   Positionnées en % À L'INTÉRIEUR de .hero-network (pas d'un autre
   conteneur) : ce calque est déjà celui dont la taille/position a été
   corrigée pour rester au bon ratio sur écran ultra-wide (voir plus bas
   dans ce fichier) — les icônes héritent automatiquement de cette même
   boîte sûre, sans règle ultra-wide supplémentaire à écrire.

   Un seul <img> par rôle (8 au total, jamais dupliqué dans le DOM — voir
   motion.js), positions réutilisées entre slides via de simples règles
   d'opacité / repositionnement scopées par mode, jamais de doublon
   d'élément. Chaque image est dans une boîte de taille fixe avec
   object-fit:contain (jamais de width/height:100% déformant),
   pointer-events:none (purement décoratif, ne bloque jamais les clics
   flèches/CTA/cartes).

   --- Round F (réorganisation composition, suite retour "9 images
   empilées au même endroit, certaines invisibles") : positions/opacités
   entièrement repensées par slide, principe 1 élément principal (le
   bouclier, ou le groupe serveur/cloud/laptop en infra) + 2-3 éléments
   moyens + 1-2 discrets en arrière-plan, jamais 9 éléments au même point.
   Les icônes utilisées sur plusieurs slides (cloud, database, wifi,
   tower5g, laptop) ont donc des coordonnées DIFFÉRENTES par mode
   (règles .hero-mode-* .hero-icon-xxx ci-dessous) plutôt qu'une position
   unique partagée — c'est la cause principale du rendu "collage"
   remonté. La règle de base .hero-icon-xxx ne fixe donc que la TAILLE
   pour ces icônes multi-slides (position neutre = position du mode
   cyber, premier slide affiché au chargement, pour éviter un saut visible
   depuis une position par défaut arbitraire au tout premier fade-in) ;
   les icônes utilisées sur un seul slide (server, phone1, phone2)
   gardent position + taille directement dans leur règle de base. Zone
   approximative du bouclier (haut:26% droite:12% 216x264, soit
   ~x:73-88% y:26-64% dans ce même repère) : sur le slide Audit, les
   icônes secondaires (wifi, cloud, database, smartphone) sont au
   CONTACT de cette zone (contact volontaire ce round, voir retour
   "bouclier isolé") sans jamais en recouvrir le centre ; sur les slides
   où le bouclier est quasi invisible (infra) ou très atténué (pentest),
   quelques légers empiètements plus francs sont assumés, sans jamais
   dépasser son opacité grâce au
   z-index dédié ci-dessus. --- */
.hero-icon {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  z-index: 1;
  /* Round J (retour "les icônes ne se repositionnent pas correctement /
     changent seules quelques secondes après") : diagnostic mesuré en live
     (getComputedStyle à 0/50/200/500/1000ms après un clic réel) — le mode
     hero-mode-* change bien à l'instant du clic, mais chaque icône
     multi-slide (ex. wifi, présente en cyber ET pentest à des positions
     différentes) mettait ~0.7s à glisser/fondre vers sa nouvelle position,
     créant une fenêtre où l'ancien ET le nouveau jeu d'icônes étaient
     partiellement visibles en même temps — perçu comme une désynchroni-
     sation alors que la classe/l'index sous-jacents étaient déjà corrects.
     Aligné sur la vitesse réelle de la transition Swiper (300ms), comme
     .hero-shield et .flow-path ci-dessus : la scène se stabilise au même
     rythme que le changement de texte. */
  transition: opacity 0.3s ease, left 0.3s ease, top 0.3s ease,
    width 0.3s ease, height 0.3s ease;
}

/* Anciens pictogrammes vectoriels du SVG réseau (cadenas, cloud, serveur,
   wifi, base de données) masqués : remplacés par les images premium
   ci-dessus, aux mêmes emplacements — sans ceci, les deux se superposent
   exactement (mêmes coordonnées de calage). id ajouté dans le fichier SVG
   lui-même (hero-network-overlay-v2.svg, sur le groupe concerné) pour
   servir de point d'accroche CSS fiable ; le fichier garde son contenu
   d'origine, cette règle se contente de ne pas l'afficher. */
.hero-network #hero-legacy-icons {
  display: none;
}

.hero-icon img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* Round I : même halo cyan que le bouclier (voir .hero-shield), pour que
     les icônes secondaires paraissent posées dans la même lumière que la
     ville plutôt qu'en calques plats. Purement additif (filter), aucun
     risque de déformation. */
  filter: drop-shadow(0 0 8px rgba(51, 229, 255, 0.39));
}

/* --- Round G (retour "images à peine perceptibles / pas identifiables") :
   tailles et opacités relevées sur l'ensemble des icônes, nouvelle grille
   d'opacité par profondeur — principal 0.7-0.9, secondaire 0.45-0.65,
   arrière-plan 0.25-0.4 — et repositionnement pour former un arc autour du
   bouclier (désormais remonté/déplacé, voir .hero-shield) plutôt qu'un
   cluster distant. --- */

/* --- server : slide infra uniquement (élément principal du trio
   serveur/cloud/laptop) — position + taille directement ici. --- */
.hero-icon-server {
  left: 55%;
  top: 62%;
  width: 100px;
  height: 100px;
}

/* --- database : utilisée sur les 3 slides (toujours secondaire/arrière-
   plan selon le slide), position neutre = cyber. Round H : repositionnée
   à l'angle bas-droit d'après la maquette (cylindre posé sur un immeuble
   à l'extrémité droite de la scène), plus l'ancienne position haut-droit. --- */
.hero-icon-database {
  left: 90%;
  top: 58%;
  width: 70px;
  height: 70px;
}

/* --- cloud : cyber (secondaire) + infra (principal), position neutre =
   cyber. Round H : recalée sur la maquette (haut-centre, au-dessus de la
   ville, plus à gauche/bas que l'estimation précédente). --- */
.hero-icon-cloud {
  left: 60%;
  top: 32%;
  width: 86px;
  height: 86px;
}

/* --- tour 5G : cyber + infra + pentest (toujours secondaire/discrète),
   position neutre = infra (coin haut-droit dans le ciel). Round H : ajout
   du mode cyber avec sa PROPRE position (voir .hero-mode-cyber
   .hero-icon-tower5g), la maquette la montrant en haut-GAUCHE au-dessus
   des collines, à l'opposé de sa place sur infra/pentest. --- */
.hero-icon-tower5g {
  left: 82%;
  top: 38%;
  width: 56px;
  height: 56px;
}

/* --- wifi : cyber (secondaire) + pentest (principal), position neutre =
   cyber. Round H : recalée sur la maquette (au-dessus du bouclier/
   château, plus à droite que l'estimation précédente). --- */
.hero-icon-wifi {
  left: 88%;
  top: 36%;
  width: 82px;
  height: 82px;
}

/* --- phone1 (iPhone) : cyber uniquement, discret mais identifiable.
   Round H : recalée sur la maquette (juste sous/à droite du bouclier,
   côté immeubles). --- */
.hero-icon-phone1 {
  /* Loop 1 (retour "interdiction de superposer bouclier et pictos") :
     76%/64% chevauchait la boîte du bouclier (~50x39px de recouvrement,
     confirmé par calcul géométrique des boîtes CSS). Déplacé sous le
     bouclier, aucun chevauchement avec lui ni avec database (marge >0
     vérifiée dans les deux cas). */
  left: 78%;
  top: 70%;
  width: 50px;
  height: 70px;
}

/* --- camera : pentest uniquement (élément secondaire ajouté ce round,
   thème "surveillance/analyse" cohérent avec le slide Tests d'intrusion),
   positionnée en haut-gauche au-dessus des collines, zone libre sur ce
   slide (loin du laptop/wifi/tour 5G/database/bouclier). --- */
.hero-icon-camera {
  left: 52%;
  top: 43%;
  width: 60px;
  height: 60px;
}

/* --- phone2 : pentest uniquement, clairement visible mais volontairement
   plus petit que le laptop pour ne jamais donner une impression de
   publicité pour smartphone. --- */
.hero-icon-phone2 {
  left: 84%;
  top: 69%;
  width: 58px;
  height: 80px;
}

/* --- laptop : infra (principal) + pentest (principal), position neutre =
   infra. --- */
.hero-icon-laptop {
  left: 86%;
  top: 70%;
  width: 92px;
  height: 92px;
}

/* --- Visibilité + position par mode : chaque image n'apparaît
   (opacity > 0) que sur le(s) slide(s) où elle est prévue, à un
   emplacement propre à ce slide pour éviter tout empilement — opacity:0
   et position neutre par défaut (règles ci-dessus) partout ailleurs. --- */

/* cyber (Audit) : bouclier = élément principal (règle .hero-shield de
   base, 0.85). Round H — composition recalée sur la maquette fournie :
   tour 5G et laptop rejoignent ce slide (absents avant ce round), tous
   deux avec leur PROPRE position (la maquette les place respectivement
   en haut-gauche au-dessus des collines et en bas-centre sur la rivière,
   loin de leur emplacement infra/pentest). Cloud/wifi/database restent
   secondaires (position neutre = leur position cyber, voir plus haut),
   smartphone discret mais identifiable. */
.hero-mode-cyber .hero-icon-cloud {
  opacity: 0.72;
}
.hero-mode-cyber .hero-icon-database {
  opacity: 0.71;
}
.hero-mode-cyber .hero-icon-wifi {
  opacity: 0.72;
}
.hero-mode-cyber .hero-icon-tower5g {
  left: 52%;
  top: 36%;
  opacity: 0.62;
}
.hero-mode-cyber .hero-icon-laptop {
  left: 57%;
  top: 64%;
  opacity: 0.71;
}
.hero-mode-cyber .hero-icon-phone1 {
  opacity: 0.63;
}

/* infra (Infogérance) : trio principal serveur (le plus visible)/cloud/
   laptop désormais dans la plage "principal" (0.7-0.9) et agrandis pour
   être clairement identifiables. Secondaire : database (0.45-0.65).
   Arrière-plan : tour 5G (0.25-0.4). Bouclier quasi invisible (voir
   .hero-mode-infra .hero-shield, 0.08). */
.hero-mode-infra .hero-icon-server {
  /* Round I (retour "ne transmet pas assez infrastructure/serveur") :
     0.8→0.85, en haut de la plage "principal". */
  opacity: 0.82;
}
.hero-mode-infra .hero-icon-cloud {
  left: 60%;
  top: 36%;
  opacity: 0.79;
}
.hero-mode-infra .hero-icon-laptop {
  /* Loop 1 : position de base (80%/58%, héritée) chevauchait le bouclier
     sur ~44x88px. Repositionné à droite/bas du bouclier, aucun
     chevauchement (marge vérifiée avec bouclier, serveur, database,
     tour 5G). */
  left: 86%;
  top: 70%;
  opacity: 0.75;
}
.hero-mode-infra .hero-icon-database {
  /* Loop 1 : 74%/40% était ENTIÈREMENT dans la boîte du bouclier.
     Repositionné à droite/bas, sous la tour 5G, sans chevaucher ni le
     bouclier ni le laptop repositionné ci-dessus. */
  left: 89%;
  top: 58%;
  opacity: 0.67;
}
.hero-mode-infra .hero-icon-tower5g {
  opacity: 0.54;
}

/* pentest (Tests d'intrusion) : laptop clairement visible (principal,
   0.78), wifi bien lisible (haut de la plage secondaire, 0.65), smartphone
   visible mais volontairement plus petit/moins opaque que le laptop pour
   ne pas évoquer une pub téléphone. Tour 5G visible mais secondaire.
   Bouclier discret (voir .hero-mode-pentest .hero-shield, 0.35). Database
   en arrière-plan. */
.hero-mode-pentest .hero-icon-laptop {
  left: 54%;
  top: 65%;
  opacity: 0.82;
}
.hero-mode-pentest .hero-icon-wifi {
  /* Loop 1 : top 20% laissait un espace de ~1px avec le haut du bouclier
     (quasi-contact). Remonté légèrement (18%) pour une marge de sécurité
     réelle. */
  left: 58%;
  top: 35%;
  opacity: 0.72;
}
.hero-mode-pentest .hero-icon-phone2 {
  /* Reste sous l'opacité du laptop (0.8) pour ne jamais dominer, malgré
     l'agrandissement général des tailles ce round. */
  opacity: 0.66;
}
.hero-mode-pentest .hero-icon-tower5g {
  left: 88%;
  top: 38%;
  opacity: 0.55;
}
.hero-mode-pentest .hero-icon-database {
  /* Loop 1 : 71%/45% était ENTIÈREMENT dans la boîte du bouclier.
     Repositionné à droite/bas, sans chevaucher le bouclier ni phone2. */
  left: 63%;
  top: 78%;
  opacity: 0.5;
}
.hero-mode-pentest .hero-icon-camera {
  /* Round H : nouvel élément secondaire (surveillance/analyse), zone
     libre en haut-gauche sur ce slide. Round I : légère hausse pour
     rester perceptible sans zoomer. */
  opacity: 0.64;
}

/* --- Slide "Tests d'intrusion" (pentest) : titre allégé. Mesuré en live,
   le thème applique nativement 46px/55px de hauteur de ligne sur ce titre
   (règle .hero-slider.two .swiper .swiper-wrapper .item-slider
   .slider-content-inner .slider-title, 6 classes) et le texte source
   ("Détectez et corrigez les failles avant qu'elles ne soient exploitées")
   se répartit alors sur 4 lignes — effet massif signalé. Réduction modérée
   de taille + largeur plafonnée pour un meilleur équilibre visuel, message
   commercial inchangé. Scopé via .slider-content-inner.middle, marqueur
   HTML natif du thème présent uniquement sur ce slide (vérifié unique) :
   aucun impact sur les 2 autres slides. Spécificité supérieure à la règle
   native (classe .middle en plus) : pas besoin de !important. --- */
.hero-slider.two .swiper .swiper-wrapper .item-slider .slider-content-inner.middle .slider-title {
  font-size: 36px;
  line-height: 44px;
  max-width: 480px;
}

/* --- Flèches Swiper natives du thème : rendues discrètes (taille réduite),
   sans toucher à leur mécanisme (position/hover/display restent gérés par
   le CSS natif du thème, on ne fait qu'ajouter par-dessus). Scopé à
   .hero-slider pour ne jamais affecter un autre carousel du site qui
   réutiliserait la même classe .hero-button.

   Comportement d'opacité : desktop uniquement (hover:hover and pointer:fine)
   — masquées par défaut, visibles en faible opacité au survol de l'ensemble
   du hero, un peu plus au survol direct de la flèche. Sur mobile (pas de
   hover fiable), on ne touche pas à l'opacité native du thème : le swipe
   tactile reste la navigation prioritaire, conformément à la consigne
   "ne pas alourdir mobile". --- */
.hero-slider .hero-button {
  width: 32px;
  height: 32px;
  font-size: 13px;
  transition: opacity 0.25s ease, background 0.2s linear;
}

@media (hover: hover) and (pointer: fine) {
  .hero-slider .hero-button {
    opacity: 0;
  }

  .hero-slider:hover .hero-button {
    opacity: 0.3;
  }

  .hero-slider .hero-button:hover {
    opacity: 0.6;
  }
}

/* --- CTA hero : style pilule premium, icône bouclier-check intégrée --- */
.inner-btn .default-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  transition: box-shadow 0.3s ease, border-color 0.3s ease, transform 0.15s ease;
  /* Glow "maîtrisé" : moins prononcé qu'avant, plus proche de la référence. */
  box-shadow: 0 0 0 1px rgba(95, 227, 192, 0.25), 0 6px 18px -8px rgba(95, 227, 192, 0.28);
}

.inner-btn .default-btn:hover,
.inner-btn .default-btn:focus-visible {
  box-shadow: 0 0 0 1px rgba(95, 227, 192, 0.5), 0 10px 24px -6px rgba(95, 227, 192, 0.42);
}

.inner-btn .default-btn::before {
  content: "";
  display: inline-block;
  width: 15px;
  height: 15px;
  margin-right: 9px;
  flex: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2'%3E%3Cpath d='M12 2 L21 6 V11 C21 16 17 20.5 12 22 C7 20.5 3 16 3 11 V6 Z'/%3E%3Cpath d='M8.5 12 L11 14.5 L16 9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: contain;
}

.inner-btn .default-btn::after {
  content: "→";
  display: inline-block;
  margin-left: 8px;
  transition: transform 0.25s ease;
}

.inner-btn .default-btn:hover::after {
  transform: translateX(4px);
}

/* --- Titre : accent teal sur un mot, ajouté en JS après hydratation.
   Filet de sécurité : sans la classe (JS non exécuté), le mot garde la
   couleur normale du titre — aucun état caché par défaut. --- */
.hero-title-accent {
  background: linear-gradient(90deg, #5fe3c0, #8fe9d3);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* --- Bandeau de confiance secondaire — DÉSACTIVÉ pour cette passe.
   Jugé surchargeant le bas du hero une fois combiné à la nouvelle barre de
   services ; priorité au hero principal (photo + texte + CTA + réseau +
   bouclier + barre de services). motion.js ne le construit plus non plus
   (voir commentaire dans le JS) — display:none ici en filet de sécurité
   supplémentaire, au cas où. Facilement réactivable plus tard. --- */
.hero-trust-strip {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 5%;
  z-index: 3;
  gap: 18px;
  padding: 0 9%;
  pointer-events: none;
}

.hero-trust-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  color: rgba(234, 255, 248, 0.8);
}

.hero-trust-item__icon {
  font-size: 13px;
  color: #7ff0d2;
  margin-top: 2px;
}

.hero-trust-item__title {
  font-size: 11.5px;
  font-weight: 700;
  color: #ffffff;
  line-height: 1.25;
}

.hero-trust-item__text {
  font-size: 10.5px;
  line-height: 1.25;
  color: rgba(234, 255, 248, 0.65);
}

/* --- Barre de services unique (bas du hero) — remplace les 4 cartes
   glassmorphism séparées par UNE bande fine translucide continue, plus
   proche de la référence (moins "blocs de template"). Le conteneur porte
   le fond/flou/bordure ; chaque item n'a plus de fond/bordure propre, juste
   un séparateur vertical fin entre colonnes. --- */
.hero-service-cards {
  /* bottom abaissé (18.5% -> 12%, correctif superposition) : mesuré en
     live, le CTA des slides "Tests d'intrusion" et "Infogérance" passait
     sous cette barre (jusqu'à 28px de recouvrement) — leur bloc de texte
     (accroche + titre + paragraphe + CTA) est plus haut que celui du 1er
     slide et n'avait plus assez de dégagement au-dessus de la barre.
     Vérifié après coup : le 1er slide (déjà largement dégagé) garde une
     bonne marge, aucun des 3 slides n'est cassé par ce décalage. */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12%;
  z-index: 3;
  display: flex;
  margin: 0 9%;
  border-radius: 10px;
  background: rgba(6, 14, 26, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  overflow: hidden;
  pointer-events: none; /* le conteneur ne capte rien, seules les cartes (enfants) sont cliquables */
}

.hero-card {
  pointer-events: auto;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 6px 12px;
  border-right: 1px solid rgba(255, 255, 255, 0.12);
  color: #eafff8;
  text-decoration: none;
  transition: background 0.25s ease;
}

.hero-card:last-child {
  border-right: none;
}

.hero-card__row {
  display: flex;
  align-items: center;
  gap: 7px;
}

.hero-card__icon {
  font-size: 13px;
  color: #7ff0d2;
  flex: none;
}

.hero-card__title {
  font-size: 12px;
  font-weight: 700;
  color: #ffffff;
  line-height: 1.15;
}

.hero-card__text {
  font-size: 10px;
  line-height: 1.25;
  color: rgba(234, 255, 248, 0.68);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

@media (hover: hover) and (pointer: fine) {
  .hero-card:hover,
  .hero-card:focus-visible {
    background: rgba(95, 227, 192, 0.1);
  }
}

@media (max-width: 991px) {
  .hero-shield {
    display: none;
  }
  /* Icônes premium (WebP) : masquées sur mobile, même logique que le
     bouclier et les cartes ci-dessous — priorité totale à la lisibilité
     du texte sur l'espace réduit, "mobile allégé" déjà validé pour ce
     hero. */
  .hero-icon {
    display: none;
  }
  /* Sur mobile, le texte occupe quasiment toute la largeur (empilement
     vertical) : aucun recadrage ne permet d'éviter complètement les icônes
     du réseau, réparties sur toute la largeur du SVG desktop. Priorité
     donnée à la lisibilité du texte (consigne explicite) : opacité très
     réduite plutôt qu'un recadrage qui laisserait quand même des icônes
     partiellement superposées au texte. */
  .hero-network__svg {
    opacity: 0.1;
  }
  /* Cartes masquées sur mobile : testé en conditions réelles, le texte
     (accroche + titre 3 lignes + sous-titre + CTA) occupe déjà toute la
     hauteur fixe du slide (.item-slider a une hauteur imposée par le thème
     pour le carousel, qui ne s'agrandit pas). Superposer les 4 cartes par
     -dessus provoquait un chevauchement direct sur le titre et le bouton —
     inacceptable. Priorité au texte/CTA, conformément à la consigne
     "mobile allégé" déjà validée précédemment pour ce hero. */
  .hero-service-cards {
    display: none;
  }
  .hero-trust-strip {
    display: none;
  }
}

/* ==========================================================================
   Hero mobile — suppression du grand espace blanc après le hero.

   Cause réelle (vérifiée par inspection DOM live) : le hero est un Swiper
   en mode fade avec 3 slides réels (contenus différents), et le vrai
   wrapper flex des slides est imbriqué à 2 niveaux :
   .hero-slider-init-one > .swiper-wrapper.p-relative
     > DIV.swiper.swiper-fade.swiper-initialized > .swiper-wrapper (celui-ci)
       > .swiper-slide (x3, les vrais slides)
   Un conteneur flex-row prend la hauteur de son enfant le plus grand : le
   slide 3 (texte le plus long) impose donc la hauteur du hero même quand
   le slide 1 (le plus court, actif par défaut) est affiché — d'où le vide
   sous le texte/CTA avant la section suivante.

   Correction : sur mobile uniquement, les slides inactifs sont sortis du
   flux (position:absolute + opacity:0 + visibility:hidden, nécessaires
   tous les trois — sans l'opacity/visibility le slide inactif redevient
   visible par-dessus l'actif après un swipe, bug constaté en test avant
   correction). Seul le slide actif compte alors pour la hauteur du
   conteneur flex, qui suit donc exactement le contenu réellement affiché.
   Le swipe tactile reste fonctionnel (les slides 2/3 restent atteignables
   et s'affichent à leur pleine hauteur naturelle une fois actifs, sans
   troncature). Aucune hauteur fixe, aucune marge négative : la hauteur
   reste 100% dérivée du contenu, quel que soit l'appareil. Desktop non
   affecté : propriétés scopées dans ce même @media (max-width: 991px)
   déjà utilisé par les autres réglages mobiles du hero ci-dessus.
   ========================================================================== */
@media (max-width: 991px) {
  .hero-slider-init-one .swiper-fade.swiper-initialized > .swiper-wrapper {
    align-items: stretch;
  }

  .hero-slider-init-one .swiper-fade.swiper-initialized > .swiper-wrapper > .swiper-slide > .item-slider {
    height: 100%;
  }

  .hero-slider-init-one .swiper-fade.swiper-initialized > .swiper-wrapper > .swiper-slide:not(.swiper-slide-active) {
    position: absolute !important;
    top: 0;
    left: 0;
    width: 100%;
    opacity: 0 !important;
    visibility: hidden !important;
    pointer-events: none !important;
  }
}

/* ==========================================================================
   Bouton retour en haut (.scroll-to-top, injecté par le thème) — mobile
   uniquement. Vérifié par mesure réelle : le bouton (40x40, bottom/right:40)
   se superposait visuellement au fond des cartes Particuliers/Professionnels
   sur toute la largeur testée (360-430px). Taille réduite et rapprochée des
   bords pour rester discret sans perdre de zone tactile confortable.
   !important nécessaire et vérifié : le style du bouton est injecté par le
   thème via un <style> CSS-in-JS (styled-jsx) ajouté dynamiquement après
   hydratation, donc plus tard dans l'ordre du DOM que ce fichier — à
   spécificité égale (un seul sélecteur de classe des deux côtés), l'ordre
   fait gagner le styled-jsx sans !important (test effectué, confirmé).
   Desktop non affecté (scopé à ce même breakpoint 991px). --- */
@media (max-width: 991px) {
  .scroll-to-top {
    width: 36px !important;
    height: 36px !important;
    right: 14px !important;
    bottom: 14px !important;
  }
}

/* ==========================================================================
   Cartes Particuliers / Professionnels (.audience-card) — hauteur mobile
   réduite modérément. Scopé à .audience-card (et non .cyber-card seul) :
   .cyber-card est aussi utilisé par 4 autres cartes sans rapport, plus bas
   sur la page (section "pourquoi nous choisir" — Proximité terrain, Un
   seul interlocuteur, Suivi personnalisé, Assistance à distance),
   découvert et corrigé pendant les tests pour ne pas les affecter.
   Vérifié par mesure réelle : padding (34px), taille + marge du titre et
   marge du texte sont posés en style inline par le composant React du
   thème, d'où le !important ciblé (nécessaire et confirmé par test, comme
   pour .scroll-to-top). Bouton, couleurs, bordures, effet fx-tilt : non
   touchés. Desktop non affecté (scopé à ce même breakpoint 991px). --- */
@media (max-width: 991px) {
  .audience-card {
    padding-top: 24px !important;
    padding-bottom: 24px !important;
  }

  .audience-card h3 {
    font-size: 23px !important;
    margin-bottom: 10px !important;
  }

  .audience-card p {
    margin-bottom: 14px !important;
  }

  .audience-card .service-badge {
    margin-bottom: 10px;
  }
}

/* ==========================================================================
   Hero mobile — typographie et espacements (titre/sous-titre/CTA).
   Breakpoint volontairement plus strict (575.98px, "smartphone" au sens
   Bootstrap) que le reste du fichier (991px) : demande explicite, pour ne
   pas affecter les grands telephones/tablettes en portrait/paysage.

   Aucun !important — mais un simple sélecteur court (.hero-slider-init-one
   .slider-title / .description) ne suffisait PAS : le thème possède ses
   propres règles responsives natives sur ces éléments avec un sélecteur à
   7 niveaux de classes (.hero-slider.two .swiper .swiper-wrapper
   .item-slider .slider-content-inner .slider-title, idem pour
   .description), bien plus spécifique — vérifié précisément par inspection
   des règles CSS appliquées (pas une supposition). Sans égaler cette
   spécificité, la règle est silencieusement ignorée quel que soit l'ordre
   de chargement. Solution : égaler exactement cette spécificité (7 classes,
   mêmes classes réellement présentes dans l'arbre DOM du titre/sous-titre)
   plutôt que d'ajouter !important — à spécificité égale, cette feuille
   étant chargée en dernier, notre règle l'emporte naturellement par ordre
   de cascade. Testé et confirmé en live avant application.
   Le CTA (.inner-btn .default-btn, 3 classes) n'a pas ce problème : aucune
   règle native aussi spécifique ne le cible, le sélecteur court suffit.
   Sélecteur CTA corrigé : la classe réelle du bouton est .default-btn
   (dans .inner-btn .default-btn), pas .theme-btn (vérifié, .theme-btn
   n'existe pas sur cet élément).
   S'applique aux 3 slides du hero (classes partagées) : testé et vérifié
   sans effet négatif sur les slides 2 et 3 (hauteur réduite dans les deux
   cas, aucun texte cassé). --- */
@media (max-width: 575.98px) {
  .hero-slider.two .hero-slider-init-one .swiper-wrapper .item-slider .slider-content-inner .slider-title {
    font-size: 27px;
    line-height: 32px;
  }

  .hero-slider.two .hero-slider-init-one .swiper-wrapper .item-slider .slider-content-inner .description {
    margin-top: 14px;
  }

  .hero-slider-init-one .inner-btn .default-btn {
    font-size: 14px;
    padding-left: 16px;
    padding-right: 16px;
  }
}

/* ==========================================================================
   Logo header — legerement agrandi sur smartphone (amelioration cosmetique,
   aucun bug reel constate sur le header ou le logo). Aucune meilleure
   version du fichier logo trouvee dans les assets (recherche effectuee) :
   fichier logo-white.png (312x71) conserve tel quel, seul l'affichage CSS
   change. Ratio preserve (height fixe + max-width coherent).
   Selecteur egal en specificite a la regle native du theme
   (.header-area-3 .logo-area .logo img, 4 classes) pour l'emporter par
   ordre de cascade sans !important — meme technique que le titre du hero
   (point 4), verifiee en live avant application. Header (80px) et
   hamburger non touches. --- */
@media (max-width: 575.98px) {
  .header-area-3 .logo-area .logo img {
    max-width: 210px;
    height: 46px;
  }
}

/* ==========================================================================
   Hero — écrans très larges / ultra-wide (21:9 et assimilés) uniquement.

   Cause réelle (vérifiée en live, feuille du thème 0fnfcz7lhxhfw.css) :
   .hero-slider.two .swiper .swiper-wrapper { height:700px } — une hauteur
   FIXE en pixels, sans variante desktop large, appliquée telle quelle de
   992px à l'infini. Sur un écran classique (1440x900, 1920x1080, y compris
   2560x1440 en 16:9) le rapport largeur/hauteur reste raisonnable et le
   rendu est correct — c'est uniquement sur des écrans nettement plus larges
   que hauts (21:9 et assimilés, ratio ≥ 2:1) que ces mêmes 700px donnent un
   bandeau écrasé. Corrigé en ne touchant QUE cette même règle, scopée à un
   double critère (largeur ET ratio) pour ne jamais affecter le desktop
   classique, même en 16:9 large (1920x1080, 2560x1440 : ratio 1.78,
   inférieur au seuil 2:1 retenu ici — non affectés, vérifié).

   Même sélecteur que le thème (4 classes), chargé après lui : l'emporte
   par ordre de cascade sans !important, technique déjà utilisée ailleurs
   dans ce fichier (titre hero, logo header). Tout le reste (réseau,
   bouclier, halos, modes par slide, cartes, flèches, textes) est purement
   positionné en % ou en absolute à l'intérieur de ce même conteneur : en
   lui redonnant de la hauteur, ils se replacent proportionnellement sans
   qu'aucune autre règle n'ait besoin d'être touchée. --- */
@media (min-width: 1600px) and (min-aspect-ratio: 2/1) {
  .hero-slider.two .swiper .swiper-wrapper {
    height: min(100vh, calc(100vw * 864 / 1821));
  }
  /* .item-slider (photo + contenu du slide) a sa PROPRE règle de thème
     (height:auto, plus spécifique que le height:100% générique de
     .swiper-slide) qui le laisse caler sur la hauteur naturelle de son
     contenu (~715px), indépendamment de la hauteur du wrapper ci-dessus —
     vérifié en live : sans cette ligne, la photo de fond (position:absolute
     dans .item-slider) s'arrête à 715px et laisse un bandeau vide sous elle
     une fois le wrapper agrandi. Même sélecteur que le thème (5 classes),
     chargé après lui : l'emporte par cascade sans !important. */
  .hero-slider.two .swiper .swiper-wrapper .item-slider {
    height: 100%;
  }

  /* --- Correctif suite au retour utilisateur : la hauteur agrandie
     ci-dessus, combinée à la largeur bien plus grande d'un écran 21:9,
     avait fait grossir le ratio largeur/hauteur du calque réseau
     (.hero-network, jusque-là étiré en inset:0 sur TOUTE la largeur/
     hauteur du hero) bien au-delà du ratio pour lequel le SVG a été
     dessiné et calé point par point sur la photo. Le SVG réseau utilise
     volontairement preserveAspectRatio="none" (voir hero-network-overlay
     -v2.svg) pour un mapping 1:1 coordonnée-viewBox -> % du calque ; ce
     choix suppose implicitement que le calque garde à peu près le ratio
     de référence (~1440/715 ≈ 2.014, le rapport constaté sur desktop
     classique au moment où tous les points ont été positionnés). Sur un
     calque devenu ~3.1:1 (2560/820), l'étirement horizontal résiduel
     passait d'environ +21% (acceptable, déjà présent avant ce correctif)
     à +87% par rapport au vertical : cercles ovalisés, icônes déformées,
     lignes visiblement étirées.

     Correctif : au lieu de laisser .hero-network occuper toute la largeur
     du hero, on le plafonne au même ratio de référence (~2.014) via
     aspect-ratio, ancré à DROITE (right:0, left:auto) — c'est là que se
     trouve toute la composition significative (bouclier, icônes, château)
     d'après le travail de calage original ; la partie gauche du hero
     (où se trouve le bloc texte) garde simplement la photo en dessous,
     sans réseau superposé, ce qui ne nuit pas à la lisibilité du texte.
     Le SVG interne (width/height:100% posés par motion.js) retrouve alors
     exactement le même facteur d'étirement qu'en desktop classique, quel
     que soit la largeur réelle de l'écran 21:9. .hero-network__svg (inset:0
     dans .hero-network) suit automatiquement la nouvelle taille du parent,
     aucune règle supplémentaire nécessaire. --- */
  .hero-network {
    left: auto;
    right: 0;
    width: auto;
    aspect-ratio: 1440 / 715;
  }

  /* --- Barre de services : mesurée trop fine/petite proportionnellement
     à un hero bien plus large en 21:9 (padding/tailles en px fixes,
     inchangés depuis le desktop classique). Légère augmentation du
     confort visuel uniquement ici, 4 cartes toujours cliquables, CTA
     jamais recouvert (la barre garde sa position bottom existante). --- */
  .hero-card {
    padding: 10px 16px;
  }

  .hero-card__icon {
    font-size: 16px;
  }

  .hero-card__title {
    font-size: 14px;
  }

  .hero-card__text {
    font-size: 11.5px;
  }

  /* --- Bloc texte : légère augmentation de présence (+13%, dans la
     fourchette +10/+18% demandée), le texte restant proportionnellement
     petit sur un hero devenu bien plus grand. Même sélecteur que le
     thème (6 classes, .slider-content-inner .slider-title / .description
     — déjà utilisé ailleurs dans ce fichier pour le même type de
     surcharge sans !important) : s'applique aux 3 slides identiquement,
     aucun changement de texte, juste la taille. --- */
  .hero-slider.two .swiper .swiper-wrapper .item-slider .slider-content-inner .slider-title {
    font-size: 52px;
    line-height: 60px;
  }

  /* Le slide "Tests d'intrusion" a un titre nettement plus long que les 2
     autres ("Détectez et corrigez les failles avant qu'elles ne soient
     exploitées") : repris tel quel à 52px, il passe à ~5 lignes et son CTA
     se retrouve caché sous la barre de services (mesuré en live : CTA à
     706-751px, barre dès 667px). Sa propre règle plus spécifique
     (.slider-content-inner.middle, 7 classes, voir plus haut dans ce
     fichier, 36px sur desktop classique pour la même raison) est reprise
     ici avec une hausse proportionnelle plus modeste (+13% par rapport à
     SA propre base de 36px, pas celle des 2 autres slides à 46px) et une
     largeur plafonnée pour garder un nombre de lignes maîtrisé. Revérifié
     après coup : CTA largement dégagé de la barre. */
  .hero-slider.two .swiper .swiper-wrapper .item-slider .slider-content-inner.middle .slider-title {
    font-size: 40px;
    line-height: 48px;
    max-width: 560px;
  }

  .hero-slider.two .swiper .swiper-wrapper .item-slider .slider-content-inner .description {
    font-size: 18px;
  }

  .hero-slider.two .swiper .swiper-wrapper .item-slider .slider-content-inner .sub-title {
    font-size: 22px;
  }

  /* --- Loop 1 (retour "interdiction de superposer bouclier et pictos") :
     chevauchements détectés UNIQUEMENT en 21/9 (confirmé par mesure
     getBoundingClientRect en live, absents en desktop classique). Cause :
     .hero-icon-* est positionné en % de .hero-network (rétréci et ancré à
     droite en 21/9, voir règle ci-dessus), tandis que .hero-shield est
     positionné en % de .hero-dynamic-extras (toujours pleine largeur,
     jamais réduit) — les deux repères divergent uniquement à cette
     largeur, d'où deux chevauchements ponctuels invisibles en desktop
     classique. Corrigé par un décalage horizontal ciblé, seulement pour
     les 2 icônes concernées, seulement dans ce média-query. */
  .hero-mode-pentest .hero-icon-laptop {
    left: 43%;
    top: 62%;
  }
  .hero-mode-infra .hero-icon-server {
    left: 46%;
    top: 56%;
  }
  .hero-mode-cyber .hero-icon-tower5g {
    left: 35%;
    top: 36%;
  }
  .hero-mode-cyber .hero-icon-cloud {
    left: 45%;
    top: 32%;
  }
  .hero-mode-cyber .hero-icon-laptop {
    left: 50%;
    top: 64%;
  }
  .hero-mode-cyber .hero-icon-wifi {
    left: 85%;
    top: 36%;
  }
  .hero-mode-cyber .hero-icon-database {
    left: 88%;
    top: 58%;
  }
  .hero-mode-cyber .hero-icon-phone1 {
    left: 76%;
    top: 70%;
  }
  .hero-mode-infra .hero-icon-cloud {
    left: 38%;
    top: 36%;
  }
  .hero-mode-infra .hero-icon-laptop {
    left: 70%;
    top: 68%;
  }
  .hero-mode-infra .hero-icon-database {
    left: 82%;
    top: 55%;
  }
  .hero-mode-infra .hero-icon-tower5g {
    left: 88%;
    top: 35%;
  }
  .hero-mode-pentest .hero-icon-wifi {
    left: 47%;
    top: 35%;
  }
  .hero-mode-pentest .hero-icon-camera {
    left: 36%;
    top: 43%;
  }
  .hero-mode-pentest .hero-icon-phone2 {
    left: 78%;
    top: 69%;
  }
  .hero-mode-pentest .hero-icon-database {
    left: 65%;
    top: 78%;
  }
  .hero-mode-pentest .hero-icon-tower5g {
    left: 84%;
    top: 38%;
  }

  /* Loop 4 — ultra-wide uniquement : la bande reste fine et à la même
     position, mais gagne juste assez de contraste pour rester lisible face
     à la plus grande surface photographique. */
  .hero-service-cards {
    background: rgba(6, 14, 26, 0.27);
    border-color: rgba(255, 255, 255, 0.17);
  }

  .hero-card__text {
    color: rgba(234, 255, 248, 0.74);
  }
}

/* Loop 0B — ratio natif de la photo hero sur desktop.
   Le hero peut dépasser la hauteur du viewport en ultra-wide afin de préserver
   le ciel, les montagnes et la profondeur de la scène sans recadrage vertical. */
@media (min-width: 992px) {
  .hero-slider.two .swiper {
    width: 100%;
    height: auto !important;
    aspect-ratio: 1821 / 864;
  }

  .hero-slider.two .swiper .swiper-wrapper {
    height: 100% !important;
  }

  .hero-slider.two .swiper .swiper-wrapper .item-slider {
    height: 100% !important;
  }
}

/* ==========================================================================
   Loop Composition Hero — Variante A locale uniquement
   ========================================================================== */
@media (min-width: 992px) {
  /* Le hero complet devient le repère de composition. La contrainte Bootstrap
     de 1140px reste intacte partout ailleurs sur le site. */
  .hero-slider.two .swiper .swiper-wrapper .item-slider .auto-container {
    position: absolute;
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100%;
    margin: 0;
    padding: 0;
  }

  .hero-slider.two .swiper .swiper-wrapper .item-slider .auto-container > .row {
    position: relative;
    width: 100%;
    height: 100%;
    margin: 0;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .auto-container
    > .row
    > .col-lg-7 {
    position: static;
    width: 100%;
    max-width: none;
    padding: 0;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    position: absolute;
    left: clamp(220px, 16.5vw, 420px);
    top: 29.5%;
    width: clamp(400px, 31vw, 480px);
    max-width: 480px;
    height: auto !important;
    isolation: isolate;
  }

  /* Nappe sombre locale : bord droit progressivement fondu pour éviter
     l'apparence d'une carte rectangulaire posée sur la photographie. */
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: -24px;
    right: -44px;
    bottom: -22px;
    left: -26px;
    border: 0;
    border-radius: 26px;
    background: radial-gradient(
      ellipse 100% 105% at 28% 48%,
      rgba(5, 13, 26, 0.63) 0%,
      rgba(5, 14, 28, 0.52) 46%,
      rgba(5, 16, 30, 0.16) 70%,
      rgba(5, 16, 30, 0) 100%
    );
    box-shadow:
      0 18px 46px rgba(0, 0, 0, 0.2),
      inset 0 1px 0 rgba(154, 244, 255, 0.06);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    -webkit-mask-image: radial-gradient(
      ellipse 100% 105% at 28% 48%,
      #000 0%,
      #000 52%,
      rgba(0, 0, 0, 0.58) 70%,
      transparent 100%
    );
    mask-image: radial-gradient(
      ellipse 100% 105% at 28% 48%,
      #000 0%,
      #000 52%,
      rgba(0, 0, 0, 0.58) 70%,
      transparent 100%
    );
    pointer-events: none;
  }

  /* A.2 : le titre Pentest est plus haut que les deux autres. Sa nappe
     s'arrête plus tôt pour préserver une séparation nette avec la barre
     de services à 1440px, sans déplacer le texte ni le CTA. */
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle::before {
    top: -16px;
    bottom: 2px;
  }

  /* Le support local reprend le travail de contraste : l'ancienne ombre
     pleine largeur devient une correction photographique très légère. */
  .hero-slider-init-one .swiper-slide:first-child .slide-bg::before {
    background: linear-gradient(
      100deg,
      rgba(6, 14, 26, 0.2) 0%,
      rgba(6, 14, 26, 0.1) 18%,
      rgba(6, 14, 26, 0.03) 32%,
      rgba(6, 14, 26, 0) 47%
    );
  }

  /* Repère commun au hero, taille responsive et présence légèrement accrue. */
  .hero-shield {
    top: 31.5%;
    right: auto;
    left: 63%;
    width: clamp(230px, 13vw, 280px);
    height: auto;
    aspect-ratio: 22 / 27;
    z-index: 4;
    opacity: 0.86;
    filter: drop-shadow(0 0 16px rgba(51, 229, 255, 0.48));
  }

  .hero-mode-pentest .hero-shield {
    opacity: 0.72;
  }

  .hero-mode-infra .hero-shield {
    opacity: 0.7;
  }
}

@media (min-width: 1600px) and (min-aspect-ratio: 2/1) {
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    left: 17%;
    top: 29.5%;
  }

  .hero-shield {
    left: 60%;
    top: 31%;
  }
}

/* ==========================================================================
   Loop Composition Hero — Variante A.3 locale uniquement
   Composition verticale + perspective photographique des points premium.
   ========================================================================== */
@media (min-width: 992px) {
  /* Le contenu descend proportionnellement. Pentest garde un déplacement
     plus prudent à 1440px afin de préserver la barre de services. */
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    top: 31.5%;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle {
    top: 30.2%;
  }

  /* Le centre visuel du bouclier rejoint celui du bloc texte. */
  .hero-shield {
    top: 29%;
    left: 61.5%;
  }

  /* Échelle de profondeur générale : aucun point ne domine plus la scène. */
  .hero-premium-node--sm {
    width: 20px;
    height: 20px;
    --premium-node-opacity: 0.5;
  }

  .hero-premium-node--md {
    width: 30px;
    height: 30px;
    --premium-node-opacity: 0.64;
  }

  .hero-premium-node--lg {
    width: 44px;
    height: 44px;
    --premium-node-opacity: 0.78;
  }

  /* Horizon et zones lointaines : petits points discrets uniquement. */
  .hero-premium-node--audit-north,
  .hero-premium-node--audit-castle-east,
  .hero-premium-node--pentest-north,
  .hero-premium-node--pentest-castle,
  .hero-premium-node--infra-north-east {
    width: 16px;
    height: 16px;
    --premium-node-opacity: 0.36;
  }

  .hero-premium-node--audit-castle,
  .hero-premium-node--pentest-urban,
  .hero-premium-node--infra-urban,
  .hero-premium-node--infra-castle {
    width: 20px;
    height: 20px;
    --premium-node-opacity: 0.46;
  }

  /* Milieu urbain : présence structurante, jamais plus forte que le bouclier. */
  .hero-premium-node--audit-city,
  .hero-premium-node--audit-urban,
  .hero-premium-node--audit-east,
  .hero-premium-node--pentest-city,
  .hero-premium-node--pentest-east,
  .hero-premium-node--pentest-west,
  .hero-premium-node--pentest-bridge,
  .hero-premium-node--infra-city,
  .hero-premium-node--infra-east,
  .hero-premium-node--infra-west {
    width: 26px;
    height: 26px;
    --premium-node-opacity: 0.58;
  }

  /* Premier plan : un seul point plus affirmé par slide, les autres moyens. */
  .hero-premium-node--audit-river,
  .hero-premium-node--pentest-south,
  .hero-premium-node--infra-river {
    width: 44px;
    height: 44px;
    --premium-node-opacity: 0.78;
  }

  .hero-premium-node--audit-road,
  .hero-premium-node--audit-bridge,
  .hero-premium-node--audit-south,
  .hero-premium-node--audit-road-east,
  .hero-premium-node--pentest-river,
  .hero-premium-node--pentest-road,
  .hero-premium-node--infra-bridge,
  .hero-premium-node--infra-south,
  .hero-premium-node--infra-road {
    width: 32px;
    height: 32px;
    --premium-node-opacity: 0.66;
  }

  /* Recalage léger sur des repères photographiques crédibles. */
  .hero-premium-node--audit-north { left: 54%; top: 36%; }
  .hero-premium-node--audit-castle-east { left: 90%; top: 38%; }
  .hero-premium-node--audit-castle { left: 78%; top: 42%; }

  .hero-premium-node--pentest-north { left: 87%; top: 36%; }
  .hero-premium-node--pentest-castle { left: 79%; top: 40%; }
  .hero-premium-node--pentest-urban { left: 64%; top: 43%; }
  .hero-premium-node--pentest-west { left: 50%; top: 47%; }

  .hero-premium-node--infra-north-east { left: 92%; top: 40%; }
  .hero-premium-node--infra-urban { left: 65%; top: 43%; }
  .hero-premium-node--infra-castle { left: 82%; top: 45%; }
}

@media (min-width: 1600px) {
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    top: 33%;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle {
    top: 32%;
  }
}

@media (min-width: 1600px) and (min-aspect-ratio: 2/1) {
  .hero-shield {
    top: 29%;
    left: 58.5%;
  }
}

/* ==========================================================================
   Loop Composition Hero — Variante A.4 locale uniquement
   Marges de sécurité entre contenu éditorial, nappe et barre de services.
   ========================================================================== */
@media (min-width: 992px) {
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    top: 28.5%;
  }

  /* Les titres Pentest et Infogérance gagnent une ligne utile sans devenir
     massifs : la réduction de hauteur crée l'air sous le CTA. */
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle,
  .hero-slider.two
    .swiper
    .swiper-wrapper
    > .swiper-slide[data-swiper-slide-index="2"]
    .item-slider
    .slider-content-inner {
    top: 28.5%;
    width: clamp(480px, 36vw, 540px);
    max-width: 540px;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle
    .slider-title,
  .hero-slider.two
    .swiper
    .swiper-wrapper
    > .swiper-slide[data-swiper-slide-index="2"]
    .item-slider
    .slider-content-inner
    .slider-title {
    width: 100%;
    max-width: 540px;
  }

  /* La nappe s'arrête dans le contenu au lieu de déborder vers la barre. */
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner::before {
    bottom: 4px;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle::before,
  .hero-slider.two
    .swiper
    .swiper-wrapper
    > .swiper-slide[data-swiper-slide-index="2"]
    .item-slider
    .slider-content-inner::before {
    bottom: 8px;
  }
}

@media (min-width: 1600px) {
  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    top: 30.5%;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle,
  .hero-slider.two
    .swiper
    .swiper-wrapper
    > .swiper-slide[data-swiper-slide-index="2"]
    .item-slider
    .slider-content-inner {
    top: 30.5%;
  }
}

@media (min-width: 992px) and (max-width: 1599.98px) {
  .hero-slider.two
    .swiper
    .swiper-wrapper
    > .swiper-slide[data-swiper-slide-index="2"]
    .item-slider
    .slider-content-inner {
    top: 25.5%;
  }
}

/* Intervention express — boucliers visibles uniquement sur smartphone. */
@media (max-width: 991px) {
  .hero-dynamic-extras {
    display: block;
    z-index: 10;
  }

  .hero-network {
    z-index: -1;
  }

  .hero-shield {
    display: block;
    position: absolute;
    right: 12px;
    left: auto;
    top: 46%;
    transform: translateY(-50%);
    width: clamp(100px, 30vw, 132px);
    height: clamp(122px, 37vw, 162px);
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    pointer-events: none;
    z-index: 3;
    filter: drop-shadow(0 0 10px rgba(51, 229, 255, 0.38));
  }

  .hero-mode-cyber .hero-shield {
    opacity: 0.86;
  }

  .hero-mode-pentest .hero-shield {
    opacity: 0.78;
  }

  .hero-mode-infra .hero-shield {
    opacity: 0.76;
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner {
    width: calc(100% - clamp(118px, 34vw, 148px));
    max-width: calc(100% - clamp(118px, 34vw, 148px));
  }

  .hero-slider.two
    .swiper
    .swiper-wrapper
    .item-slider
    .slider-content-inner.middle {
    margin-left: 0;
    margin-right: auto;
    text-align: left;
  }
}
/* Mascotte Nono 2026 — verrouille le decor de la section activite a sa
   taille historique, quel que soit le canvas natif du nouvel asset. */
.about-section.three > .shape-img .shape-2 {
  width: 80px;
  height: auto;
}
/* Patch ciblé : texte du Hero visible dès le premier affichage. */
.hero-slider.two .swiper-slide .sub-title,
.hero-slider.two .swiper-slide .slider-title,
.hero-slider.two .swiper-slide .description,
.hero-slider.two .swiper-slide .inner-btn {
  opacity: 1 !important;
  visibility: visible !important;
  animation: none !important;
  animation-delay: 0s !important;
}

.hero-slider.two .swiper-slide .inner-btn .default-btn {
  opacity: 1 !important;
  visibility: visible !important;
}
