/* Encoche de la barre de statut. Formule reprise telle quelle de la
   supervision (son index.lp) : c'est la condition pour que le menu tombe au
   même endroit des deux côtés. Capacitor pose --safe-area-inset-* sur <html>
   (0px quand il a déjà décalé le WebView lui-même) ; env() prend le relais en
   PWA et dans Safari iOS, et vaut 0px partout ailleurs, navigateur de bureau
   compris. Sans ce repli, le portail ignorait l'encoche là où la supervision
   la respectait. */
:root {
    --fcs-safe-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px));
}

/* Surlignage de toucher d'Android. Par défaut le WebView peint un aplat bleu
   sur la BOÎTE de l'élément touché, angles droits compris et border-radius
   ignoré : sur le bouton du menu, rond de 40px, un carré apparaissait donc
   autour de l'icône au moindre appui. Mesuré sur appareil le 2026-08-27, ce
   carré faisait 120px physiques, soit exactement les 40px CSS du bouton.

   Retiré globalement et pas seulement sur ce bouton : le même aplat sortait
   sur « Se connecter », « Créer un compte » et sur tous les liens. Les boutons
   gardent leur propre retour au toucher, le :active qui les rétrécit de 2 %. */
:root {
    -webkit-tap-highlight-color: transparent;
}

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html, body {
    height: 100%;
}

body {
    background: #000;
    font-family: 'DM Sans', sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    overflow-y: auto;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 40px;
    width: 100%;
    max-width: 360px;
    margin: auto;
    padding: 32px 24px;
    animation: fadeUp 0.5s ease both;
}

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

.logo img {
    max-width: 140px;
    height: auto;
    display: block;
}

/* ── Écran d'accueil calé sur le splash natif ─────────────────────────────
   Objectif : que le logo ne bouge pas d'un pixel au moment où le splash se
   retire, au premier lancement.

   Le splash est peint sur la fenêtre entière, son logo est donc centré sur
   l'écran physique. La page, elle, vit dans un WebView décalé sous la barre
   de statut : un centrage à 50 % du viewport tombe une demi-barre trop bas.
   D'où --fcs-status-bar, publié par FcsWindowInsets.java.

   Les deux décalages fins sont mesurés sur le rendu natif, pas estimés : le
   sigle est 3,03 px à gauche du centre de son propre cadre, et son cercle de
   cadrage le place à 4,48 px à droite et 1,86 px au-dessus du centre écran.
   Somme : 7,5 px à droite et 1,9 px en haut.

   Pas d'animation ici, volontairement. Une entrée en fondu ou en glissement
   trahirait la bascule que l'on cherche justement à rendre invisible.

   POUR REVENIR EN ARRIÈRE : retirer « home-aligned » de la classe dans
   templates/app/security/home.html.twig. Rien d'autre, ce bloc redevient
   sans effet. */
.container.home-aligned {
    position: fixed;
    left: 50%;
    top: calc(50% - var(--fcs-status-bar, 0px) / 2 - 1.9px);
    margin: 0;
    padding-top: 0;
    transform: translateX(-50%);
    animation: none;
}

.container.home-aligned .logo {
    margin-top: -69px;
    transform: translateX(7.5px);
}

.container.home-aligned .logo img {
    width: 138px;
    max-width: none;
}

/* ── Apparition des actions de l'accueil (2026-08-25) ─────────────────────
   Le logo, lui, ne doit JAMAIS être animé : il prolonge celui du splash
   natif au pixel près, le moindre mouvement casserait le raccord construit
   dans l'app. Les boutons n'existent pas sur le splash : les faire arriver
   en fondu adoucit le seul changement encore visible au lancement.

   La courbe est un ease-out prononcé : l'essentiel du trajet se joue au
   début, la fin est imperceptible. Le léger délai laisse la page se poser
   avant que quoi que ce soit ne bouge. */
.container.home-aligned .home-actions {
    opacity: 0;
    transform: translateY(10px);
    animation: fcs-actions-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.12s forwards;
}

@keyframes fcs-actions-in {
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .container.home-aligned .home-actions {
        animation-duration: 0.01s;
        animation-delay: 0s;
    }
}

