/* Meme palette et meme typographie que la console : c'est la meme piece. */
@font-face {
  font-family: 'Pixel MC';
  src: url('calques/pixel_mc.ttf') format('truetype');
  font-display: swap;
}

:root {
  --fond: #1a1a2e;
  --surface: #16213e;
  --texte: #ffffff;
  --libelle: #a8a8a8;
  --ombre: #3f3f3f;
  --alerte: #ff5555;
  --vivant: #51cf66;
  --accent: #e94560;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: 'Pixel MC', ui-monospace, monospace;
  /* La police pixel n'a que du latin-1 : on ne la laisse pas se substituer
     silencieusement pour le reste. */
  -webkit-text-size-adjust: 100%;
  min-height: 100%;
}

body {
  display: flex; flex-direction: column;
  min-height: 100dvh;
  align-items: center; justify-content: center;
  gap: 12px; padding: 12px;
}

/* Les calques sont composes a 1106x960, au-dessus de ce qu'un telephone
   affiche : l'image est donc REDUITE, jamais agrandie. Le plus proche voisin,
   qui protegeait le dessin quand on l'agrandissait, jette ici une colonne sur
   deux et hache les diagonales — or une piece isometrique n'est faite que de
   diagonales. On laisse filtrer le navigateur. */
canvas {
  display: block;
  width: 100%; max-width: 720px; height: auto;
  background: var(--fond);
}

.scene { position: relative; width: 100%; max-width: 720px; }

/* `hidden` vient de la feuille du navigateur, ou il ne pese presque rien :
   la moindre regle d'auteur qui pose un `display` sur le meme element gagne,
   et l'attribut ne cache plus rien. `#chargement { display: flex }` suffisait
   a laisser le voile par-dessus la piece, pour toujours. */
[hidden] { display: none !important; }

