/* ---------------------------------------------------------------------
   Écran de verrouillage façon lockscreen + saisie de code, maintenant
   combiné avec l'application dans index.php. Le fond (dégradé, lueur
   ambrée, particules montantes) vient de style.css, partagé avec
   l'application. Tout le reste de l'écran de verrouillage — ainsi que la
   bascule entre les deux interfaces (voir tout en bas) — est ici.
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   Écran de verrouillage : horloge centrée
   --------------------------------------------------------------------- */

#zone-verrouillage {
  position: fixed;
  /* inset:0 (plutôt qu'une hauteur limitée au premier quart d'écran) :
     #horloge-verrouillage est désormais positionné en fixed lui-même et
     doit rester calé sur les coordonnées du viewport même quand ce
     conteneur devient un contexte de positionnement (le "filter"
     appliqué ci-dessous en mode-code en fait un bloc englobant pour ses
     descendants fixed) — en couvrant tout l'écran, ça revient au même. */
  inset: 0;
  z-index: 2;
  pointer-events: none;
  transition: opacity .5s ease, filter .5s ease;
}

/* En mode saisie du code, l'horloge recule doucement au second plan
   plutôt que de disparaître d'un coup — comme sur un vrai écran de
   verrouillage. */
body.mode-code #zone-verrouillage {
  opacity: .38;
  filter: blur(2px);
}

/* Espace réservé au slider (voir #glisser-zone : bottom 2.2rem + hauteur
   de piste 4.9rem) : l'horloge se centre sur l'espace libre au-dessus,
   pas sur l'écran entier. */
:root {
  --espace-slider: 7.1rem;
}

/* Centrage par positionnement fixed (plutôt que flex + margin:auto) :
   garantit un centrage exact indépendamment de la largeur relative des
   blocs heure/date, sans dépendre de calculs de largeur en cascade. Au
   repos, centré sur l'espace libre au-dessus du slider ; en mode-code,
   remonte et rétrécit vers sa position/taille d'origine (voir plus bas). */
#horloge-verrouillage {
  width: 100%;
  position: fixed;
  left: 50%;
  top: calc((100vh - var(--espace-slider)) / 2);
  transform: translate(-50%, -50%);
  font-family: 'DSEG7 Classic', 'Courier New', monospace;
  text-align: center;
  display: flex;
  justify-content: center;
  transition: top .5s ease;
}

/* Quand le voile de code apparaît, l'horloge remonte presque tout en
   haut de l'écran (elle recule aussi en opacité/flou via
   #zone-verrouillage ci-dessus) plutôt que de rester centrée — et
   rétrécit en même temps vers sa taille d'origine (voir .cadran--heure /
   .cadran--date plus bas), pour ne pas gêner le clavier. */
body.mode-code #horloge-verrouillage {
  top: 80px;
}

/* Les classes .cadran / .cadran--heure / .cadran--date / .segments-fond /
   .segments-actifs / #deuxpoints viennent de style.css (génériques, pas
   liées à l'id #horloge de la page principale) : seule la taille et le
   centrage changent ici, pour un rendu façon lockscreen plutôt que coin
   d'écran. Taille au repos = 1.25x la taille d'origine (4.6rem) ; en
   mode-code, retour à cette taille d'origine en même temps que la
   remontée ci-dessus. */
#horloge-verrouillage .cadran--heure {
  font-size: 5.75rem;
  transition: font-size .5s ease;
}

body.mode-code #horloge-verrouillage .cadran--heure {
  font-size: 4.6rem;
}

/* Même clignotement des ":" que l'horloge de l'application (voir
   #deuxpoints dans style.css) : id différent pour éviter le doublon
   maintenant que les deux horloges vivent dans le même document, mais
   même keyframe (globale, définie une seule fois dans style.css). */
#deuxpoints-verrouillage {
  animation: clignoter 1s steps(1, end) infinite;
}
@media (prefers-reduced-motion: reduce) {
  #deuxpoints-verrouillage { animation: none; }
}

/* Le centrage par "margin: auto" dépend de la largeur "shrink-to-fit" du
   parent, qui s'est révélée peu fiable ici (la date rendait décalée vers
   la droite malgré margin:auto). On réutilise donc exactement la même
   technique que pour #horloge-verrouillage lui-même — un centrage par
   position absolue — qui, elle, fonctionne de façon fiable : la date
   sort du flux et se recentre indépendamment sous l'heure, quelle que
   soit la largeur réellement calculée du bloc parent. */
#horloge-verrouillage .cadran--date {
  position: absolute;
  top: 100%;
  margin-top: .5rem;
  margin-left: -1px;
  white-space: nowrap;
  font-size: 1.25rem;
  text-align: center;
  width: 100%;
  display: flex;
  justify-content: center;
  transition: font-size .5s ease;
}

