/* =====================================================================
   [w3cam 2026-09-07 v2 menu-vertical] MENU PRINCIPAL VERTICAL, BUREAU
   Objectif : le bas des sous-menus ne doit jamais sortir de la fenetre,
   SANS jamais rendre un panneau inatteignable a la souris.

   Historique : une revue independante a rejoue la v1 de ce fichier en
   production (injection CSS + souris reelle pilotee en CDP) et l'a
   rejetee. La v1 posait `position: static` sur le <li> des categories
   en submenu_position_1, ce qui deplacait le panneau en haut de la
   LISTE au lieu du haut de la LIGNE survolee. Mesure le 2026-09-07 a
   1366x1080 en deplacant reellement le pointeur : l'intersection
   verticale entre la ligne et le panneau (74 px pour les 8 categories
   avant tout correctif) tombait a 16, 0 ou 28 px pour Systemes Audio,
   Alarmes, Accessoires et Kits Videosurveillance, qui se refermaient
   des que la souris quittait la ligne pour entrer dans le panneau.
   4 categories sur 8 cassees par la v1 (2 sur 5 pour le niveau 2).

   Regle absolue de la v2 : NE JAMAIS changer la position d'un <li>. Le
   <li> reste dans tous les cas la cible du survol, ce qui garantit que
   le panneau demarre par defaut au niveau de la ligne (comportement de
   base du theme, inchange ici) et peut donc etre atteint par un trajet
   de souris horizontal depuis n'importe quel point de la ligne. Nuance
   verifiee le 2026-09-07 par lecture directe de offsetParent en
   production : le <li> n'est le bloc CONTENEUR du panneau (celui contre
   lequel `top` se calcule) que pour submenu_position_1/2, ou le theme le
   pose en position:relative. Pour submenu_position_0 (Cameras de
   Surveillance, Accessoires), le <li> reste position:static et le bloc
   conteneur reel est `.menu-vertical` (position:absolute) : c'est deja
   ce qui fait demarrer leur panneau en haut de la LISTE aujourd'hui, pas
   en haut de la ligne. w3c-menu-vertical.js lit le vrai bloc conteneur
   via `panel.offsetParent` plutot que de supposer que c'est le <li>.
   Le repositionnement vertical (uniquement quand le panneau
   deborderait la fenetre) est calcule par ce script, jamais par ce
   fichier CSS seul : voir la section degradation ci-dessous.

   Aucune mise en colonnes (column-count) : la version precedente en
   posait une a partir de 13 entrees pour eviter le defilement interne
   du niveau 1. Mesure en production sur le panneau Accessoires (mis en
   deux colonnes de 300 px) : les 10 volets de niveau 2, quelle que soit
   leur colonne d'origine, s'ouvraient tous a la meme abscisse [870,1170]
   px, calee sur le bord droit du panneau entier (600 px) et non sur
   celui de leur propre <li> (colonne 1 a gauche, colonne 2 a droite) :
   un descendant position:absolute d'un conteneur en colonnes se
   positionne par rapport a la boite du contenu comme si elle n'etait
   pas fragmentee, pas par rapport a la colonne visuelle de son <li>.
   Un volet de colonne 1 se retrouvait donc a deux colonnes de distance
   de sa propre ligne, avec les 8 lignes de la colonne 2 entre les deux
   sur le trajet de souris : la meme regle qui divisait le panneau en
   deux faisait tomber son overlap a 28 px. Remplace ici par un
   defilement interne (le niveau 2 est le noeud le plus profond du
   menu : aucun element_ul_depth_3 dans le gabarit, verifie le
   2026-09-07 sur le module en production, un defilement y est donc
   sans risque de rogner un troisieme niveau).

   Degradation : ce fichier CSS seul, sans JavaScript, ne deplace AUCUN
   panneau. Chaque regle qui pose `top` ci-dessous retombe, via le
   fallback de var(), exactement sur la valeur que le theme pose deja
   aujourd'hui (0 pour un panneau de niveau 1, -1px pour un volet de
   niveau 2) tant que la variable CSS correspondante n'a pas ete posee
   par le script. Les regles qui posent max-height/overflow/position ne
   s'appliquent qu'aux elements portant une classe ajoutee par le
   script (.w3c-scroll, .w3c-fixed) : sans script, ces classes
   n'existent jamais et ces regles ne s'appliquent jamais. Si
   w3c-menu-vertical.js ne charge pas ou echoue, le menu se comporte
   donc exactement comme avant ce correctif, pas moins bien.

   Portee : bureau seul (min-width: 1025px, meme seuil que la section
   d'entete qui porte ce menu : elementor-hidden-tablet +
   elementor-hidden-phone), uniquement sous .wrapper-menu-vertical. Le
   menu mobile (.wrapper-menu-mobile) et le menu horizontal
   (.menu-horizontal) ne sont touches par aucune regle de ce fichier.
   w3c-menu-vertical.js porte exactement la meme garde de 1025px (fonction
   isDesktop()) : sans elle, aucun ecouteur ne serait pose sous ce seuil. Le
   <link> de cette feuille est declare dans le theme avec
   media="(min-width: 1025px)" : sous ce seuil, le navigateur le recupere en
   arriere-plan sans qu'il bloque le premier rendu de la page, cette feuille
   n'est donc meme pas render-blocking en dessous de 1025px.

   submenu_position_2 est explicitement exclu des regles de niveau 1 :
   la regle de production
   .wrapper-menu-vertical .item-level-0.submenu_position_2>.menu_sub{top:auto;bottom:0}
   ancre le panneau sur le BAS de la liste plutot que sur le haut de la
   ligne. Sans exclusion, notre regle (plus de classes dans le
   selecteur) gagnerait en specificite et ecraserait silencieusement ce
   comportement. Aucune des 8 categories actuelles n'utilise cette
   position (verifie sur la capture DOM du 2026-09-07), mais un
   gestionnaire du back-office pourrait la choisir demain. Le <li> de
   niveau 1 (imbrique dans un panneau) ne porte lui jamais de classe
   submenu_position_N (verifie sur la meme capture) : l'exclusion n'est
   donc utile qu'au niveau 1, pas au niveau 2.
   ===================================================================== */

