﻿/* =============================================================================
   rail-modules.css — RAIL vertical à gauche des pages HORS dashboard
   -----------------------------------------------------------------------------
   Rail ÉTROIT (icônes seules, 64px), PLEINE HAUTEUR sous le header du haut. Au survol
   d'une icône, un TIROIR (.rail-flyout) glisse à sa droite — PAR-DESSUS le contenu —
   avec le libellé (même fond → on dirait que le pavé de l'icône s'allonge). Le contenu
   garde toute sa largeur (rail seulement 64px). Le tiroir est rendu sur <body>
   (position:fixed, positionné en JS, cf. <script> de _RailModules) → il échappe au
   clipping du rail scrollable. `pointer-events:none` → le clic passe au lien.

   Fond marine repris du thème (tokens --tg-sidebar-*, définis dans
   assets/src/scss/_theme.default.scss). Le shell legacy est en position:fixed
   (#header, #content, .titre-layout-page, #foot — assets/css/socle/shell.css) → on
   décale chaque élément fixe par `left`/`width`. Scopé à body.has-rail-modules.
   ============================================================================= */

.rail-modules {
    /* Palette alignée sur la sidebar du dashboard (aucune couleur en dur ici). */
    /* Fond = couleur du HEADER personnalisée par l'abonné (/Preferences → --tg-bandeau-fond),
       repli sur le marine de la charte. La perso du header pilote ainsi le rail. */
    --rail-bg: var(--tg-bandeau-fond, var(--tg-sidebar-bg));
    /* Texte/icônes du rail = couleur de texte perso abonné (--tg-bandeau-texte, /Preferences),
       REPLI sur le thème `--tg-sidebar-text` (= #CBD5E1, slate-300). → change avec Preferences ;
       #CBD5E1 par défaut. Le nom + l'avatar de l'utilisateur en bas font EXCEPTION (fixés clairs,
       cf. .rail-modules-user + flyout `.is-user`). */
    --rail-icon: var(--tg-bandeau-texte, var(--tg-sidebar-text));
    --rail-icon-hover: var(--tg-bandeau-texte, var(--tg-sidebar-text-hover));
    --rail-muted: var(--tg-sidebar-muted);
    --rail-hover-bg: var(--tg-sidebar-hover-bg);
    --rail-actif-bg: var(--tg-sidebar-active-bg);
    --rail-separateur: var(--tg-sidebar-divider);
    --rail-w: 64px;         /* largeur ÉTROITE (icônes seules) */
    --rail-header-h: 60px;  /* hauteur RÉELLE du header (#header/#topBlock = 60px) → pas d'empiètement */

    /* Pleine hauteur SOUS le header (pas coupé). */
    position: fixed;
    top: var(--rail-header-h);
    bottom: 0;
    left: 0;
    width: var(--rail-w);
    z-index: 1031; /* au-dessus de #header (z-index:999, socle/shell.css) */

    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding-bottom: .5rem;

    background: var(--rail-bg);
    color: var(--rail-icon);
    overflow: hidden;
    box-shadow: 1px 0 0 rgba(255, 255, 255, .05); /* fine séparation rail / contenu */
}

/* ---- Zone HAUTE défilante (Dashboard + modules) : seule à scroller si la liste est longue. ---- */
.rail-modules-top {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    /* Scrollbar MASQUÉE (défilement molette/trackpad) : aucune gouttière réservée → pas de
       « padding » à droite et largeur du rail CONSTANTE (scroll visible ou non). */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.rail-modules-top::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
}

/* ---- Zone BASSE figée (Contact / Paramètres / Déconnexion), séparée par un liseret. ----
   `margin-top` : creuse un écart AVANT le séparateur. Comme la zone haute est en `flex:1 1 auto`
   (elle occupe tout l'espace restant), cette marge réduit d'autant la hauteur de la liste des
   modules → la liste ne touche plus le bloc bas, on a une vraie respiration liste / icônes+photo. */
.rail-modules-bottom {
    flex: 0 0 auto;
    margin-top: 2rem;
    padding-top: .5rem;
    border-top: 2px solid var(--rail-separateur);
}

