/*
  The lock — écran contrôleuse.

  Le langage visuel vient de `mockups/login.html` (Phase 0) : fond noir bleuté,
  accent cyan givré unique, serif pour les chiffres, cadenas sur cadran
  horloger. Les jetons de couleur et les deux familles de police sont repris
  tels quels ; les styles, eux, ne sont plus inline — la CSP porte
  `style-src 'self'`, et un attribut `style=` posé dans le HTML serait refusé.

  Un seul écart de composition avec la maquette, et il est délibéré : le cadran
  devient la jauge. Ses traits de minute s'allument à mesure que le quota se
  consomme, le chiffre restant s'installe au centre, et le cadenas descend en
  sous-cadran à six heures — la place qu'occupe une petite seconde sur une
  montre. La maquette de login, elle, garde sa composition d'origine.
*/

:root {
  color-scheme: dark;

  --noir:   #07090c;   /* fond, noir bleuté */
  --panne:  #10161f;   /* haut du corps du cadenas */
  --creux:  #0b0f15;   /* bas du corps du cadenas */
  --trait:  #435061;   /* contours acier */
  --brume:  #8494a7;   /* texte secondaire */
  --clair:  #e8eef5;   /* texte principal */
  --givre:  #9fd6e4;   /* accent unique : cyan givré */

  /* Deux teintes de service, hors palette d'accent. */
  --braise: #d99a5b;   /* un signal qui demande une lecture */
  --eteint: #2e3947;   /* trou de serrure au repos */

  --serif: ui-serif, "New York", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Angle du secteur consommé, en degrés de `stroke-dashoffset` : 360 = cadran
     vierge, 0 = quota entièrement brûlé. Seule variable pilotée par app.js. */
  --jauge: 360;
}

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

/* `hidden` doit gagner contre les `display: flex` des vues. */
[hidden] { display: none !important; }

html { height: 100%; }

body {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--sans);
  color: var(--clair);
  background:
    radial-gradient(circle at 50% 34%, rgba(159, 214, 228, 0.055), transparent 58%),
    var(--noir);
  -webkit-tap-highlight-color: transparent;
}