#chargement {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; gap: 10px;
  align-items: center; justify-content: center;
  background: var(--fond); font-size: 14px; color: var(--libelle);
}
.barre { width: 60%; height: 4px; background: #2a2a44; }
.barre > i { display: block; height: 100%; width: 0; background: var(--accent); }

.panneau {
  width: 100%; max-width: 720px;
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 8px; text-align: center;
}
.bloc { min-width: 0; }
/* Cinq colonnes au lieu de quatre : la typo doit reculer sur un ecran etroit,
   sinon les deux libelles les plus longs sont coupes. Mesure sur `pixel_mc` —
   « lecture » vaut 74 px a 24 px, « ORDINATEUR » 70 px a 12 px, et une colonne
   sur cinq n'en offre que 67 sur un telephone de 390 px de large. Les bornes du
   `clamp` gardent exactement les tailles d'avant des que la place revient. */
.valeur {
  font-size: clamp(18px, 5.2vw, 24px); line-height: 1.1;
  text-shadow: 3px 3px 0 var(--ombre);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.libelle {
  font-size: clamp(10px, 2.8vw, 12px); color: var(--libelle);
  text-shadow: 2px 2px 0 var(--ombre);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.barre-etat {
  width: 100%; max-width: 720px;
  display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; color: var(--libelle);
}
.etat { display: inline-flex; align-items: center; gap: 6px; }
.rond {
  width: 8px; height: 8px; flex: none;
  border-radius: 50%; background: var(--vivant);
}
.direct { color: var(--vivant); }
.hors { color: var(--alerte); display: none; }
body.horsligne .direct { display: none; }
body.horsligne .hors { display: inline; }
body.horsligne .rond { background: var(--alerte); }
body.horsligne canvas { filter: saturate(0.55) brightness(0.8); }

/* « Tres gentiment » : 2,8 s par cycle et jamais jusqu'a l'extinction. Un
   clignotement franc est une ALERTE — c'est le vocabulaire des voyants — alors
   qu'ici il ne signale rien d'anormal, il dit seulement que la liaison est
   vivante. On ne l'anime QUE dans l'etat vert : hors ligne, le temoin doit
   rester fixe, sans quoi la panne aurait l'air d'un battement de coeur.
   L'opacite est portee par le conteneur, donc le rond et le mot respirent
   ensemble ; deux animations separees se dephaseraient a la longue. */
@keyframes respire { 0%, 100% { opacity: 1; } 50% { opacity: 0.42; } }
body:not(.horsligne) .etat { animation: respire 2.8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  body:not(.horsligne) .etat { animation: none; }
}

button, .lien {
  font-family: inherit; font-size: 12px;
  color: var(--libelle); background: none;
  border: 2px solid #3b2e7a; padding: 6px 10px;
  cursor: pointer;
}
button:hover, button:focus-visible { color: var(--texte); border-color: #6c5cc8; }

/* ---- connexion ---- */
.carte {
  width: 100%; max-width: 340px;
  display: flex; flex-direction: column; gap: 14px;
}
.carte h1 { font-size: 24px; margin: 0; text-shadow: 3px 3px 0 var(--ombre); }
.carte p { font-size: 12px; color: var(--libelle); margin: 0; line-height: 1.5; }
label { display: flex; flex-direction: column; gap: 6px; font-size: 12px; color: var(--libelle); }
input {
  font-family: inherit; font-size: 16px;      /* 16px : en dessous, iOS zoome */
  color: var(--texte); background: var(--surface);
  border: 2px solid #3b2e7a; padding: 10px;
}
input:focus { outline: none; border-color: #6c5cc8; }
.envoi { border-color: #6c5cc8; color: var(--texte); font-size: 14px; padding: 10px; }
.erreur { color: var(--alerte); font-size: 12px; }

@media (orientation: landscape) and (min-width: 700px) {
  body { flex-direction: row; flex-wrap: wrap; align-content: center; }
  /* Un telephone couche est large et TRES bas : c'est la hauteur qui manque,
     jamais la largeur. Le canevas gardant ses proportions, on le borne par une
     largeur deduite de la hauteur disponible — sinon la piece descend sous le
     bord de l'ecran et on en perd le sol. */
  .scene { flex: 1 1 60%; max-width: calc((100dvh - 76px) * 553 / 480); }
  .panneau { flex: 1 1 30%; grid-template-columns: repeat(2, 1fr); max-width: 320px; }
  /* Cinq blocs sur deux colonnes laissent le dernier seul sur sa ligne : on le
     fait tenir toute la largeur plutot que de le laisser pendre a gauche. */
  .panneau .bloc:last-child { grid-column: 1 / -1; }
  .barre-etat { flex: 1 1 100%; }
}

/* ---------------------------------------------------------- code & appareils */

.discret {
  color: var(--libelle); font-size: 12px; text-align: center;
  text-decoration: underline; padding: 4px;
}
.carte.large { max-width: 520px; }
.aide { font-size: 12px; color: var(--libelle); line-height: 1.5; margin: 0; }
.code {
  font-size: 15px; color: var(--texte); background: var(--primaire, #0f3460);
  border: 2px solid #6c5cc8; padding: 10px; margin: 0; word-break: break-all;
}

.appareil {
  display: flex; flex-direction: column; gap: 6px;
  border: 2px solid #2a2a44; padding: 10px;
}
.appareil.moi { border-color: #6c5cc8; }
.appareil.sorti { opacity: 0.55; }
.ligne { display: flex; gap: 6px; align-items: stretch; }
.ligne .nom {
  flex: 1 1 auto; min-width: 0;
  font-family: inherit; font-size: 16px;   /* 16px : en dessous, iOS zoome */
  color: var(--texte); background: var(--surface);
  border: 2px solid #3b2e7a; padding: 8px;
}
.mini {
  font-family: inherit; font-size: 13px; padding: 6px 12px;
  color: var(--texte); background: var(--surface); border: 2px solid #6c5cc8;
}
.mini.danger { border-color: var(--alerte); color: var(--alerte); }
.detail {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  font-size: 12px; color: var(--libelle);
}
.detail .marque { color: #6c5cc8; }

/* Le bouton de sortie non plus. Cacher n'est pas interdire — `/deconnexion`
   repond toujours — mais c'est desormais sans consequence : sortir conserve le
   nom et le tour du jour, et ressaisir le code ramene au meme endroit. */
.sortie { display: none; }
body.proprietaire .sortie { display: block; }

/* Le lien d'administration n'apparait que pour le proprietaire. Le serveur pose
   la classe ; sans elle, le lien reste dans le HTML mais invisible — et de
   toute facon `/qui` repond 403 a qui n'est pas proprietaire. */
.quiestla { display: none; }
body.proprietaire .quiestla {
  display: inline; color: var(--libelle); font-size: 12px;
  text-decoration: underline; margin-right: auto;
}

/* ------------------------------------------------------------------ commandes */

.rangee {
  width: 100%; max-width: 720px;
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center; justify-content: center;
  font-size: 12px; color: var(--libelle); min-height: 0;
}
.mot:empty { display: none; }

/* Rien de tout ca n'existe si le serveur n'a pas marque le `<body>` : sans
   crochet configure il n'y a rien a proposer. Ce n'est PAS la protection —
   `/commande` revoit droit et quota a chaque appel — c'est ne pas montrer une
   porte fermee.

   L'attribut `hidden` pilote ensuite l'etat courant depuis le script, et il
   gagne sur ces regles grace au `!important` de `[hidden]` plus haut. */
.rangee > button, .rangee > form { display: none; }
body.commandes #fete { display: inline-block; }
.rangee > span.moi { display: none; }
body.commandes #moi { display: inline-block; }

.identite { gap: 6px; align-items: center; }
.identite label { flex-direction: row; }
.lettre {
  width: 2.2em; text-align: center; text-transform: uppercase;
  font-family: inherit; font-size: 16px;   /* 16px : en dessous, iOS zoome */
  color: var(--texte); background: var(--surface);
  border: 2px solid #3b2e7a; padding: 8px 0;
}
.lettre:focus { outline: none; border-color: #6c5cc8; }
/* Le nom s'AFFICHE, il ne se clique pas : ni bordure, ni fond, ni curseur de
   pointeur. Encadre, il invitait a le changer — alors qu'il est unique, qu'il
   porte le quota, et qu'il se choisit une seule fois a l'arrivee. */
.moi {
  letter-spacing: 2px; color: var(--libelle);
  font-size: 12px; padding: 6px 2px; cursor: default;
}
.valeur.on { color: #8fd0ff; }

/* ---- l'ecran d'accueil : les trois cases, en grand et au milieu ---- */
.accueil { max-width: 360px; text-align: center; align-items: center; }
.accueil h1 { font-size: 28px; }
.accueil .envoi { width: 100%; }
.logo.grand { width: 96px; height: 96px; }
.lettres { display: flex; gap: 12px; justify-content: center; }
.lettre.grande {
  width: 72px; height: 88px; font-size: 44px; padding: 0;
  line-height: 88px; caret-color: transparent;
}
@media (max-width: 380px) {
  .lettre.grande { width: 58px; height: 72px; font-size: 34px; line-height: 72px; }
  .lettres { gap: 8px; }
}
button:disabled { opacity: 0.45; cursor: default; border-color: #2a2a44; }
button:disabled:hover { color: var(--libelle); border-color: #2a2a44; }

/* Le logo, sur la page d'entree. Pris dans la version 512 puis REDUIT : a
   l'agrandissement il aurait fallu un facteur entier pour rester net, alors
   qu'a la reduction le lissage du navigateur rend service. */
.logo { display: block; width: 64px; height: 64px; margin: 0 0 2px; }
