/* Agentville - prototype. Palette « cozy town » façon Habbo / Animal Crossing. */
:root{
  --bg:#1b2335; --bg2:#232c44; --panel:#27314c; --ink:#eaf0ff; --muted:#9fb0d4;
  --accent:#ffd479; --line:#34406180;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:radial-gradient(1200px 600px at 50% -10%, #2b3865, var(--bg)) fixed;
  color:var(--ink); font:15px/1.45 system-ui,Segoe UI,Roboto,sans-serif; overflow:hidden;
}
#topbar{
  display:flex; align-items:center; justify-content:space-between;
  padding:10px 18px; background:#1a2236cc; border-bottom:1px solid var(--line); backdrop-filter:blur(6px);
}
#topbar h1{font-size:18px; margin:0; letter-spacing:.2px}
.tag{font-size:11px; font-weight:600; color:#0c1326; background:var(--accent);
  padding:2px 8px; border-radius:999px; margin-left:8px; vertical-align:middle}
/* Etat du miroir. On ne laisse jamais croire que la demo est du reel : la pastille dit
   toujours ce qu'on est en train de regarder. */
.tag.off{background:#4a5677; color:#cdd8f3}                    /* pas de serveur : demo seule */
.tag.wait{background:#5fb3a1; color:#08201b}                    /* branche, rien en cours */
.tag.live{background:#ff6b6b; color:#2a0a0a; animation:pulse 1.4s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.62}}
#clock{font-size:14px; color:var(--muted); font-variant:all-small-caps; letter-spacing:.5px}

main{display:flex; height:calc(100vh - 48px)}
#stage{flex:1; min-width:0; position:relative}
#stage canvas{display:block; width:100%; height:100%}

/* La largeur vient d'une VARIABLE : la poignee la modifie, la media query mobile la
   remplace sans avoir a defaire un style pose en ligne par le script. */
#side{width:var(--side-w,320px); flex:none; padding:14px; overflow:auto; background:#181f31;
  border-left:1px solid var(--line)}

/* Poignee de redimensionnement. 6px de large a l'ecran, mais une zone de PRISE de 14px
   (::before deborde de chaque cote) : viser 6 pixels a la souris est desagreable. */
#poignee{flex:none; width:6px; cursor:col-resize; background:var(--line);
  position:relative; touch-action:none}
#poignee::before{content:''; position:absolute; top:0; bottom:0; left:-4px; right:-4px}
#poignee:hover,#poignee:focus-visible,#poignee.actif{background:#6f86c9; outline:none}
/* Pendant le glissement, plus aucune selection de texte ni curseur qui change au survol :
   sinon on selectionne le chat en deplacant la poignee. */
body.redim{user-select:none; cursor:col-resize}
.panel{background:var(--panel); border:1px solid var(--line); border-radius:14px;
  padding:12px 14px; margin-bottom:14px}
.panel.mini{font-size:12.5px; color:var(--muted)}
.panel h2{font-size:12px; text-transform:uppercase; letter-spacing:1px; color:var(--muted);
  margin:0 0 8px}
.hint{font-size:11.5px; color:var(--muted); margin:8px 0 0}
code{background:#0d1426; padding:1px 5px; border-radius:5px; font-size:12px; color:#9ad}

#legend{list-style:none; margin:0; padding:0}
#legend li{display:flex; align-items:center; gap:9px; padding:6px 6px; border-radius:9px; cursor:pointer}
#legend li:hover{background:#ffffff10}
#legend .dot{width:14px; height:14px; border-radius:50%; flex:none; box-shadow:0 0 0 2px #ffffff22}
#legend .who{font-weight:600}
#legend .role{color:var(--muted); font-size:12px; margin-left:auto}

#journal{list-style:none; margin:0; padding:0; font-size:12.5px; max-height:230px; overflow:auto}
#journal li{padding:4px 0; border-bottom:1px dashed #ffffff12; color:#cdd8f3}
#journal li .ev{color:var(--accent); font-weight:600}
#journal li .demo{color:#7f8db3; font-size:10px}
/* Le reel se voit d'un coup d'oeil, sans lire : c'est toute la promesse de la page. */
#journal li .demo.reel{color:#0c1326; background:#5fb3a1; font-weight:700;
  padding:1px 6px; border-radius:999px}
#journal li.passe{opacity:.55}                                  /* deja arrive, non anime */
.hint .demo{font-size:10px; color:#7f8db3}
.hint .demo.reel{color:#0c1326; background:#5fb3a1; font-weight:700;
  padding:1px 6px; border-radius:999px}

/* Carte au clic (popup) */
#card{position:fixed; inset:0; display:grid; place-items:center; background:#0008;
  z-index:50; transition:opacity .15s}
#card.hidden{opacity:0; pointer-events:none}
#card-inner{width:min(420px,92vw); background:linear-gradient(180deg,#2a3556,#222c47);
  border:1px solid #4a5a8a; border-radius:18px; padding:22px 24px; box-shadow:0 24px 60px #000a}
#card-inner h3{margin:0 0 2px; font-size:21px}
#card-inner .sub{color:var(--muted); margin:0 0 14px; font-size:13px}
#card-inner ul{margin:0 0 16px; padding-left:18px}
#card-inner li{margin:6px 0}
#card-inner .cta{display:block; background:var(--accent); color:#10182e; font-weight:700;
  text-decoration:none; text-align:center; padding:10px; border-radius:11px}