/* La scrollbar de la zone haute est masquée (aucune gouttière) → plus besoin de compenser
   un décalage sur les icônes du bas : elles s'alignent naturellement sur celles du haut. */

.rail-modules-menu {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rail-modules-menu li {
    margin: 0;
}

/* Icône du Dashboard : toujours en couleur « main » du thème (uniquement l'icône). */
#rail-modules .rail-dashboard svg,
#rail-modules .rail-dashboard [data-lucide] {
    color: var(--bs-main);
    transition: transform .15s ease;
}

/* Dashboard au survol : fond BLANC (icône) — on bat le hover marine générique (spécificité
   `.rail-modules-menu a.rail-dashboard`) — + léger ZOOM de l'icône. */
#rail-modules .rail-modules-menu a.rail-dashboard:hover,
#rail-modules .rail-modules-menu a.rail-dashboard.tiroir-actif {
    background: #fff;
}

#rail-modules .rail-modules-menu a.rail-dashboard:hover svg,
#rail-modules .rail-modules-menu a.rail-dashboard:hover [data-lucide],
#rail-modules .rail-modules-menu a.rail-dashboard.tiroir-actif svg,
#rail-modules .rail-modules-menu a.rail-dashboard.tiroir-actif [data-lucide] {
    color: var(--bs-main);
    transform: scale(1.18);
}

/* Titre de groupe dans le rail (icônes seules) : nom du groupe encadré par deux liserets
   (au-dessus et en-dessous). Petit texte, centré, qui tient dans la largeur du rail (peut passer
   sur plusieurs lignes plutôt que déborder). */
.rail-modules-groupe-titre {
    margin-top: .35rem;
    padding: .3rem 0; /* pas de padding horizontal : le texte occupe toute la largeur du rail */
    width: 100%;
    box-sizing: border-box;
    border-top: 1px solid var(--rail-separateur);
    border-bottom: 1px solid var(--rail-separateur);
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: uppercase;
    text-align: center;
    color: var(--rail-muted);
    overflow-wrap: anywhere;
    hyphens: auto;
}

/* Titre de groupe CLIQUABLE : replie/déplie les modules du groupe (même geste que la barre latérale
   du dashboard). Le rail est trop étroit pour un chevron → l'état est marqué par la couleur. */
.rail-modules-groupe-titre.rail-groupe-toggle {
    cursor: pointer;
    user-select: none;
    transition: color .12s ease;
}

.rail-modules-groupe-titre.rail-groupe-toggle:hover,
.rail-modules-groupe-titre.rail-groupe-toggle:focus-visible {
    color: var(--rail-icon);
}

/* Groupe replié : les modules sont masqués SAUF les ÉPINGLÉS (toujours visibles, cf. Modules-Epingles).
   Animation calquée sur la barre latérale du dashboard (`.dashboard-sidebar-groupe-modules.est-deplie`) :
   glissement max-height + fondu. ⚠️ On anime chaque <li> et NON la liste : les épinglés vivent dans la
   MÊME liste et doivent rester visibles (le dashboard, lui, les rend hors du conteneur repliable).
   `display:none` ne se transitionne pas → max-height/opacity. La borne haute = la hauteur d'un item
   (`.rail-modules-menu a { height: 44px }`), à garder synchronisée avec elle. */
.rail-modules-menu[data-groupe-modules] > li {
    overflow: hidden;
    max-height: 44px;
    opacity: 1;
    transition: max-height .28s ease, opacity .2s ease;
}

/* Restent visibles quand le groupe est replié : les ÉPINGLÉS **et** le module de la page COURANTE
   (`> a.active`, posé au rendu par RailItem) — on ne masque jamais l'écran où l'on se trouve. */
.rail-modules-menu.est-replie > li:not(.est-epingle):not(:has(> a.active)) {
    max-height: 0;
    opacity: 0;
}

/* Item = icône CENTRÉE dans le rail étroit. Le libellé n'est pas dans le rail : il s'affiche
   au survol dans le tiroir .rail-flyout. La barre d'accent de l'item actif est portée par le
   border-left ; on réserve un border-right transparent SYMÉTRIQUE pour que l'icône reste
   parfaitement centrée (sinon le seul border-left la décale de 3px → besoin d'un margin négatif). */