@media (min-width: 1025px) {

  /* 1. Panneau de niveau 1. Le theme pose deja `top: 0` (relatif a la
        ligne, qui reste position:relative, jamais touchee ici) : c'est
        deja un ancrage correct, celui-la meme qui fait fonctionner
        Cameras de Surveillance et Accessoires aujourd'hui. On expose
        seulement un point d'ancrage ajustable par le script pour les
        fenetres ou ce point de depart ferait deborder le panneau. */
  .wrapper-menu-vertical .menu-vertical > .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub {
    top: var(--w3c-sub-top, 0px);
  }

  /* 2. Volet de niveau 2. Le theme pose deja `top: -1px` (relatif au
        <li> de niveau 1, qui reste position:relative, jamais touche
        ici). Meme logique qu'au point 1. */
  .wrapper-menu-vertical .menu-vertical .menu_sub.tdmenu_multi_level > li > ul {
    top: var(--w3c-sub2-top, -1px);
  }

  /* 3. Largeur fixe du volet de niveau 2. Bat
        `.td_mega_menu .tdmenu_multi_level ul{width:100%}` (socle theme,
        specificite 0-2-1 ; notre selecteur ci-dessous, avec 4 classes,
        la bat deja sans !important, conserve neanmoins en garde-fou).
        Sans cette regle le volet heriterait de 100% de la largeur de
        son bloc conteneur, correct par coincidence tant qu'aucune
        colonne n'intervient (~300px, la largeur du <li> de niveau 1),
        mais faux des que le script bascule ce volet en position:fixed
        (regle 4) : position:fixed change le bloc conteneur du calcul
        de width:100%, du <li> au viewport, et le volet s'etirerait sur
        presque toute la largeur de la fenetre. megamenu-sub.tpl (ligne
        169 du gabarit, module tdmegamenu, verifie en lecture sur la
        production le 2026-09-07) pose deja un style en ligne
        `width: 300px` sur le panneau de NIVEAU 1 (pas sur le niveau 2,
        genere par megamenu-category.tpl qui ne pose aucun style en
        ligne) : le !important est conserve ici en prevision d'un futur
        alignement des deux gabarits, pas parce qu'un style en ligne
        existe aujourd'hui a ce niveau. */
  .wrapper-menu-vertical .menu-vertical .menu_sub.tdmenu_multi_level > li > ul {
    width: 300px !important;
  }

  /* 4. Volet de niveau 2 promu position:fixed par le script, uniquement
        quand son panneau de niveau 1 defile en interne (regle 6 :
        overflow-y:auto y rognerait sinon un descendant
        position:absolute, exactement le piege que la v1 de ce fichier
        evitait deja en n'appliquant jamais overflow au niveau 1 -- sauf
        que la v1 n'avait alors aucune solution pour les panneaux a la
        fois trop longs ET dont les lignes ont un second niveau.

        `top`/`left` en coordonnees fenetre litterales ne sont corrects que si
        le bloc conteneur reel de ce position:fixed est la fenetre. Le theme
        anime `transform` sur CE panneau de niveau 1 (.menu_sub) a
        l'ouverture : un ancetre transforme redevient sinon le bloc
        conteneur, ce qui fausserait ces coordonnees. La regle 7 plus bas
        neutralise ce `transform` precisement quand ce panneau porte
        .w3c-scroll, c'est-a-dire dans le seul cas ou ce volet devient
        .w3c-fixed : voir son commentaire pour l'historique mesure (deux
        defauts trouves dans une version anterieure qui compensait ce
        transform depuis le script plutot que de le supprimer).

        La largeur fixe de la regle 3 reste necessaire ici (voir plus haut). */
  .wrapper-menu-vertical .menu-vertical .menu_sub.tdmenu_multi_level > li > ul.w3c-fixed {
    position: fixed;
    top: var(--w3c-sub2-top, auto);
    left: var(--w3c-sub2-left, auto);
  }

  /* 5. Le volet de niveau 2 est le noeud le plus profond du menu (aucun
        element_ul_depth_3 dans le gabarit, verifie le 2026-09-07) : un
        defilement interne y est donc toujours sans danger, applique par
        le script a chaque positionnement (classe .w3c-scroll), que le
        panneau de niveau 1 defile lui-meme ou non. */
  .wrapper-menu-vertical .menu-vertical .menu_sub.tdmenu_multi_level > li > ul.w3c-scroll {
    max-height: var(--w3c-sub2-maxh, none);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* 6. Panneau de niveau 1 en defilement interne, uniquement quand sa
        hauteur naturelle depasse la fenetre meme apres le meilleur
        repositionnement possible (cas mesure le 2026-09-07 : Accessoires,
        988 px de haut dans la maquette pour son contenu de ce jour ;
        recherche binaire dans la maquette, meme jour : le panneau defile a
        1160 px de hauteur de fenetre, plus a 1161. Ce seuil precis est
        propre a cette maquette (161 px d'entete suppose) et depend du
        nombre d'entrees de la categorie et de la hauteur d'entete reelle au
        moment de la mesure ; ce n'est pas une constante du correctif, donc
        environ 1160 px en production). Applique par le script
        (classe .w3c-scroll), jamais par ce fichier seul : sans script,
        aucun panneau de niveau 1 ne defile, comme aujourd'hui.

        `width` compense la scrollbar native de ce defilement (voir le
        commentaire du script a l'endroit ou --w3c-sub-width est pose).

        Le repli `300px` n'est pas decoratif : mesure le 2026-09-07 dans la
        maquette (Chrome, barres de defilement en surimpression, donc
        offsetWidth - clientWidth = 0), une declaration `width: var(--x)
        !important` dont la variable n'est pas posee n'est PAS « ignoree » et
        ne retombe PAS sur le style en ligne du theme : une var() invalide au
        moment du calcul rend la propriete `unset`, donc `auto` pour width,
        et le `!important` a deja fait perdre le `width:300px` en ligne de
        megamenu-sub.tpl. Le panneau tombait ainsi a 168 px de large des
        qu'il defilait. Le repli reprend la valeur posee en ligne par le
        gabarit ; le script pose de toute facon toujours la variable en meme
        temps que la classe .w3c-scroll. */
  .wrapper-menu-vertical .menu-vertical > .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub.w3c-scroll {
    max-height: var(--w3c-sub-maxh, none);
    overflow-y: auto;
    overscroll-behavior: contain;
    width: var(--w3c-sub-width, 300px) !important;
  }

  /* 7. Neutralise le `transform` du theme sur CE panneau precis (niveau 1,
        en defilement interne, .w3c-scroll), le seul cas ou un descendant de
        ce panneau (le volet de niveau 2) passe en position:fixed (regle 4)
        et devient donc sensible au bloc conteneur que ce panneau
        etablirait s'il restait transforme.

        Une revue independante a rejoue en production, avec une souris
        reelle, une version anterieure de ce correctif qui COMPENSAIT ce
        transform depuis le script (lecture de `flyout.offsetParent`,
        suppose null hors transition, non nul pendant) plutot que de le
        supprimer ici. Deux defauts mesures, dans les deux moteurs :

        - Chrome : offsetParent n'est lu qu'une fois, a mouseenter, pendant
          que .menu_sub anime encore `transform` (200ms, transition posee
          par le theme). Rien ne recalcule ensuite (aucun gestionnaire
          transitionend ; positionLevel2 ne tourne qu'a mouseenter et au
          redimensionnement/defilement) : quand la transition se termine
          ~200ms plus tard, sans que la souris ait bouge, le bloc conteneur
          redevient silencieusement la fenetre et la compensation deja
          posee devient perimee. Mesure a 1366x768, ligne a top 213 px /
          droite 570 px : le volet, correct a la mesure (haut 213, gauche
          530, chevauchement 52 px), sautait 600 ms plus tard sur son
          propre panneau (haut 52, gauche 260), le recouvrant entierement
          et interceptant le survol a la place des liens du menu.
        - Firefox : offsetParent d'un element position:fixed vaut BODY meme
          SANS aucun ancetre transforme (deviation du moteur par rapport a
          la specification, qui impose null pour un position:fixed ;
          Chrome la respecte ici, Firefox non). La compensation s'appliquait
          donc aussi en regime stable, a tort, et l'erreur introduite valait
          exactement `body.getBoundingClientRect().top`, l'oppose du
          defilement de la page. Mesure a scrollY=400 : chevauchement de
          52 px (correct sans compensation) tombait a -348 px avec elle.
          Les lignes de ce menu mesurant 52 px, tout defilement de page de
          plus d'environ 52 px cassait alors le trajet de la souris dans
          Firefox, le navigateur de bureau principal du site.

        Plutot que de detecter ce cas a l'execution (fragile : les deux
        moteurs sont en desaccord sur la valeur meme d'offsetParent pour un
        position:fixed, un cas que la specification ne leur impose de toute
        facon de traiter identiquement que hors transform), on retire ici la
        cause : ce panneau ne transitionne plus jamais sur `transform`
        (`transition-property` ne liste plus que opacity et visibility), il
        vaut `none` des l'instant ou le script pose .w3c-scroll. Les deux
        moteurs sont alors d'accord : offsetParent d'un descendant
        position:fixed de ce panneau vaut null dans les deux cas, la fenetre
        reste le seul bloc conteneur possible, et les coordonnees fenetre
        litterales posees par le script (voir positionLevel2) s'appliquent
        toujours telles quelles, avant, pendant et apres tout ce qui aurait
        ete une transition.

        Cout accepte : ce panneau precis n'a plus la meme entree animee
        (glissement de 15px) que les panneaux qui ne defilent pas -- lui
        seul, et seulement sur bureau (>=1025px, meme garde que tout ce
        fichier). Les panneaux qui ne defilent jamais gardent l'animation du
        theme, inchangee. */
  .wrapper-menu-vertical .menu-vertical > .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub.w3c-scroll {
    transition-property: opacity, visibility;
    transform: none;
  }

  /* 8. La regle 7 neutralise le `transform` du panneau de niveau 1
        lui-meme, mais un position:fixed cherche son bloc conteneur en
        remontant TOUS les ancetres, pas seulement le plus proche : la
        liste entiere (.menu-vertical) porte elle aussi un `transform`
        anime par le theme (translateY 15px -> none, 200ms), a l'ouverture
        du menu (clic sur .menu-vertical-title, avant tout survol d'une
        ligne). Mesure le 2026-09-07 avec une souris reelle en pilotant un
        clic reel puis un trajet immediat vers Accessoires (categorie qui
        defile a 1366x768) : dans la fenetre d'environ 90 a 170ms apres le
        clic (le menu devient survolable vers 90-100ms, `pointer-events`
        etant une propriete a bascule discrete qui ne change qu'a la moitie
        de la transition de 200ms ; `.menu-vertical` termine sa propre
        transition vers 170-200ms), `flyout.offsetParent` valait l'element
        `.menu-vertical` lui-meme (au lieu de null) et le volet de niveau 2
        se posait 209 px trop bas (haut mesure 419,2 au lieu de 210,3
        attendu), chevauchement negatif, recouvrant des lignes qui n'ont
        rien a voir avec la sienne. Meme defaut que la regle 7, memes deux
        moteurs concernes, par un ancetre different.

        Neutralise ici de la meme facon, mais seulement pendant que
        `.menu-vertical` CONTIENT un panneau .w3c-scroll (selecteur
        `:has()`). Avant le premier survol d'une ligne racine qui defile
        en interne, cette regle ne correspond a rien et l'entree animee de
        la liste entiere (glissement de 15px a l'ouverture) reste celle du
        theme. Des qu'un tel panneau recoit .w3c-scroll (positionLevel1),
        cette regle correspond et coupe la transition de `.menu-vertical`
        en cours a cet instant precis : voir le commentaire de la regle 7
        pour le mecanisme exact (le changement de `transition-property`
        annule une transition en cours sur une propriete qui en sort, la
        valeur cible s'applique alors immediatement au lieu de continuer a
        s'animer).

        PERMANENT des ce premier survol, verifie le 2026-09-07 avec une
        souris reelle : .w3c-scroll n'est jamais retire au `mouseleave`
        (seul positionLevel1 le retire, en tout debut de son PROPRE
        prochain appel, avant de remesurer -- voir w3c-menu-vertical.js,
        les gestionnaires mouseleave ne font qu'untrack()). Le `:has()`
        ci-dessus continue donc de correspondre bien apres que la souris a
        quitte le panneau, et l'entree animee de TOUTE la liste reste
        coupee pour le reste de la vie de la page, y compris pour les
        categories qui n'ont jamais defile elles-memes. Verifie que
        l'alternative (retirer .w3c-scroll et ses variables --w3c-sub-* au
        mouseleave) n'est pas preferable : mesure avec une souris reelle
        pilotant Chrome, le panneau (contraint a 595px de haut dans ce
        cas) reprend alors sa hauteur naturelle (988px, +393px) des
        l'image suivant le mouseleave, pendant que son opacite vaut encore
        environ 0.99 et reste visible ~160ms de plus avant de disparaitre
        completement : un agrandissement brutal et visible pendant le
        fondu de fermeture, plus genant que la simple perte de l'entree
        animee deja acceptee ci-dessus et a la regle 7. Ce fichier choisit
        donc de garder cette latence permanente plutot que d'introduire ce
        second defaut.

        Portee `:has()` necessaire (Chrome 105+, Firefox 121+, tous deux
        largement couverts en 2026) : sans elle, neutraliser le transform de
        TOUTE la liste en permanence supprimerait son animation d'ouverture
        pour toutes les categories, y compris celles qui ne defilent
        jamais -- un cout largement superieur a celui deja accepte a la
        regle 7. Dans un moteur sans :has(), cette regle ne s'applique
        jamais (regle entiere ignoree, pas seulement le :has()) : le risque
        mesure ci-dessus reapparaitrait, mais seulement dans cette fenetre
        etroite de 90 a 170ms apres un clic sur un navigateur obsolete,
        jamais dans le regime stable ni dans les autres defauts corriges
        par ce fichier. */
  .wrapper-menu-vertical .menu-vertical:has(> .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub.w3c-scroll) {
    transition-property: opacity, visibility;
    transform: none;
  }

  /* 9. Scrollbar fine pour ce meme panneau, meme convention que le
        theme ailleurs dans ce module (.style_wide::-webkit-scrollbar,
        socle-theme-extrait.css). Reduit la largeur de la bande que le
        script doit contourner (regle OVERLAP_PX du script, sur le volet
        de niveau 2 fixe) sans la faire disparaitre : Chrome/Safari
        (WebKit/Blink) l'appliquent, Firefox retombe sur sa scrollbar
        systeme, plus large, sans casser la mise en page (OVERLAP_PX est
        volontairement plus genereux que ces 6px pour rester correct
        aussi sur Firefox). Meme exclusion submenu_position_2 qu'aux
        regles 1, 6 et 7, pour la meme raison : ces quatre regles ciblent
        le meme panneau de niveau 1. */
  .wrapper-menu-vertical .menu-vertical > .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub.w3c-scroll::-webkit-scrollbar {
    width: 6px;
  }
  .wrapper-menu-vertical .menu-vertical > .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub.w3c-scroll::-webkit-scrollbar-thumb {
    background-color: #cdcdcd;
  }
  .wrapper-menu-vertical .menu-vertical > .item-level-0.is_parent:not(.submenu_position_2) > .menu_sub.w3c-scroll::-webkit-scrollbar-track {
    background-color: #f0f0f0;
  }
}