#card-inner .note{font-size:12px; color:var(--muted); margin:12px 0 0; border-top:1px solid var(--line); padding-top:10px}
#card-inner .close{position:relative; float:right; cursor:pointer; color:var(--muted); font-size:20px; margin:-6px -6px 0 0}

#loading{position:fixed; inset:0; display:grid; place-items:center; text-align:center;
  background:var(--bg); color:var(--muted); z-index:80; transition:opacity .4s}
#loading.gone{opacity:0; pointer-events:none}
#loading small{color:#6c7aa0}

/* Parler a Paul ------------------------------------------------------------ */
/* 🚨 Trois defauts vus a l'ecran le 2026-08-20 (capture de John) :
   - les retours a la ligne de Paul n'etaient pas rendus : sa liste numerotee arrivait
     en un seul pave illisible. C'est `white-space: pre-wrap` qui manquait, pas la mise
     en forme de Paul ;
   - une URL de 120 caracteres ne se coupe nulle part -> barre de defilement HORIZONTALE
     dans un panneau de 320 px ;
   - la boite etait plafonnee a 210 px, donc une reponse de trois sources se lisait par
     une meurtriere. */
#chat{max-height:min(46vh,420px); overflow-y:auto; overflow-x:hidden; margin:0 0 8px;
  font-size:13px; line-height:1.45}
#chat:empty{display:none}
#chat .msg{padding:7px 10px; border-radius:10px; margin:0 0 7px; max-width:100%;
  white-space:pre-wrap; overflow-wrap:anywhere}
#chat .visiteur{background:#33406099; border-bottom-right-radius:3px}
#chat .paul{background:#2f4a44; border-bottom-left-radius:3px}
#chat .qui{display:block; font-size:10px; letter-spacing:.5px; text-transform:uppercase;
  color:var(--muted); margin-bottom:3px}
/* Le corps d'un message est du Markdown RENDU (cf. rendreMarkdown) : ce sont les blocs
   qui portent les retours a la ligne, plus le texte brut. Sans ce `normal`, le pre-wrap
   herite de .msg ajouterait les sauts du source AUX marges des <p> : un message troue. */
#chat .md{white-space:normal}
#chat .md p{margin:0 0 6px}
#chat .md p:last-child{margin-bottom:0}
#chat .md ul,#chat .md ol{margin:4px 0 6px; padding-left:18px}
#chat .md li{margin:0 0 3px}
#chat .md li::marker{color:var(--muted)}
#chat .md strong{color:#eaf2ff; font-weight:600}
#chat .md .md-titre{display:block; margin:7px 0 3px}
#chat .md code{background:#0000004d; padding:1px 4px; border-radius:4px;
  font-family:ui-monospace,Menlo,monospace; font-size:.92em}