.rail-modules-menu a {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
    border-left: 3px solid transparent;
    border-right: 3px solid transparent;
    color: var(--rail-icon);
    text-decoration: none;
    transition: background-color .12s ease, color .12s ease;
}

/* Lucide rend un <svg> héritant de currentColor ; taille 18px (comme .dashboard-sidebar-menu a svg). */
.rail-modules-menu a svg,
.rail-modules-menu a [data-lucide] {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
}

/* Libellé inline MASQUÉ : il s'affiche au survol dans le tiroir .rail-flyout (le flyout lit
   le libellé via `aria-label`). Le <span> reste dans le markup (cohérence) mais caché. */
.rail-modules-label {
    display: none;
}

/* #header impose `color:#fff` via #topBlock a ; on verrouille la palette du rail (spécificité ID). */
#rail-modules .rail-modules-menu a {
    color: var(--rail-icon);
}

/* Survol : MÊME fond que le tiroir .rail-flyout (effet « le pavé de l'icône s'allonge »).
   ⚠️ On DOIT utiliser la formule EXACTE du flyout (color-mix sur --tg-bandeau-fond) et non
   --rail-hover-bg : le flyout est rendu sur <body> et ne voit pas --rail-hover-bg (défini sur
   .rail-modules), il calcule donc sa couleur depuis les tokens :root → les deux doivent partager
   la même expression, sinon le fond de l'icône et celui de l'étiquette diffèrent. */
    #rail-modules .rail-modules-menu a:hover,
    #rail-modules .rail-modules-menu a.tiroir-actif {
        background: var(--rail-hover-bg);
        color: var(--rail-icon-hover);
    }

    /* Paramètres : pas de libellé au survol (classe rail-no-flyout, géré en JS), icône en couleur
       « main » du thème. PAS d'animation (contrairement à Déconnexion) : une rotation de
       l'engrenage a été tentée puis RETIRÉE le 2026-07-28 (rendu instable à l'écran). */
    #rail-modules .rail-modules-menu a.rail-parametres:hover {
        color: var(--bs-main);
    }

    /* Déconnexion : pas de libellé au survol (classe rail-no-flyout, géré en JS). L'icône « power »
       passe en ROUGE (danger) et joue un petit « pulse » (scale + léger pivot) au survol. */
    #rail-modules .rail-modules-menu a.confirmdisconnect:hover {
        color: var(--bs-danger, #dc3545);
    }

    #rail-modules .rail-modules-menu a.confirmdisconnect svg,
    #rail-modules .rail-modules-menu a.confirmdisconnect [data-lucide] {
        transition: transform .2s ease;
    }

        #rail-modules .rail-modules-menu a.confirmdisconnect:hover svg,
        #rail-modules .rail-modules-menu a.confirmdisconnect:hover [data-lucide] {
            animation: rail-power-pulse .55s ease;
        }

@keyframes rail-power-pulse {
    0% { transform: scale(1) rotate(0); }
    40% { transform: scale(1.22) rotate(-10deg); }
    70% { transform: scale(1.1) rotate(6deg); }
    100% { transform: scale(1) rotate(0); }
}

    /* Module courant : teinte orange + BARRE D'ACCENT gauche (3px) + icône orange. */
    #rail-modules .rail-modules-menu a.active {
        background: color-mix(in srgb, var(--rail-actif-bg) 16%, transparent);
        border-left-color: var(--rail-actif-bg);
        color: var(--rail-actif-bg);
    }

        #rail-modules .rail-modules-menu a.active:hover,
        #rail-modules .rail-modules-menu a.active.tiroir-actif {
            background: color-mix(in srgb, var(--rail-actif-bg) 24%, transparent);
        }

/* « Voir plus de modules » (14ᵉ item) : le chevron pivote à 180° quand la liste est dépliée. */
#rail-modules .rail-modules-plus-toggle svg,
#rail-modules .rail-modules-plus-toggle [data-lucide] {
    transition: transform .15s ease;
}

