/* login-constellation.css — Écran de connexion « Constellation » (espace dentiste + labo).
   Design PARTAGÉ par dentiste.html et index.html. Toutes les classes sont préfixées .lgc-*
   pour n'entrer en collision avec aucune classe/variable de l'app (cf. CONVENTIONS).
   Thème : clair par défaut ; sombre si html[data-theme="dark"] (dark-mode.js, index.html)
   OU si la scène porte .lgc-scene--dark (init selon l'OS, dentiste.html — sombre limité au
   login, sans repeindre la vue post-login).
   Multi-tenant : le bouton reprend var(--grad) de l'app (thémable par labo). */

.lgc-scene{
  /* ── Tokens thème CLAIR (défaut) ── */
  --lgc-scene-bg:linear-gradient(165deg,#eaf3f8 0%,#d6e7f0 52%,#c1d9ea 100%);
  --lgc-card-bg:rgba(255,255,255,.92); --lgc-card-border:rgba(255,255,255,.95);
  --lgc-card-shadow:0 30px 70px rgba(20,80,120,.30),0 3px 10px rgba(20,80,120,.12),inset 0 1.5px 0 rgba(255,255,255,.95);
  --lgc-orb:transparent; --lgc-ring:rgba(26,92,138,.5); --lgc-ring2:rgba(43,143,179,.6); --lgc-sheen:rgba(26,92,138,.95);
  --lgc-logo-shadow:rgba(20,60,90,.20);
  --lgc-title:linear-gradient(100deg,#12507e,#3fb1ab 55%,#12507e);
  --lgc-sub:#4a7286; --lgc-foot:#7c99a8;
  --lgc-input-bg:#f1f7fa; --lgc-input-border:#c6dbe6; --lgc-input-text:#1c2a35; --lgc-input-ph:#8ea7b5; --lgc-input-focus-bg:#fff;
  --lgc-ecg-base:rgba(26,92,138,.28); --lgc-ecg-hot:#1798b5;

  position:fixed; inset:0; z-index:100000; display:flex; align-items:center; justify-content:center;
  padding:20px; background:var(--lgc-scene-bg); font-family:'DM Sans',system-ui,sans-serif;
}
html[data-theme="dark"] .lgc-scene, .lgc-scene.lgc-scene--dark{
  /* ── Tokens thème SOMBRE ── */
  --lgc-scene-bg:radial-gradient(130% 130% at 50% 0%,#0c2b3e,#071825 55%,#040c14);
  --lgc-card-bg:rgba(9,24,36,.42); --lgc-card-border:rgba(120,200,220,.2);
  --lgc-card-shadow:0 30px 80px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,255,255,.1);
  --lgc-orb:transparent; --lgc-ring:rgba(120,220,215,.4); --lgc-ring2:rgba(120,220,215,.2); --lgc-sheen:rgba(143,227,223,.95);
  --lgc-logo-shadow:rgba(0,0,0,.45);
  --lgc-title:linear-gradient(100deg,#8fe3df,#dff4f4 55%,#8fe3df);
  --lgc-sub:#7fb6c9; --lgc-foot:#6f97a9;
  --lgc-input-bg:rgba(255,255,255,.06); --lgc-input-border:rgba(140,200,220,.28); --lgc-input-text:#eaf6fb; --lgc-input-ph:#7fa6b8; --lgc-input-focus-bg:rgba(255,255,255,.1);
  --lgc-ecg-base:rgba(120,200,220,.26); --lgc-ecg-hot:#9ff0eb;
}

/* ── Fond : halos doux (sombre uniquement) + réseau (canvas) ── */
.lgc-fx{position:absolute;inset:0;overflow:hidden;z-index:1;display:none}
html[data-theme="dark"] .lgc-fx, .lgc-scene--dark .lgc-fx{display:block}
.lgc-blob{position:absolute;border-radius:50%;filter:blur(66px);mix-blend-mode:screen;opacity:.5}
.lgc-blob1{width:48vw;height:48vw;background:#1a6fa8;top:-14vw;left:-10vw;animation:lgc-drift1 17s ease-in-out infinite}
.lgc-blob2{width:42vw;height:42vw;background:#5bc4c0;bottom:-16vw;right:-8vw;animation:lgc-drift2 21s ease-in-out infinite}
.lgc-blob3{width:32vw;height:32vw;background:#2b8fb3;top:34%;left:56%;animation:lgc-drift3 25s ease-in-out infinite}
@keyframes lgc-drift1{50%{transform:translate(9vw,7vw) scale(1.18)}}
@keyframes lgc-drift2{50%{transform:translate(-8vw,-6vw) scale(1.14)}}
@keyframes lgc-drift3{50%{transform:translate(-7vw,5vw) scale(1.22)}}
.lgc-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:2}

/* ── Le même décor EMBARQUÉ dans un panneau de l'app (Paramètres › Forfait & conso) ──
   Même composition que l'écran de connexion (dégradé, halos, réseau), mais en bloc, et
   aux couleurs DU LABO : l'écran de connexion est commun à tous, une page de l'app ne
   l'est pas. Tout se calcule sur les tokens du labo (--bg, --accent, --teal, posés par
   tenant-branding.js) ; le réseau lit la propriété `color` du canvas (login-constellation.js,
   data-lgc-fit). Le panneau pose .lgc-fond, puis .lgc-fx et le canvas SOUS son contenu. */
.lgc-fond{position:relative; isolation:isolate; overflow:hidden;
  background:linear-gradient(165deg, color-mix(in srgb, var(--teal) 8%, var(--bg)) 0%, color-mix(in srgb, var(--accent) 12%, var(--bg)) 52%, color-mix(in srgb, var(--accent) 24%, var(--bg)) 100%)}
html[data-theme="dark"] .lgc-fond{
  background:radial-gradient(130% 130% at 50% 0%, color-mix(in srgb, var(--accent) 26%, var(--bg)), var(--bg) 55%, color-mix(in srgb, black 35%, var(--bg)))}
.lgc-fond > .lgc-fx, .lgc-fond > .lgc-canvas{z-index:0; pointer-events:none}
.lgc-fond > .lgc-canvas{color:var(--accent)}
html[data-theme="dark"] .lgc-fond > .lgc-canvas{color:var(--teal)}
.lgc-fond .lgc-blob1{background:var(--accent)}
.lgc-fond .lgc-blob2{background:var(--teal)}
.lgc-fond .lgc-blob3{background:color-mix(in srgb, var(--accent) 50%, var(--teal))}

/* ── Fond « constellation » optionnel DERRIÈRE l'app (Paramètres > Apparence, par labo) ──
   Conteneur plein écran fixe, sous le contenu (z-index:-1) et non cliquable. Masqué par
   défaut → le moteur (login-constellation.js) le voit invisible = zéro CPU. La classe
   html.app-constellation-on (posée par applyTenantConstellation) l'affiche. Le canvas
   dessine par-dessus la couleur de fond d'app du labo (var --bg), thème clair/sombre géré. */
#app-constellation{position:fixed;inset:0;z-index:-1;pointer-events:none;display:none}
html.app-constellation-on #app-constellation{display:block}

/* ── Carte ── */
.lgc-card{position:relative;z-index:3;width:400px;max-width:100%;padding:44px 38px 34px;text-align:center;border-radius:26px;
  background:var(--lgc-card-bg);backdrop-filter:blur(22px) saturate(1.15);-webkit-backdrop-filter:blur(22px) saturate(1.15);
  border:1px solid var(--lgc-card-border);box-shadow:var(--lgc-card-shadow)}

/* ── Bouton lune/soleil, en haut à droite de la scène (labo ET dentiste — même
   composant .lgc-scene). data-theme piloté par js/dark-mode.js → cohérent avec
   le reste de l'app avant même la connexion. ── */
.lgc-theme-toggle{
  position:absolute;top:18px;right:18px;z-index:5;
  display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(255,255,255,.7);
  border-radius:50%;
  cursor:pointer;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:background .15s,transform .15s;
}
.lgc-theme-toggle:hover{background:rgba(255,255,255,.75);transform:scale(1.05)}
html[data-theme="dark"] .lgc-theme-toggle, .lgc-scene--dark .lgc-theme-toggle{
  background:rgba(20,40,55,.55);border-color:rgba(120,200,220,.3);
}
html[data-theme="dark"] .lgc-theme-toggle:hover, .lgc-scene--dark .lgc-theme-toggle:hover{background:rgba(20,40,55,.8)}
.lgc-theme-toggle .lgc-ic-moon, .lgc-theme-toggle .lgc-ic-sun{font-size:17px;line-height:1}
.lgc-theme-toggle .lgc-ic-sun{display:none}
html[data-theme="dark"] .lgc-theme-toggle .lgc-ic-moon, .lgc-scene--dark .lgc-theme-toggle .lgc-ic-moon{display:none}
html[data-theme="dark"] .lgc-theme-toggle .lgc-ic-sun, .lgc-scene--dark .lgc-theme-toggle .lgc-ic-sun{display:inline-grid}

/* ── Logo + halo/anneaux + arc lumineux ── */
.lgc-logo-wrap{position:relative;width:138px;height:138px;margin:0 auto 16px;display:flex;align-items:center;justify-content:center}
.lgc-orb{position:absolute;inset:6px;border-radius:50%;background:radial-gradient(circle,var(--lgc-orb),transparent 66%);animation:lgc-pulse 3.8s ease-in-out infinite}
.lgc-ring{position:absolute;inset:12px;border-radius:50%;border:1.5px solid var(--lgc-ring);animation:lgc-pulse 3.8s ease-in-out infinite}
.lgc-ring2{inset:-2px;border-color:var(--lgc-ring2);border-width:2px;animation-delay:.7s}
@keyframes lgc-pulse{0%,100%{transform:scale(1);opacity:.95}50%{transform:scale(1.09);opacity:.5}}
.lgc-sheen{position:absolute;inset:-4px;border-radius:50%;padding:2.5px;
  background:conic-gradient(from 0deg,transparent 0deg,var(--lgc-sheen) 55deg,transparent 130deg,transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;
  animation:lgc-rotate 4.5s linear infinite}
@keyframes lgc-rotate{to{transform:rotate(360deg)}}
.lgc-logo{position:relative;z-index:4;height:82px;width:auto;
  filter:drop-shadow(0 4px 9px var(--lgc-logo-shadow));animation:lgc-bob 5s ease-in-out infinite}
@keyframes lgc-bob{50%{transform:translateY(-6px)}}

/* ── Titre / sous-titre ── */
.lgc-title{font-family:var(--font-signature,'Dancing Script',cursive);font-size:2.7rem;font-weight:700;line-height:1;margin:0 0 6px;
  background:var(--lgc-title);background-size:220% auto;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:lgc-sheen-t 6s linear infinite}
@keyframes lgc-sheen-t{to{background-position:220% center}}
.lgc-sub{color:var(--lgc-sub);font-size:.6rem;letter-spacing:2.6px;text-transform:uppercase;font-weight:600;margin:0 0 12px;white-space:nowrap}
/* petits écrans : on autorise le retour à la ligne pour éviter tout débordement horizontal */
@media (max-width:440px){ .lgc-sub{white-space:normal;letter-spacing:2px} }

/* ── Tracé ECG (battement cardiaque) ── */
.lgc-ecg{display:block;width:196px;height:34px;margin:0 auto 24px;overflow:visible}
.lgc-ecg path{fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.lgc-ecg-base{stroke:var(--lgc-ecg-base)}
.lgc-ecg-pulse{stroke:var(--lgc-ecg-hot);stroke-dasharray:15 100;stroke-dashoffset:100;
  filter:drop-shadow(0 0 4px var(--lgc-ecg-hot));animation:lgc-ecg 2.4s cubic-bezier(.6,0,.2,1) infinite}
@keyframes lgc-ecg{0%{stroke-dashoffset:100}34%{stroke-dashoffset:-15}100%{stroke-dashoffset:-15}}

/* ── Champs / bouton / pied ── */
.lgc-field{margin-bottom:12px}
.lgc-input{display:block;width:100%;padding:13px 16px;margin-bottom:12px;border-radius:13px;font:500 .92rem 'DM Sans',sans-serif;outline:none;box-sizing:border-box;
  background:var(--lgc-input-bg);border:1.5px solid var(--lgc-input-border);color:var(--lgc-input-text);transition:border-color .2s,box-shadow .2s,background .2s}
.lgc-input::placeholder{color:var(--lgc-input-ph)}
.lgc-input:focus{border-color:#5bc4c0;box-shadow:0 0 0 3px rgba(91,196,192,.25);background:var(--lgc-input-focus-bg)}
.lgc-btn{display:block;width:100%;padding:14px;margin-top:8px;border:0;border-radius:13px;cursor:pointer;font:700 .95rem 'DM Sans',sans-serif;color:#fff;
  background:var(--grad,linear-gradient(120deg,#1a5c8a,#5bc4c0));position:relative;overflow:hidden;
  box-shadow:0 6px 22px rgba(26,92,138,.45);transition:transform .15s,box-shadow .15s}
.lgc-btn:hover{transform:translateY(-2px);box-shadow:0 10px 30px rgba(26,92,138,.55)}
.lgc-btn:active{transform:translateY(0)}
.lgc-btn:disabled{opacity:.6;cursor:wait;transform:none}
/* Reflet : animé en transform (compositeur) et non en `left` (layout à chaque frame).
   Équivalence visuelle exacte : l'élément fait 60% du bouton, et translateX(%) est
   relatif à l'ÉLÉMENT quand left(%) l'est au bouton → left:-120% ≙ translateX(-200%),
   left:160% ≙ translateX(266.667%). Le skewX d'origine reste dans le même transform. */
.lgc-btn::after{content:"";position:absolute;top:0;left:0;width:60%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.45),transparent);transform:translateX(-200%) skewX(-20deg);animation:lgc-shine 4.5s ease-in-out infinite}
@keyframes lgc-shine{0%,58%{transform:translateX(-200%) skewX(-20deg)}78%,100%{transform:translateX(266.667%) skewX(-20deg)}}
.lgc-foot{margin-top:20px;font-size:.74rem;line-height:1.5;color:var(--lgc-foot)}
.lgc-foot a{color:inherit;font-weight:600}

/* ── Bandeau d'erreur login (partagé index.html + dentiste.html) ──
   dentiste.html : toggle via la classe .show ; index.html : toggle via style.display
   inline (js/auth.js) — l'inline gagne sur le display:none ci-dessous. */
.lgc-error {
  display: none;
  margin-top: 12px;
  padding: 10px 14px;
  background: #ffebee;
  color: #c62828;
  border: 1px solid #ef9a9a;
  border-radius: 10px;
  font-size: 0.82rem;
  text-align: left;
}
.lgc-error.show { display: block; }
html[data-theme="dark"] .lgc-scene .lgc-error,
.lgc-scene--dark .lgc-error { background:#3a1414; color:#ffb4ab; border-color:#7a2a24; }

/* ── Messages du formulaire « mot de passe oublié » (js/password-reset.js, #pr-message) ──
   Tokens de style.css (clair + sombre gérés par les tokens eux-mêmes). */
.lgc-msg-err { color: var(--danger); }
.lgc-msg-muted { color: var(--muted); }
.lgc-msg-ok { color: var(--success); }

/* Accessibilité : mouvement réduit → on fige, sans toucher au reste de l'app */
@media (prefers-reduced-motion:reduce){
  .lgc-scene *{animation:none!important}
}

/* ── Encarts de contexte de la carte de connexion (chat.html) ──
   .lgc-note : une phrase qui dit POURQUOI on voit cet écran. La variante --app
   (première ouverture de l'app Chat installée, qui n'a pas la session de l'app
   complète) ne s'affiche qu'en mode application, via display-mode — sans JS.
   .lgc-guide : guide d'installation de l'app Chat, révélé À LA PLACE du
   formulaire par js/pwa-install-chat.js (html.scx-guide, arrivée avec
   #installer). Le bouton 1 appui remplace les gestes manuels dès que le
   navigateur propose l'installation (html.scx-prompt-ready) ; les gestes
   suivent l'appareil (html.scx-ios). Couleurs = tokens .lgc-* → clair/sombre
   suivent tout seuls. */
.lgc-note{display:none;margin:0 0 14px;padding:10px 12px;border-radius:12px;text-align:left;font-size:.8rem;line-height:1.45;
  color:var(--lgc-input-text);background:var(--lgc-input-bg);border:1px solid var(--lgc-input-border)}
@media (display-mode:standalone){.lgc-note--app{display:block}}
.lgc-guide{display:none;text-align:left}
html.scx-guide .lgc-guide{display:block}
html.scx-guide #login-form-wrap{display:none}
/* Le guide PRIME sur la session : auth.js masque #login-screen et révèle
   #app-content en style en ligne dès qu'un utilisateur est connecté — et sur
   l'adresse du chat on l'est souvent déjà (session partagée Chrome ⇄ app
   installée). Sans ces règles, on arrivait « pour installer » et on tombait sur
   le chat ouvert, le guide caché dessous (vécu le 11/09/2026). Le spinner de
   boot n'a rien à faire non plus devant un guide statique. js/chat-boot.js
   n'ouvre pas le chat tant que html.scx-guide est posée. */
html.scx-guide #login-screen{display:flex!important}
html.scx-guide #app-content,html.scx-guide #app-loading{display:none!important}
.lgc-guide-t{margin:4px 0 12px;font-size:1rem;font-weight:700;text-align:center;color:var(--lgc-input-text)}
.lgc-guide-p{margin:0 0 12px;font-size:.84rem;line-height:1.5;text-align:center;color:var(--lgc-input-text)}
.lgc-guide-btn{margin:0 0 10px}
html:not(.scx-prompt-ready) .lgc-guide-btn,html:not(.scx-prompt-ready) .lgc-guide-ready{display:none}
.lgc-guide-steps{margin:0 0 4px;padding-left:1.3em;font-size:.84rem;line-height:1.5;color:var(--lgc-input-text)}
.lgc-guide-steps li{margin:0 0 8px}
html.scx-prompt-ready .lgc-guide-manual{display:none}
html:not(.scx-ios) .lgc-guide-ios{display:none}
html.scx-ios .lgc-guide-android{display:none}
/* Après « appinstalled » (html.scx-installed) : le guide reste et dit la suite,
   au lieu de disparaître d'un coup sur un formulaire ou sur le chat. */
.lgc-guide-apres{display:none}
html.scx-installed .lgc-guide-apres{display:block}
html.scx-installed .lgc-guide-avant,html.scx-installed .lgc-guide-btn,html.scx-installed .lgc-guide-manual{display:none!important}