body.mode-code #horloge-verrouillage .cadran--date {
  font-size: 1rem;
}

#horloge-verrouillage .cadran--date span{
  width: 100%;
}

/* ---------------------------------------------------------------------
   Glisser pour déverrouiller (façon iOS 6, en verre dépoli)
   --------------------------------------------------------------------- */

#glisser-zone {
  position: fixed;
  left: 50%;
  bottom: 2.2rem;
  transform: translateX(-50%);
  width: min(23rem, calc(100vw - 3rem));
  z-index: 2;
  transition: opacity .4s ease, transform .4s ease;
}
#glisser-zone.masque {
  opacity: 0;
  transform: translateX(-50%) translateY(.8rem);
  pointer-events: none;
}

#glisser-piste {
  --progression: 0;
  --remplissage-largeur: 0px;
  --remplissage-hauteur: 0px;
  position: relative;
  /* 4.9rem - 8px (marge haut+bas du bouton, voir #glisser-bouton) = 4.4rem,
     exactement la largeur du bouton : il reste ainsi parfaitement rond au
     repos. */
  height: 4.9rem;
  border-radius: 2.45rem;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(242,238,251,.22);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  overflow: hidden;
  display: flex;
  align-items: center;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Remplissage de progression : un blanc transparent et doux, flouté, qui
   part du centre de la piste comme un petit cercle, grandit d'abord en
   restant circulaire, puis continue à s'élargir une fois la hauteur de
   la piste atteinte, jusqu'à la remplir entièrement. --remplissage-largeur
   / --remplissage-hauteur sont calculées en JS (voir positionnerBouton). */
#glisser-piste::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: var(--remplissage-largeur);
  height: var(--remplissage-hauteur);
  border-radius: 999px;
  background: rgba(255,255,255,.3);
  filter: blur(8px);
  pointer-events: none;
}

#glisser-texte {
  position: relative;
  width: 100%;
  /* Centré sur l'espace libre du slider (hors du rond à glisser, posé à
     gauche), pas sur toute la largeur de la piste. */
  padding-left: calc(4.4rem + 4px);
  text-align: center;
  font-size: .82rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  pointer-events: none;
  /* Chatoiement façon iOS 6 : un reflet clair qui balaie le texte en
     boucle. */
  background: linear-gradient(90deg, var(--sourdine) 35%, #fff 50%, var(--sourdine) 65%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: chatoiement 2.6s linear infinite;
  /* Disparaît progressivement au fil du glissement (--progression, mise
     à jour par le JS sur #glisser-piste et héritée ici) : totalement
     invisible dès 60% du parcours plutôt qu'à 100%. clamp() évite une
     opacité négative au-delà de ce seuil. */
  opacity: clamp(0, calc(1 - var(--progression) / 0.6), 1);
  transition: opacity .12s linear;
}
@keyframes chatoiement {
  from { background-position: 100% 0; }
  to   { background-position: -100% 0; }
}
@media (prefers-reduced-motion: reduce) {
  #glisser-texte { animation: none; color: var(--sourdine); background: none; }
}

/* Le rond ne se déplace plus le long de la piste : il s'étire en largeur
   (bord gauche fixe) via le "width" mis à jour par le JS pendant le
   glissement, plutôt qu'un translateX. La flèche reste ancrée à droite
   (justify-content: flex-end) quelle que soit la largeur atteinte.
   Hauteur fixée à la même valeur que la largeur (plutôt que déduite de
   "top/bottom: 4px") : avec le border-box et la bordure de la piste, ce
   calcul ne tombait pas pile sur un carré parfait (66 x 63.5px mesurés) —
   un centrage vertical par transform garantit un cercle exact. */
#glisser-bouton {
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 4.2rem;
  height: 4.2rem;
  border-radius: 999px;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(242,238,251,.4);
  color: var(--encre);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 1.3rem;
  cursor: grab;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
#glisser-bouton:active { cursor: grabbing; }

/* ---------------------------------------------------------------------
   Saisie du code (pastilles + pavé numérique), révélée après le
   glissement. Le flou de "l'écran qui devient flou" est obtenu en
   floutant directement #braises/#lueur (voir plus bas) plutôt que via un
   backdrop-filter au-dessus : le canvas animé de fond ne se floute pas
   correctement à travers un backdrop-filter dans cet environnement.
   --------------------------------------------------------------------- */

#braises, #lueur {
  transition: filter .5s ease;
}
body.mode-code #braises {
  filter: blur(20px);
}
body.mode-code #lueur {
  filter: blur(20px);
}