#rail-modules .rail-modules-plus-toggle.est-ouvert svg,
#rail-modules .rail-modules-plus-toggle.est-ouvert [data-lucide] {
    transform: rotate(180deg);
}

/* ---- Avatar utilisateur (bas) : pastille centrée (nom dans le tiroir au survol). ---- */
.rail-modules-user {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: .5rem 0 .25rem;
    /* Centré sur le RAIL ENTIER (64px) : la zone basse ne réserve plus de gouttière (seule la
       liste des 3 icônes la réserve via padding-right), donc l'avatar se centre naturellement. */
}

.rail-modules-user img,
.rail-modules-user .avatar-initiales {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 50%;
}

.rail-modules-user img {
    object-fit: cover;
    background: rgba(255, 255, 255, .1);
}

/* Repli initiales (pas de photo) : rond plein, initiales centrées. */
.rail-modules-user .avatar-initiales {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Pastille initiales : fond couleur « main » du thème, texte blanc (indépendant de la perso abonné). */
    background: var(--bs-main);
    color: #fff;
    line-height: 1;
    text-transform: uppercase;
}

/* Fonds OPAQUES partagés « icône survolée ↔ tiroir » — définis sur body.has-rail-modules car le
   flyout est rendu sur <body> (hors .rail-modules → ne verrait pas une variable scopée au rail).
   OPAQUES : le flyout flotte AU-DESSUS du contenu, il doit avoir exactement la même couleur que
   l'icône (posée, elle, sur le fond du rail) — un tint semi-transparent (--tg-sidebar-hover-bg)
   composité sur des fonds différents ne coïnciderait pas. rgb(2 9 64) = navy du thème (= couleur
   de --tg-sidebar-hover-bg sans son alpha .06). */
body.has-rail-modules {
    --rail-flyout-bg: color-mix(in srgb, rgb(2 9 64) 6%, var(--tg-bandeau-fond, var(--tg-sidebar-bg)));
    --rail-flyout-bg-active: color-mix(in srgb, var(--tg-bandeau-fond, var(--tg-sidebar-bg)), var(--tg-sidebar-active-bg) 24%);
}

/* ---- TIROIR (drawer) d'expansion au survol ----
   Panneau collé À DROITE de l'icône survolée (libellé), MÊME fond que l'icône au survol → on
   dirait que le pavé s'allonge. Rendu sur <body> (position:fixed, positionné en JS) → échappe
   au clipping du rail scrollable. Glisse + apparaît (effet tiroir). `pointer-events:none` → le
   clic passe au lien (la souris reste sur l'icône). */
.rail-flyout {
    position: fixed;
    z-index: 1032; /* au-dessus du rail (1031) */
    display: flex;
    align-items: center;
    padding: 0 1rem 0 .35rem;
    background: var(--rail-flyout-bg); /* = fond de l'icône au survol (même variable) */
    color: var(--tg-bandeau-texte, var(--tg-sidebar-text)); /* perso abonné, repli #CBD5E1 (sauf nom utilisateur, cf. .is-user) */
    /* Même taille que les textes du header du haut (menu modules = hérite 1rem) — pas .875rem. */
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    border-radius: 0 8px 8px 0;
    box-shadow: 6px 0 18px rgba(0, 0, 0, .3);
    /* Découpe l'ombre AU RAS du bord GAUCHE (0) : sinon le flou (18px) déborde ~12px sur la
       moitié droite de l'icône survolée → halo sombre au raccord = illusion de couleur différente.
       Ombre conservée en haut/droite/bas (effet tiroir) mais nulle côté icône (raccord net). */
    clip-path: inset(-30px -30px -30px 0);
    /* Le tiroir est CLIQUABLE : le libellé relaie le clic vers l'item survolé (cf. JS de
       _RailModules). Il reste collé à l'icône → la souris ne « quitte » pas vraiment l'item. */
    pointer-events: auto;
    cursor: pointer;
    visibility: hidden;
    opacity: 0;
    transform: translateX(-10px); /* glisse depuis l'icône (effet tiroir) */
    transition: opacity .16s ease, transform .16s ease, visibility .16s;
}