/* ── Formulaire login ── */
.login-form {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

label {
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #555;
}

input[type="text"],
input[type="email"],
input[type="password"] {
    /* Aucun habillage natif : sur iOS le champ recoit sinon une ombre interne
       et ses propres coins arrondis, imposes par le systeme. */
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    background: #111;
    border: 1px solid #222;
    border-radius: 6px;
    padding: 12px 14px;
    color: #e8e8e8;
    font-family: inherit;
    font-size: 14px;
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}

input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus {
    border-color: #444;
    box-shadow: 0 0 0 3px rgba(255,255,255,0.04);
}

/* ── Remplissage automatique : reprendre la main sur le navigateur ─────────
   Chrome, Safari et Edge repeignent un champ rempli automatiquement en bleu
   tres clair et forcent la couleur du texte, par des declarations internes
   qu'aucune regle ordinaire ne surcharge. Deux leviers passent quand meme :
   une ombre interne assez large pour recouvrir tout le fond, et
   -webkit-text-fill-color, qui l'emporte sur color. La transition de 9999s
   repousse indefiniment la couleur de fond animee que le navigateur repose
   apres coup.

   Les selecteurs sont volontairement separes en plusieurs regles : un
   navigateur qui ne connait pas :autofill jetterait TOUTE une liste ou il
   apparait, y compris la partie -webkit- qu'il comprend. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:active {
    -webkit-text-fill-color: #e8e8e8;
    caret-color: #e8e8e8;
    -webkit-box-shadow: 0 0 0 1000px #111 inset;
    box-shadow: 0 0 0 1000px #111 inset;
    border-color: #222;
    transition: background-color 9999s ease-in-out 0s;
}

/* Le focus garde son liseré : l'ombre de recouvrement passe en premier, celle
   du focus par-dessus. */
input:-webkit-autofill:focus {
    -webkit-text-fill-color: #e8e8e8;
    caret-color: #e8e8e8;
    -webkit-box-shadow: 0 0 0 1000px #111 inset, 0 0 0 3px rgba(255,255,255,0.04);
    box-shadow: 0 0 0 1000px #111 inset, 0 0 0 3px rgba(255,255,255,0.04);
    border-color: #444;
    transition: background-color 9999s ease-in-out 0s;
}

/* Forme standard, et Firefox, qui pose en plus un filtre colore sur le champ. */
input:autofill {
    filter: none;
    -webkit-text-fill-color: #e8e8e8;
    caret-color: #e8e8e8;
    box-shadow: 0 0 0 1000px #111 inset;
    border-color: #222;
    transition: background-color 9999s ease-in-out 0s;
}

input:autofill:focus {
    box-shadow: 0 0 0 1000px #111 inset, 0 0 0 3px rgba(255,255,255,0.04);
    border-color: #444;
}

input::placeholder {
    color: #333;
}

button[type="submit"] {
    margin-top: 6px;
    width: 100%;
    padding: 13px;
    background: #fff;
    color: #000;
    border: none;
    border-radius: 6px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.2s, transform 0.1s;
}

button[type="submit"]:hover  { background: #e8e8e8; }
button[type="submit"]:active { transform: scale(0.98); }

/* ── Messages d'erreur Symfony ── */
.alert-error {
    width: 100%;
    background: rgba(220, 38, 38, 0.08);
    border: 1px solid rgba(220, 38, 38, 0.3);
    border-radius: 6px;
    padding: 16px 18px;
    color: #f87171;
    font-size: 13px;
    line-height: 1.5;
    text-align: center;
    white-space: pre-line;
}

/* ── Sélection controller ── */
.select-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

.select-label {
    color: #555;
    font-size: 12px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.controller-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.controller-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: #111;
    border: 1px solid #222;
    border-radius: 6px;
    padding: 16px 18px;
    color: #e8e8e8;
    text-decoration: none;
    font-size: 14px;
    transition: border-color 0.2s, background 0.2s;
}

.controller-item:hover {
    background: #181818;
    border-color: #444;
}

.controller-arrow {
    color: #444;
    font-size: 16px;
}

.controller-item.is-busy {
    opacity: 0.55;
    pointer-events: none;
}

.controller-item.is-busy .controller-arrow {
    animation: controller-arrow-pulse 0.9s ease-in-out infinite;
}

@keyframes controller-arrow-pulse {
    0%, 100% { opacity: 0.3; }
    50% { opacity: 1; }
}

/* Ouverture directe d'un projet : la liste de sélection n'est qu'un repli, pour
   le cas où JS est absent ou l'auto-login échoue. La classe est posée par un
   script en tête de page, avant le rendu, sinon la liste clignoterait. */
.fcs-auto-opening .select-header,
.fcs-auto-opening .account-links,
.fcs-auto-opening .account-menu,
.fcs-auto-opening .controller-list {
    display: none;
}

.select-loading {
    display: none;
    color: #555;
    font-size: 12px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.fcs-auto-opening .select-loading {
    display: block;
}

/* ── Page d'accueil : logo, se connecter, créer un compte ── */
.home-actions {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.btn-primary,
.btn-secondary {
    display: block;
    width: 100%;
    padding: 13px;
    border-radius: 6px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: 0.04em;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s, transform 0.1s;
}

/* Qualifiées par balise (a./button.) pour egaler la specificite de
   button[type="submit"] et gagner par l'ordre de declaration : sans ça, un
   <button type="submit" class="btn-secondary"> perdait fond/couleur/bordure
   face a la regle generique, alors qu'un <a class="btn-secondary"> (non
   concerne par ce selecteur) s'affichait correctement. Constate le
   2026-08-26 sur le bouton de suppression de compte. */
a.btn-primary,
button.btn-primary {
    background: #fff;
    color: #000;
    border: 1px solid #fff;
}

a.btn-primary:hover,
button.btn-primary:hover { background: #e8e8e8; border-color: #e8e8e8; }

a.btn-secondary,
button.btn-secondary {
    background: transparent;
    color: #e8e8e8;
    border: 1px solid #222;
}

a.btn-secondary:hover,
button.btn-secondary:hover { border-color: #444; background: #111; }

/* Variante destructive. Uniquement la couleur de texte de .alert-error,
   déjà au vocabulaire du portail : un bouton qui efface un compte ne doit
   pas avoir exactement la même apparence que celui qui déconnecte, sans
   pour autant crier plus fort que le reste de la page. */
a.btn-danger,
button.btn-danger {
    color: #f87171;
    border-color: rgba(220, 38, 38, 0.3);
}
a.btn-danger:hover,
button.btn-danger:hover { border-color: rgba(220, 38, 38, 0.5); background: rgba(220, 38, 38, 0.08); }

a.btn-primary:active,
button.btn-primary:active,
a.btn-secondary:active,
button.btn-secondary:active { transform: scale(0.98); }

/* ── Menu du portail ──────────────────────────────────────────────────
   Posé en fixe plutôt que dans le flux : les pages du portail n'ont pas
   d'en-tête commun.

   Le calage vise le menu de la supervision AU PIXEL PRÈS. Les deux sont
   servis sur la même origine depuis le proxy du 2026-08-27, le client passe
   donc de l'un à l'autre et l'icône ne doit pas bouger. Référence côté
   supervision : en-tête fixe de 80px calé à --fcs-safe-top, marge latérale de
   64px (20px sous 768px), icône de 24px centrée. Son centre tombe donc à 76px
   du bord droit (32px en mobile) et à safe + 40px du haut.

   Ici la pastille tactile fait 40px et l'icône 24px centrée dedans, son
   centre est donc à right + 20 et top + 20 : d'où 56px et 20px, et 12px en
   mobile. Tout changement d'un côté se reporte sur l'autre. */
.account-menu {
    position: fixed;
    top: calc(20px + var(--fcs-safe-top));
    right: 56px;
    z-index: 40;
}

@media (max-width: 767px) {
    .account-menu { right: 12px; }
}

.account-menu-toggle {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: 20px;
    background: transparent;
    color: #888;
    font-family: inherit;
    cursor: pointer;
}

/* Survol reserve aux vrais pointeurs. Sur un ecran tactile, :hover se pose
   au toucher et RESTE pose jusqu'au toucher suivant ailleurs : la pastille
   sombre restait accrochee autour du hamburger apres chaque fermeture.
   Constate sur appareil le 2026-08-27, mesure a rgb(17,17,17) sur du noir. */
@media (hover: hover) {
    .account-menu-toggle:hover { color: #e8e8e8; background: #111; }
}

/* Ouvert, le bouton est DANS la carte blanche : il repasse en noir et perd
   sa pastille sombre, qui n'aurait plus de fond noir sous elle. Le z-index
   le maintient au-dessus du panneau, qui vient se deployer derriere lui. */
.account-menu-toggle[aria-expanded="true"],
.account-menu-toggle[aria-expanded="true"]:hover {
    color: #000;
    background: transparent;
}

/* Hamburger qui se change en croix a l'ouverture (2026-08-27).
   L'etat est lu sur aria-expanded, deja pose par le JS du menu : aucune
   classe de plus a gerer, et l'attribut accessible devient la source unique
   de l'apparence. */
.account-menu-icon {
    position: relative;
    display: block;
    width: 24px;
    height: 24px;
}

.account-menu-icon span {
    position: absolute;
    left: 3px;
    width: 18px;
    height: 2px;
    background: currentColor;
    transition: transform 0.2s ease, opacity 0.12s ease;
}

.account-menu-icon span:nth-child(1) { top: 6px; }
.account-menu-icon span:nth-child(2) { top: 11px; }
.account-menu-icon span:nth-child(3) { top: 16px; }

/* Les deux barres extremes se rejoignent au centre de la boite et s'y
   croisent, celle du milieu s'efface. Les centres sont a 7, 12 et 17 : le
   deplacement est donc de 5px, pas d'un nombre choisi a l'oeil. */
.account-menu-toggle[aria-expanded="true"] .account-menu-icon span:nth-child(1) {
    transform: translateY(5px) rotate(45deg);
}

.account-menu-toggle[aria-expanded="true"] .account-menu-icon span:nth-child(2) {
    opacity: 0;
}

.account-menu-toggle[aria-expanded="true"] .account-menu-icon span:nth-child(3) {
    transform: translateY(-5px) rotate(-45deg);
}

/* Le panneau demarre au sommet du bouton, qui se retrouve donc DANS la carte
   et en occupe le coin haut droit. Aucun retrait en haut : c'est la premiere
   entree qui vient se caler sur le bouton, voir sa hauteur minimale plus bas.

   Blanc legerement transparent plutot qu'opaque, avec le meme flou d'arriere
   plan que l'en-tete de la supervision, qui est en bg-surface/70
   backdrop-blur-xl. Sur le noir du portail cela donne un gris tres clair, le
   texte noir y reste largement lisible. */
.account-menu-panel {
    position: absolute;
    top: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    width: 240px;
    /* Aucun retrait : les rangees occupent toute la carte, du bord haut au
       bord bas. Le moindre retrait bas laissait une bande vide sous la
       derniere entree, et c'est exactement la marge residuelle qu'on ne veut
       pas. Ce sont les entrees qui portent leur propre retrait. */
    padding: 0;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.88);
    -webkit-backdrop-filter: blur(24px);
    backdrop-filter: blur(24px);
    /* Les entrees touchent le bord haut de la carte : sans ce debordement
       masque, le survol de la premiere depasserait des coins arrondis. */
    overflow: hidden;
    /* clip-path plutot qu'une hauteur ou un scaleY : le texte ne se deforme
       pas, il se decouvre. */
    clip-path: inset(0 0 0 0);
    transition: opacity 0.18s ease, clip-path 0.18s ease, visibility 0s;
}

/* Le panneau se deplie et se replie, d'ou une exception assumee : on garde
   display:flex meme sous hidden, et c'est visibility qui le retire pour de
   bon, une fois l'animation finie. C'est aussi elle qui le sort de l'arbre
   d'accessibilite, ce que display:none faisait avant.

   A retenir si on revient en arriere : sans regle ici, le display:flex du
   bloc precedent l'emporte sur le display:none que l'attribut hidden tient
   du navigateur, et le panneau reste ouvert en permanence. Le piege est
   muet.

   Le JS n'a pas bouge : il continue de poser et de retirer hidden, tout le
   mouvement est ici. */
.account-menu-panel[hidden] {
    display: flex;
    visibility: hidden;
    opacity: 0;
    clip-path: inset(0 0 100% 0);
    pointer-events: none;
    transition: opacity 0.18s ease, clip-path 0.18s ease, visibility 0s 0.18s;
}

/* Texte noir sur la carte claire, survol au #e8e8e8 de .btn-primary : la
   couleur d'action du portail est deja celle-la, le menu ne l'invente pas.

   La hauteur minimale vaut celle du bouton, 40px. C'est ce qui aligne la
   premiere entree sur l'icone EXACTEMENT, sans dependre de la police ni de
   l'interligne : la premiere rangee occupe la meme bande que le bouton, par
   construction. Regler ca par un retrait calcule aurait bouge au premier
   changement de police.

   Coins carres et entrees jointives : sur une liste, un creux entre les
   rangees et des pastilles arrondies faisaient trois fois trop d'espace. Ce
   sont les coins de la carte qui arrondissent, via son overflow. */
.account-menu-item {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 40px;
    padding: 0 14px;
    border: none;
    background: transparent;
    color: #000;
    font-family: inherit;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: 0.04em;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

/* La premiere entree passe SOUS le bouton, qui la recouvre a droite : de quoi
   lui reserver la place, sinon un libelle long finirait derriere la croix. */
.account-menu-item:first-child {
    padding-right: 48px;
}

@media (hover: hover) {
    .account-menu-item:hover { background: #e8e8e8; }
}

.account-menu-item:disabled { color: #999; cursor: default; }

/* Sur telephone, le bord GAUCHE de la carte tombe sur celui des boutons de
   l'accueil, tranche le 2026-08-27 apres essai sur appareil.

   Le bord droit, lui, ne bouge pas : la carte est accrochee au bouton, pose a
   12px du bord pour que l'encre de son icone tombe a 20px, exactement la ou
   tombe celle de la supervision. Les deux marges different donc, 12px a
   droite contre 24px a gauche, et la carte est un peu PLUS large que les
   boutons. C'est assume : a l'oeil, ce qui compte est que les bords gauches
   se rejoignent, le bord droit etant tenu par le bouton.

   La largeur se deduit, elle n'est pas choisie :
     bord gauche des boutons = (100vw - C) / 2 + 24,  avec C = min(360px, 100vw)
     largeur                 = 100vw - ce bord - 12
                             = (100vw + C) / 2 - 36
   Rien a retoucher si le .container change de largeur maximale, seul C bouge. */
@media (max-width: 767px) {
    .account-menu-panel {
        width: calc((100vw + min(360px, 100vw)) / 2 - 36px);
        /* Les rangees passent a 44px alors que le bouton en fait 40 : la carte
           remonte de la moitie de l'ecart pour que la premiere reste centree
           sur l'icone. */
        top: -2px;
    }

    /* 44px, le minimum tactile d'Apple, la largeur etant deja acquise. */
    .account-menu-item {
        min-height: 44px;
        padding: 0 16px;
    }

    .account-menu-item:first-child {
        padding-right: 48px;
    }
}


/* Champ appât du formulaire d'inscription. Sorti de l'écran plutôt que
   masqué par display:none : certains automates ignorent ce qui est
   explicitement caché, mais remplissent ce qui est présent dans le flux. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ── Liens et aides sous les formulaires ── */
.form-link {
    color: #555;
    font-size: 12px;
    text-align: center;
}

/* Separateur entre deux liens de la meme ligne. Reste en inline, sans
   toucher a .form-link : cette classe sert sur sept pages, dont deux ou elle
   entoure du texte suivi d'un lien, et la passer en flex les casserait. */
.form-link-sep {
    margin: 0 8px;
}

/* Plus de trait sous le lien, demande du 2026-08-27. C'etait un
   border-bottom et non un text-decoration, d'ou la disparition du survol qui
   allait avec : il ne jouait que sur la couleur de ce trait. Remplace par un
   eclaircissement du texte, et reserve aux vrais pointeurs pour ne pas rester
   accroche apres un toucher. */
.form-link a {
    color: #e8e8e8;
    text-decoration: none;
}

@media (hover: hover) {
    .form-link a:hover { color: #fff; }
}

.field-hint {
    color: #444;
    font-size: 11px;
    line-height: 1.5;
}

/* ── Écrans d'information (email envoyé, compte confirmé) ── */
.notice {
    width: 100%;
    background: #111;
    border: 1px solid #222;
    border-radius: 6px;
    padding: 18px;
    color: #999;
    font-size: 13px;
    line-height: 1.6;
    text-align: center;
}

.notice-title {
    color: #e8e8e8;
    font-size: 14px;
    font-weight: 400;
    margin-bottom: 6px;
}

/* Fleche de retour des pages secondaires (inscription, mot de passe).
   Meme calage que .account-menu, en miroir : la barre de statut est sous
   le WebView, sans --safe-area-inset-top la fleche passerait dessous. */
.back-link {
    position: fixed;
    top: calc(8px + var(--safe-area-inset-top, 0px));
    left: 8px;
    z-index: 40;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 20px;
    color: #888;
    font-size: 20px;
    line-height: 1;
    text-decoration: none;
}

.back-link:hover { color: #e8e8e8; background: #111; }