#voile-code {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.8rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .45s ease;
}
body.mode-code #voile-code {
  opacity: 1;
  pointer-events: auto;
}

/* Assombrit nettement l'arrière-plan flouté derrière le clavier — il doit
   quasiment disparaître, sans devenir totalement invisible. */
#voile-code::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(6,7,14,.78);
}

#pastilles-code {
  display: flex;
  gap: 1.25rem;
}

/* Mauvais code : tremblement de gauche à droite façon iOS. */
@keyframes secousse-pastilles {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}
#pastilles-code.secousse {
  animation: secousse-pastilles .4s ease;
}
.pastille {
  width: .95rem;
  height: .95rem;
  border-radius: 50%;
  border: 1.5px solid rgba(242,238,251,.55);
  background: transparent;
  transition: background .2s ease, transform .2s ease, border-color .2s ease;
}
.pastille.remplie {
  background: var(--encre);
  border-color: var(--encre);
  transform: scale(1.15);
  box-shadow: 0 0 .6em rgba(126,224,201,.45);
}

#pave-numerique {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.33rem;
  width: min(19.8rem, 85vw);
}

.touche {
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid rgba(242,238,251,.2);
  background: rgba(255,255,255,.05);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--encre);
  font-size: 1.75rem;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
  transition: background .15s ease, transform .1s ease;
}
.touche:active {
  background: rgba(255,255,255,.16);
  transform: scale(.94);
}

/* "Annuler" et "Effacer" : boutons de commande, pas des chiffres — pas de
   contour circulaire pour bien les distinguer du pavé, comme sur un
   écran de code iOS. */
.touche.controle {
  border-color: transparent;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  font-size: .83rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--sourdine);
}
.touche.controle:active {
  background: rgba(255,255,255,.06);
  transform: none;
}

/* ---------------------------------------------------------------------
   Vue mobile
   --------------------------------------------------------------------- */

@media (max-width: 700px) {
  /* Même logique qu'en desktop : 1.25x au repos, retour à la taille
     d'origine (3.6rem) en mode-code. */
  #horloge-verrouillage .cadran--heure {
    font-size: 4.5rem;
  }
  body.mode-code #horloge-verrouillage .cadran--heure {
    font-size: 3.6rem;
  }
  #pave-numerique {
    width: min(18.5rem, 86vw);
  }
}

/* ---------------------------------------------------------------------
   Bascule écran de verrouillage <-> application (index.php combiné)

   La classe "verrouille" sur <body> (posée côté serveur selon la session,
   retirée/ajoutée côté client par le JS lors d'une connexion/déconnexion
   réussie) détermine quelle interface est visible. Les deux jeux
   d'éléments restent en permanence dans le DOM — seules l'opacité et une
   légère mise à l'échelle changent, pour un fondu-enchaîné plutôt qu'un
   simple "display: none" abrupt.
   --------------------------------------------------------------------- */

#zone-verrouillage,
#glisser-zone,
#voile-code {
  transition: opacity .5s ease, transform .5s ease, filter .5s ease;
}

#horloge,
#etat,
#local,
#bascule,
#conversation {
  transition: opacity .5s ease, transform .5s ease;
}

/* Connecté : l'application est visible, l'écran de verrouillage se
   dissipe en grossissant très légèrement, comme un voile qui s'écarte. */
body:not(.verrouille) #zone-verrouillage,
body:not(.verrouille) #glisser-zone,
body:not(.verrouille) #voile-code {
  opacity: 0;
  transform: scale(1.05);
  pointer-events: none;
}

/* Verrouillé : l'application est cachée (légèrement rétrécie), l'écran
   de verrouillage occupe toute la place. */
body.verrouille #horloge,
body.verrouille #etat,
body.verrouille #local,
body.verrouille #bascule,
body.verrouille #conversation {
  opacity: 0;
  transform: scale(.96);
  pointer-events: none;
}

/* La galaxie a sa propre animation d'arrivée/disparition, plus marquée
   que le simple fondu ci-dessus : à la déconnexion elle se referme sur
   elle-même en tournant légèrement et en se floutant, comme un astre qui
   s'éteint ; à la connexion, le même mouvement se joue à l'envers, comme
   si elle se reformait. */
#galaxie {
  transition: opacity 1s cubic-bezier(.22, .61, .36, 1),
              transform 1s cubic-bezier(.22, .61, .36, 1),
              filter 1s cubic-bezier(.22, .61, .36, 1);
}
body.verrouille #galaxie {
  opacity: 0;
  transform: scale(.4) rotate(-8deg);
  filter: blur(6px);
  pointer-events: none;
}