.rail-flyout.show {
    visibility: visible;
    opacity: 1;
    transform: translateX(0);
}

/* Module actif (page courante) : tiroir raccord avec l'item actif survolé (24% orange),
   TEXTE en couleur « main » du thème (--bs-main). */
.rail-flyout.is-active {
    background: var(--rail-flyout-bg-active); /* = fond de l'item actif survolé (même variable) */
    color: var(--bs-main);
}

/* Tiroir du Dashboard : fond BLANC (raccord avec le fond blanc de l'icône au survol) + texte main. */
.rail-flyout.is-dashboard {
    background: #fff;
    color: var(--bs-main);
}

/* Tiroir du NOM utilisateur (avatar bas) : EXCEPTION → fond BLANC (le pavé de l'avatar n'a pas
   de fond de survol coloré comme les icônes) + texte sombre pour rester lisible. Posé par le JS
   (classe is-user) au survol de .rail-modules-user. */
    .rail-flyout.is-user {
        background: #fff;
        color: var(--tg-sidebar-text-strong);
    }

/* =============================================================================
   Décalage du shell fixe vers la droite (largeur ÉTROITE du rail seulement ; le tiroir
   flotte par-dessus le contenu, il ne le repousse pas). Scopé à body.has-rail-modules.
   ============================================================================= */
.has-rail-modules {
    --rail-w: 64px;
}

/* Header du haut : PLEINE LARGEUR (le rail est sous lui, à gauche). */
.has-rail-modules #header {
    left: 0;
    width: 100%;
}

/* Header de la MÊME couleur que le rail / la sidebar (= couleur du bandeau perso abonné,
   --tg-bandeau-fond, repli marine) → chrome cohérente (header + rail = un seul bloc). #topBlock
   pose déjà son fond depuis teogest-fonctionnel.css (var --tg-bandeau-fond) ; on garde la surcharge
   scopée aux pages à rail (spécificité 1,1,0) pour rester explicite. */
.has-rail-modules #topBlock,
.has-rail-modules #header {
    background: var(--tg-bandeau-fond, var(--tg-sidebar-bg));
}

/* Fil d'Ariane + contenu + barre de boutons : décalés de la largeur (étroite) du rail. */
.has-rail-modules .titre-layout-page,
.has-rail-modules #content,
.has-rail-modules #foot {
    left: var(--rail-w);
    width: calc(97% - var(--rail-w));
}

/* La barre de boutons (#foot) s'etire jusqu'au BORD DROIT (aucun coin decouvert en bas-droite) :
   on annule la largeur calculee ci-dessus et on borne par left (rail) + right:0. */
.has-rail-modules #foot {
    right: 0;
    width: auto;
}

/* Fil d'Ariane : même traitement que #foot → il s'étire jusqu'au BORD DROIT pour que le trait
   (border-bottom) file tout à droite. On annule le width:calc(97% - rail) et on borne left (rail)
   + right:0. Le CONTENU (#content) garde sa largeur calculée → position/affichage inchangés. */
.has-rail-modules .titre-layout-page {
    right: 0;
    width: auto;
}

/* Index élargis (pleine largeur, marqués par .tg-index-wrap) : on CENTRE #content dans l'espace
   disponible (rail gauche → bord droit) pour que l'écart gauche (rail→grille) = écart droit
   (grille→bord). Par défaut #content colle à gauche (margin-left:15px) et le width:calc(97% - rail)
   laisse ~3% à droite → asymétrique. En posant right:0 + margin-inline:auto, l'espace résiduel
   (~58px) se répartit également des deux côtés (~29px). Scopé aux seules vues d'index. */
.has-rail-modules #content:has(> .tg-index-wrap) {
    right: 0;
    margin-left: auto;
    margin-right: auto;
}

/* Repli mobile : rail un peu plus étroit. */
@media (max-width: 767px) {
    .rail-modules {
        --rail-w: 52px;
    }

    .has-rail-modules {
        --rail-w: 52px;
    }
}