#chat a{color:#9fd8c6; overflow-wrap:anywhere}
#chat .attente{color:var(--muted); font-style:italic}
#dire{display:flex; gap:6px}
#dire input{flex:1; min-width:0; padding:8px 10px; border-radius:8px; font:inherit;
  border:1px solid var(--line); background:#1b2335; color:var(--ink)}
#dire input::placeholder{color:#6c7aa0}
#dire button{padding:8px 13px; border-radius:8px; border:0; font:inherit; font-weight:600;
  background:var(--accent); color:#0c1326; cursor:pointer}
#dire button[disabled]{opacity:.5; cursor:default}

/* ── Téléphone ────────────────────────────────────────────────────────────────
   Sous 760px, deux colonnes ne tiennent pas : un panneau de 320px mangeait 82% d'un
   écran de 390px et la ville, qui est TOUT l'argument, se réduisait à une bande de
   70px. On empile : la ville en haut, à hauteur fixe, le panneau en dessous.
   La ville garde une hauteur généreuse - on vient la regarder, pas lire une colonne. */
@media (max-width:760px){
  /* Hauteur FIXE, pas `auto` : `body` est en overflow:hidden (la ville est une scene,
     pas un document). Avec un `main` qui grandit, le panneau depassait sans que rien
     ne puisse defiler - la fenetre de discussion devenait inatteignable. C'est donc
     le PANNEAU qui defile, sous une ville qui reste visible : on doit pouvoir lire
     la reponse sans perdre de vue Paul qui traverse, c'est tout le propos.
     100dvh en second : sur mobile, 100vh ignore la barre d'adresse du navigateur et
     pousse le bas du panneau hors de l'ecran. Les navigateurs qui ignorent dvh
     gardent la premiere ligne. */
  main{flex-direction:column; height:calc(100vh - 48px); height:calc(100dvh - 48px)}
  #stage{flex:none; height:min(46vh,340px)}
  /* touch-action:none - sans ça, glisser sur la ville fait défiler la PAGE au lieu de
     déplacer la vue : le geste principal de la démo ne répondrait pas au doigt. */
  #stage canvas{touch-action:none}
  /* min-height:0 : sans lui, un enfant flex refuse de retrecir sous son contenu et
     `overflow:auto` ne defile jamais. C'est LE piege de flexbox, et c'etait celui-ci. */
  #side{width:auto; flex:1; min-height:0; overflow:auto;
    border-left:0; border-top:1px solid var(--line)}
  #poignee{display:none}
  /* « molette = zoom » ne veut rien dire au doigt, et cette astuce passait sur deux
     lignes en haut de l'écran, au détriment du reste. */
  .hintbar{display:none}
  /* Le bandeau passait quand même sur DEUX lignes dès que l'état était long
     (« miroir branché · en attente ») et la phase aussi (« CRÉPUSCULE ») : autant de
     hauteur perdue sur un écran où la ville en manque. On compacte, et de l'heure du
     jour on ne garde que l'emoji - le mot est décoratif. La pastille d'état, elle,
     RESTE : c'est elle qui dit si on regarde du réel ou une démo, et on ne laisse
     jamais planer le doute là-dessus. `nowrap` en dernier recours : si ça déborde
     encore, la ligne se coupe proprement au lieu de replier le bandeau. */
  #topbar{padding:8px 12px}
  #topbar h1{font-size:16px; white-space:nowrap}
  .tag{font-size:10px; padding:2px 7px; margin-left:6px; white-space:nowrap}
  #phase{display:none}
  /* Le chat garde son propre defilement, borne : sinon une longue reponse repousse le
     champ de saisie tout en bas du panneau, et il faut defiler pour repondre. */
  #chat{max-height:min(38vh,300px)}
}