/* Le porteur des dégradés partagés : présent dans le document, invisible. */
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.scene {
  width: min(100%, 23rem);
  margin: auto;
  padding: 2rem 1.5rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.vue {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ---------------------------- Emblème commun ---------------------------- */

.embleme svg { display: block; width: 100%; height: auto; }

.embleme-login { width: clamp(190px, 52vw, 238px); margin-bottom: 1.1rem; }
.embleme-jauge { width: clamp(210px, 62vw, 268px); margin-bottom: 0.6rem; }

/* Cadran horloger : soixante traits de minute, douze traits d'heure. */
.cadran .minutes { stroke: #232c38; stroke-width: 4.5; }
.cadran .heures  { stroke: #313d4d; stroke-width: 8; }

/* Les mêmes traits, allumés, ne se voient qu'à travers le secteur consommé. */
.cadran-vif .minutes { stroke: var(--givre); }
.cadran-vif .heures  { stroke: var(--givre); }

/*
  Le secteur consommé. Blanc, parce qu'un masque SVG lit la luminance : blanc
  révèle, noir cache. `--jauge` est le seul chiffre que app.js y injecte.
*/
.secteur {
  fill: none;
  stroke: #fff;
  stroke-width: 26;
  stroke-dasharray: 360 360;
  stroke-dashoffset: var(--jauge);
  transition: stroke-dashoffset 1s linear;
}

/* Cadenas : mêmes formes que la maquette, états pilotés par `.verrouille`. */
.acier-haut { stop-color: #7d8ea3; }
.acier-bas  { stop-color: #46536a; }
.fonte-haut { stop-color: var(--panne); }
.fonte-bas  { stop-color: var(--creux); }
.halo-coeur { stop-color: var(--givre); stop-opacity: 0.55; }
.halo-bord  { stop-color: var(--givre); stop-opacity: 0; }

.anse {
  fill: none;
  stroke: url(#acier);
  stroke-width: 11;
  stroke-linecap: round;
  transform: translateY(-27px);
  transition: transform 0.6s cubic-bezier(0.34, 1.28, 0.64, 1);
}
.corps { fill: url(#fonte); }
.contour { fill: none; stroke: var(--trait); stroke-width: 2; }
.lueur { fill: url(#halo); opacity: 0; transition: opacity 0.6s ease; }
.trou { fill: var(--eteint); transition: fill 0.45s ease 0.15s; }

/* Verrou posé : l'anse tombe, le trou de serrure s'allume. */
.verrouille .anse { transform: translateY(0); }
.verrouille .lueur { opacity: 0.26; }
.verrouille .trou { fill: var(--givre); }

/* Séquence d'entrée, réservée à la page de login (héritée de la maquette). */
.embleme-login .cadran { animation: apparait 0.9s ease-out both; }
.cadenas-entree .contour { stroke-dasharray: 100; animation: trace 0.6s cubic-bezier(0.65, 0, 0.35, 1) 0.05s both; }
.cadenas-entree .corps { animation: apparait 0.55s ease-out 0.2s both; }
.cadenas-entree .anse { animation: anse-tombe 0.62s 0.4s both; }
.cadenas-entree .trou { animation: allumage 0.5s ease-out 0.78s both; }
.cadenas-entree .lueur { animation: lueur-nait 1.1s ease-out 0.78s both; }

/* ------------------------------- Chiffres ------------------------------- */

.chiffre {
  font-family: var(--serif);
  font-size: 46px;
  font-weight: 600;
  fill: var(--clair);
}

.legende {
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  fill: var(--brume);
}

.sommaire {
  font-size: 0.95rem;
  color: var(--brume);
}

.nombre {
  font-family: var(--serif);
  font-size: 1.1rem;
  color: var(--clair);
}

/* -------------------------------- Textes -------------------------------- */

.marque {
  font-family: var(--serif);
  font-size: clamp(2.15rem, 9vw, 2.85rem);
  font-weight: 600;
  letter-spacing: 0.005em;
}

.titre {
  font-family: var(--serif);
  font-size: 1.7rem;
  font-weight: 600;
  margin-top: 0.4rem;
}

.eyebrow {
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brume);
}

.devise {
  margin-top: 0.55rem;
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--brume);
}

.discret {
  margin-top: 0.5rem;
  font-size: 0.82rem;
  color: var(--brume);
}

.annonce {
  min-height: 1.5rem;
  margin-top: 1.2rem;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--givre);
}

/* -------------------------------- Blocs --------------------------------- */

.bloc {
  width: 100%;
  margin-top: 1.6rem;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(67, 80, 97, 0.35);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
}

/* ------------------------------- Boutons -------------------------------- */

.btn {
  font: 500 1rem/1.2 var(--sans);
  letter-spacing: 0.01em;
  color: var(--clair);
  background: rgba(159, 214, 228, 0.03);
  border: 1px solid rgba(159, 214, 228, 0.38);
  border-radius: 14px;
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color 0.25s ease, background-color 0.25s ease, transform 0.15s ease;
}

.btn-primaire {
  margin-top: 1.6rem;
  width: 100%;
  max-width: 20rem;
  min-height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.85rem 1.4rem;
}

.btn-primaire .cle { flex: none; opacity: 0.9; }

.btn-verrou {
  width: 100%;
  min-height: 52px;
  padding: 0.85rem 1.4rem;
}

/* Verrou manuel posé : le bouton porte la couleur du signal, pas de l'accent. */
.btn-verrou.pose {
  color: var(--braise);
  border-color: rgba(217, 154, 91, 0.5);
  background: rgba(217, 154, 91, 0.06);
}

.btn-pas {
  width: 3rem;
  height: 3rem;
  font-size: 1.35rem;
  line-height: 1;
  border-radius: 50%;
}

@media (hover: hover) {
  .btn:hover { border-color: rgba(159, 214, 228, 0.75); background: rgba(159, 214, 228, 0.07); }
  .btn-verrou.pose:hover { border-color: rgba(217, 154, 91, 0.85); background: rgba(217, 154, 91, 0.1); }
}

.btn:active { transform: scale(0.985); }

.btn[disabled] { opacity: 0.45; cursor: default; transform: none; }

:focus-visible {
  outline: 2px solid var(--givre);
  outline-offset: 3px;
  border-radius: 14px;
}

/* -------------------------------- Quota --------------------------------- */

.stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
}

.quota-valeur {
  min-width: 6rem;
  font-family: var(--serif);
  font-size: 1.65rem;
  color: var(--clair);
}

/* ------------------------------ Formulaire ------------------------------ */

.champ {
  align-self: flex-start;
  margin-top: 1.6rem;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brume);
}

.saisie {
  width: 100%;
  min-height: 52px;
  margin-top: 0.5rem;
  padding: 0.8rem 1rem;
  font: 400 1rem/1.2 var(--sans);
  color: var(--clair);
  background: rgba(159, 214, 228, 0.03);
  border: 1px solid rgba(67, 80, 97, 0.7);
  border-radius: 14px;
}

.saisie:focus { border-color: rgba(159, 214, 228, 0.6); outline: none; }

/* -------------------------------- Listes -------------------------------- */

.liste {
  width: 100%;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  text-align: left;
  font-size: 0.9rem;
}

.ligne-titre { color: var(--clair); }
.ligne-detail { flex: none; font-size: 0.8rem; color: var(--brume); }

/* Une machine qui compte en ce moment : un point d'accent, pas un clignotant. */
.pastille {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: 0.5rem;
  border-radius: 50%;
  background: var(--eteint);
  vertical-align: 0.06em;
}

.compte .pastille { background: var(--givre); }

/* Une ligne d'usage porte TROIS informations et non deux : le nom et le délai
   tiennent la première ligne, l'heure absolue et le total du jour passent
   dessous. Mises bout à bout, elles se tronqueraient sur un téléphone — or la
   date est précisément ce qu'on vient lire ici. */
.ligne-usage { flex-wrap: wrap; row-gap: 0.15rem; }

.ligne-sous {
  flex-basis: 100%;
  font-size: 0.78rem;
  color: var(--brume);
}

/* Deux dates de natures différentes se suivent : l'étiquette est ce qui les
   empêche de se lire l'une pour l'autre. Assez large pour que les valeurs
   s'alignent, sinon l'œil compare des colonnes qui ne le sont pas. */
.sous-nom {
  display: inline-block;
  min-width: 6.5rem;
  color: var(--eteint);
}

/* Alertes : la braise pour ce qui demande une lecture, la brume pour ce qui
   s'est résolu tout seul. */
.alerte .ligne-titre { color: var(--braise); }
.alerte-apaisee .ligne-titre { color: var(--brume); }

.vide { font-size: 0.85rem; color: var(--brume); text-align: left; }

/* -------------------------------- Liens --------------------------------- */

.lien {
  font: 400 0.8rem/1.2 var(--sans);
  letter-spacing: 0.02em;
  color: var(--brume);
  background: none;
  border: none;
  padding: 0.4rem 0.2rem;
  text-decoration: underline;
  text-underline-offset: 0.25em;
  cursor: pointer;
}

.lien-bloc { margin-top: 1rem; }

@media (hover: hover) {
  .lien:hover { color: var(--givre); }
}

.pied {
  padding: 1rem 1.5rem;
  padding-bottom: max(1.1rem, env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--brume);
}

/* ------------------------- Séquence de la maquette ---------------------- */

@keyframes trace {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

@keyframes apparait {
  from { opacity: 0; }
}

@keyframes anse-tombe {
  0%   { transform: translateY(-27px); animation-timing-function: cubic-bezier(0.55, 0, 0.83, 0.34); }
  62%  { transform: translateY(2.6px); animation-timing-function: cubic-bezier(0.2, 0.6, 0.35, 1); }
  80%  { transform: translateY(-2.1px); animation-timing-function: cubic-bezier(0.35, 0, 0.65, 1); }
  100% { transform: translateY(0); }
}

@keyframes allumage {
  0%   { fill: var(--eteint); }
  22%  { fill: #eafbff; }
  100% { fill: var(--givre); }
}

@keyframes lueur-nait {
  0%   { opacity: 0; }
  16%  { opacity: 0.75; }
  100% { opacity: 0.26; }
}

/*
  Mouvement réduit : rien ne bouge, tout reste lisible. Le cadenas est
  directement dans son état, la jauge saute à sa valeur, l'entrée est un simple
  fondu — comme dans la maquette.
*/
@media (prefers-reduced-motion: reduce) {
  .cadran, .cadenas, .contour, .corps, .anse, .trou, .lueur { animation: none; }
  .anse, .trou, .lueur, .secteur { transition: none; }
  .cadenas-entree .contour { stroke-dasharray: none; }
  body { animation: fondu 0.6s ease both; }
}

@keyframes fondu {
  from { opacity: 0; }
  to   { opacity: 1; }
}
