/* Une salle d'archives mal eclairee, pas un tableau de bord.
 *
 * Le jeu se joue la nuit, dans un batiment ou quelqu'un est mort. L'interface
 * hors-jeu prepare a cela : fond sombre, ambre pour ce qui compte, rouge sourd
 * pour ce qui accuse. Les couleurs gardent le sens qu'elles avaient dans le
 * terminal (titres, a surveiller, favorable, hostile) — c'est la seule chose
 * de l'ancienne interface qui meritait d'etre transposee telle quelle. */

:root {
	--fond:        #0d0f13;
	--fond-carte:  #14171d;
	--fond-creux:  #1b1f27;
	--trait:       #2a303b;
	--texte:       #dfe3ea;
	--texte-faible:#8a93a3;
	--titre:       #f2cc66;   /* ambre : titres, ce qui structure */
	--intertitre:  #73ccdf;
	--bon:         #66d98a;
	--attention:   #f2b25c;
	--danger:      #ef6f6f;
	--focus:       #f2cc66;
}

* { box-sizing: border-box; }

/* L'attribut `hidden` n'est qu'un `display: none` de la feuille du navigateur :
 * n'importe quelle regle d'auteur qui pose un `display` le neutralise. Le
 * bandeau (`display: flex`) restait donc affiche sur l'ecran de connexion,
 * alors qu'il n'a rien a y faire. */
[hidden] { display: none !important; }

/* La page elle-meme ne defile JAMAIS. C'est l'ecran actif qui defile, dans sa
 * propre boite. Auparavant la hauteur du plein ecran etait calculee en
 * soustrayant une hauteur de bandeau ecrite en dur (49 px) : des que le
 * bandeau faisait un pixel de plus ou de moins, la page depassait, et l'on se
 * retrouvait avec DEUX barres de defilement — celle du fil, et une seconde qui
 * decalait tout de deux millimetres. Une colonne flex n'a pas ce probleme :
 * elle mesure, elle ne devine pas. */
html { height: 100%; }
body {
	margin: 0;
	background: var(--fond);
	color: var(--texte);
	font: 16px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
	height: 100%;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

/* Le fond portait un grain : une couche `position: fixed` plein ecran repetant
 * un degrade radial tous les 3 px. C'est un piege de rendu connu — le
 * navigateur rasterise des centaines de milliers de degrades, et recommence a
 * chaque defilement. Un simple degrade en haut de page donne la meme
 * profondeur pour rien, et ne se recalcule pas. */
body {
	background-image:
		radial-gradient(ellipse 90% 55% at 50% 0%, #171b22 0%, transparent 65%);
	background-repeat: no-repeat;
}

.ecran {
	/* Assez large pour les listes qui portent des boutons — une ligne
	 * d'enquete en aligne cinq, plus les etiquettes — sans laisser les
	 * paragraphes s'etirer au point qu'on perde la ligne suivante en revenant
	 * a la marge. L'ecran de JEU n'est pas concerne : `.ecran.plein` retire
	 * cette limite, la scene prenant toute la fenetre. */
	max-width: 1100px;
	width: 100%;
	margin: 0 auto;
	padding: 1.5rem 1.25rem 1.25rem;
	/* Chaque ecran occupe ce qui reste et defile CHEZ LUI. */
	flex: 1;
	min-height: 0;
	overflow-y: auto;
}

h1 { font-size: 1.6rem; margin: 0 0 .2rem; color: var(--titre); letter-spacing: .02em; }
h2 { font-size: 1.15rem; margin: 1.4rem 0 .5rem; color: var(--intertitre); }
h3 { font-size: .95rem; margin: 0 0 .25rem; }
p  { margin: .28rem 0; }

.discret { color: var(--texte-faible); font-size: .875rem; }
.erreur  { color: var(--danger); min-height: 1.4em; font-size: .9rem; }

/* ---------------------------------------------------------------- */
/* Formulaires                                                      */
/* ---------------------------------------------------------------- */

.carte {
	background: var(--fond-carte);
	border: 1px solid var(--trait);
	border-radius: 10px;
	padding: 1.05rem 1.2rem;
}

label { display: block; margin: .6rem 0 .22rem; font-size: .85rem; color: var(--texte-faible); }

input[type=text], input[type=password], input[type=number], select, textarea {
	width: 100%;
	padding: .6rem .7rem;
	background: var(--fond-creux);
	border: 1px solid var(--trait);
	border-radius: 6px;
	color: var(--texte);
	font: inherit;
}
/* Un signalement se redige : le champ doit pouvoir grandir vers le bas, mais
 * pas sur les cotes — une ligne de 200 caracteres ne se relit pas. */
textarea { resize: vertical; min-height: 6rem; line-height: 1.5; }
input:focus, select:focus, textarea:focus, button:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 1px;
}

button {
	font: inherit;
	padding: .6rem 1.1rem;
	border-radius: 6px;
	border: 1px solid var(--trait);
	background: var(--fond-creux);
	color: var(--texte);
	cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--titre); }
button:disabled { opacity: .45; cursor: default; }

button.principal {
	background: var(--titre);
	border-color: var(--titre);
	color: #17130a;
	font-weight: 600;
}
button.discret-bouton { background: none; border: none; color: var(--texte-faible); padding: .3rem; }
button.discret-bouton:hover { color: var(--titre); }

.actions { display: flex; gap: .6rem; align-items: center; margin-top: .85rem; flex-wrap: wrap; }

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

.liste { display: grid; gap: .45rem; margin: .7rem 0; }

.item {
	width: 100%;
	text-align: left;
	padding: .7rem .9rem;
	background: var(--fond-carte);
	border: 1px solid var(--trait);
	border-radius: 8px;
	display: grid;
	gap: .25rem;
	cursor: pointer;
}
.item:hover { border-color: var(--titre); background: var(--fond-creux); }
.item .ligne { display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; }
.item .nom { font-weight: 600; }

/* Les etiquettes du menu terminal, mot pour mot : dire si la reponse est figee
 * ou tiree n'est pas un detail quand on choisit de rejouer. */
.etiquette {
	font-size: .72rem;
	padding: .1rem .45rem;
	border-radius: 4px;
	border: 1px solid currentColor;
	white-space: nowrap;
}
.etiquette.tirage    { color: var(--attention); }
.etiquette.sauvegarde{ color: var(--bon); }
.etiquette.resolue   { color: var(--bon); }

/* ---------------------------------------------------------------- */
/* Le tri du catalogue par etiquettes                               */
/* ---------------------------------------------------------------- */

/* Les deux commandes, toujours visibles ; leurs panneaux, non. */
.barre-tri { display: flex; gap: .5rem; margin: .9rem 0 .6rem; }

button.regle-liste {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	font-size: .85rem;
	padding: .35rem .8rem;
	background: transparent;
}
/* Ouvert : le bouton se rattache visuellement a son panneau, qui vient
 * juste dessous. */
button.regle-liste.ouvert { border-color: var(--titre); color: var(--titre); }
/* Regle sans etre ouvert : la page ne montre PAS tout le catalogue, et rien
 * d'autre ne le dirait une fois le panneau referme. */
button.regle-liste.regle { color: var(--titre); }
button.regle-liste .badge { background: var(--titre); color: var(--fond); }

.filtres {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .35rem;
	margin: 0 0 1rem;
}
.filtres:empty { display: none; }   /* pas de blanc quand il n'y a rien a trier */

/* Une rangee par nature d'etiquette : les fixes au-dessus, les genres —
 * releves sur le catalogue, donc changeants — en dessous. */
.filtre-rang { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.filtres > .filtre-rang { flex: 1 1 100%; }
.filtre-rang.genres { padding-top: .5rem; border-top: 1px solid var(--trait); }

.filtre {
	display: inline-flex;
	align-items: baseline;
	gap: .35rem;
	font-size: .78rem;
	padding: .2rem .55rem;
	border-radius: 999px;
	border: 1px solid var(--trait);
	background: transparent;
	color: var(--texte-faible);
	cursor: pointer;
}
/* Le survol vient de `button` (bordure --titre) : le redire ici serait une
 * regle de moins de specificite qui ne s'appliquerait jamais. */

/* Chaque famille garde la couleur qu'elle a deja dans la liste : l'etiquette
 * « coupable fixe » du filtre et celle de l'enquete sont la meme chose, et
 * rien ne le dirait si elles n'avaient pas le meme ton. */
.filtre.etiquette-tirage { color: var(--attention); }
.filtre.etiquette-partie { color: var(--bon); }
/* La difficulte est la SEULE famille dont les etiquettes s'ordonnent, et le
 * rouge la fait lire comme une echelle plutot que comme quatre mots au
 * hasard. Elle ne prend pas la couleur du tirage : les deux occupent la meme
 * rangee, et deux familles voisines de meme ton se confondent des qu'on en
 * coche une de chaque — c'est deja arrive avec les genres. */
.filtre.etiquette-diff { color: var(--danger); }
/* Le GROUPE partage la rangee du bas avec les genres, et doit s'en distinguer :
 * « pyrescom » et « cyberpunk » sont deux natures d'etiquette, l'une dit d'ou
 * vient l'enquete, l'autre ce qu'elle raconte. Le vert les separe sans crier —
 * il sert deja aux parties ouvertes, qui ne sont jamais dans cette rangee. */
.filtre.etiquette-groupe { color: var(--bon); }
/* Un genre coche se remplit en clair, et non en --titre : les etiquettes de
 * tirage sont deja de cette couleur, et les deux familles se confondaient des
 * qu'on en cochait une de chaque. */
.filtre.etiquette-genre.actif { color: var(--texte); }

/* Cochee : le fond se remplit. Un simple changement de bordure ne se voyait
 * pas assez sur une rangee de douze. La regle ne touche PAS a `color` — c'est
 * lui qui porte la famille, et le reprendre ici ecraserait les trois regles
 * ci-dessus par simple ordre d'ecriture. */
.filtre.actif {
	background: currentColor;
	border-color: currentColor;
}
.filtre.actif .filtre-nom,
.filtre.actif .filtre-nb { color: var(--fond); }

/* Le compte : combien d'enquetes portent cette etiquette. Il dit d'avance
 * qu'une etiquette ne separe rien, ou qu'elle ne ramenera qu'une chose. */
.filtre-nb { font-size: .7rem; opacity: .65; font-variant-numeric: tabular-nums; }

.filtre-sep {
	width: 1px;
	align-self: stretch;
	margin: .1rem .3rem;
	background: var(--texte-faible);
	opacity: .35;
}

.filtre.raz {
	border-style: dashed;
	color: var(--texte-faible);
	margin-left: .3rem;
}

/* Le panneau de TRI : un choix unique, donc des boutons plus larges qu'une
 * etiquette et sans compte — il n'y a rien a compter, la liste entiere est
 * rangee autrement. */
.filtre.tri { padding: .3rem .8rem; color: var(--texte-faible); }
.filtre.tri.actif { color: var(--titre); }

.compte-enquetes { margin: .6rem 0 0; font-size: .8rem; }

/* ---------------------------------------------------------------- */
/* Briefing                                                         */
/* ---------------------------------------------------------------- */

.dossier { border-left: 2px solid var(--trait); padding-left: 1rem; margin: 1rem 0; }
.dossier .cle { color: var(--texte-faible); }
.victime { color: var(--danger); font-weight: 600; }

.objectifs { list-style: none; padding: 0; margin: .5rem 0; }
.objectifs li { color: var(--attention); padding-left: 1.1rem; position: relative; }
.objectifs li::before { content: '›'; position: absolute; left: 0; }

.gens { display: grid; gap: .7rem; margin-top: .6rem; }
.gens .personne { padding-left: 1rem; border-left: 2px solid var(--trait); }
.gens .metier { color: var(--texte-faible); font-size: .875rem; }
.gens .description { font-size: .9rem; margin-top: .2rem; }
/* Tant que la personne ne s'est pas presentee, sa description reste absente —
 * et on le DIT, plutot que de laisser un blanc qu'on prendrait pour un oubli. */
.gens .inconnue { color: var(--texte-faible); font-style: italic; font-size: .85rem; }

/* ---------------------------------------------------------------- */
/* Barre de lancement                                               */
/* ---------------------------------------------------------------- */

.lancement { margin: 1.5rem 0; }
.lancement .libelle { color: var(--texte-faible); font-size: .9rem; min-height: 1.4em; }
.jauge {
	height: 6px;
	background: var(--fond-creux);
	border-radius: 3px;
	overflow: hidden;
	margin-top: .5rem;
}
.jauge .remplissage {
	height: 100%;
	width: 0;
	background: var(--titre);
	transition: width .4s ease;
}
/* Pendant un appel au modele, l'attente peut durer une minute : une barre
 * immobile passerait pour un plantage. */
.jauge.attente .remplissage {
	background: linear-gradient(90deg, var(--trait) 0%, var(--titre) 50%, var(--trait) 100%);
	background-size: 200% 100%;
	animation: glisse 1.4s linear infinite;
}
@keyframes glisse { from { background-position: 200% 0; } to { background-position: -200% 0; } }

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

.quota { display: grid; gap: .4rem; }
.quota .jauge .remplissage { background: var(--bon); }
.quota .jauge.bas .remplissage { background: var(--attention); }
.quota .jauge.vide .remplissage { background: var(--danger); }

.bandeau {
	/* Colle en haut : le briefing est long, et c'est precisement en le lisant
	 * qu'on veut garder sous les yeux ce qui reste de l'essai — et pouvoir
	 * atteindre les reglages pour y ajouter sa cle. */
	flex: none;
	z-index: 10;
	display: flex; justify-content: space-between; align-items: center;
	gap: 1rem; padding: .7rem 1.25rem;
	border-bottom: 1px solid var(--trait);
	background: var(--fond-carte);
	font-size: .875rem;
	flex-wrap: wrap;
}
/* Les deux moities du bandeau alignent leur contenu au centre. Elles etaient
 * en ligne : un bouton parmi du texte se posait sur la ligne de base, donc
 * legerement trop bas. */
.bandeau > span { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.bandeau .qui { color: var(--titre); font-weight: 600; }

/* « Accueil » n'est pas un lien de service comme les autres : c'est la sortie,
 * celle qu'on cherche quand on ne sait plus ou l'on est. En bouton discret il
 * se confondait avec le nom du compte juste a cote. Il garde donc un contour
 * et la couleur d'accent — sans etre plein, ce qui en ferait l'action
 * principale de chaque page. */
.bandeau #aller-accueil {
	flex: none;
	padding: .3rem .8rem;
	font-size: .85rem;
	font-weight: 600;
	color: var(--titre);
	border-color: color-mix(in srgb, var(--titre) 45%, transparent);
	background: color-mix(in srgb, var(--titre) 10%, transparent);
}
.bandeau #aller-accueil:hover {
	border-color: var(--titre);
	background: color-mix(in srgb, var(--titre) 20%, transparent);
}
/* Un peu d'air avant le nom du compte, sinon les deux se touchent. */
.bandeau #aller-accueil + .qui { margin-left: .4rem; }

@media (max-width: 560px) {
	.ecran { padding: 1.5rem 1rem 3rem; }
	.bandeau { padding: .6rem 1rem; }
}

/* ---------------------------------------------------------------- */
/* La partie                                                        */
/* ---------------------------------------------------------------- */

/* Une partie ouverte n'est jamais DEMONTEE quand on va ailleurs : elle passe
 * en coulisse. La cacher en display:none reduisait le canvas a 0x0 ; WebGL y
 * perdait son contenu, et l'on revenait sur un ecran noir alors que la scene
 * se portait bien — boucle en marche, camera a la bonne taille, tout en ordre
 * sauf l'image. Mesure : 0 couleur, 0x0 pixels au retour.
 *
 * En coulisse, elle garde exactement sa place et sa taille, mais ne se voit
 * pas et n'attrape rien. */
.en-coulisse {
	position: fixed !important;
	inset: 0;
	visibility: hidden;
	pointer-events: none;
	z-index: -1;
}

.ecran.plein {
	max-width: none;
	padding: 0;
	position: relative;
	overflow: hidden;
}

/* Deux tiers / un tiers : la scene dit ou l'on est, le fil dit ce qui a ete
 * dit. Les bulles sont ephemeres par choix (D5) ; sans un fil visible en
 * permanence, ce choix obligeait a ouvrir le carnet pour relire une phrase
 * prononcee dix secondes plus tot. */
.plateau {
	display: grid;
	grid-template-columns: 2fr 1fr;
	/* Entetes, boites, barre de saisie. La rangee du milieu est BORNEE a la
	 * hauteur disponible : en « auto », elle grandit avec son contenu, le canvas
	 * mesure son parent, le parent grandit du canvas, et la scene gonfle a
	 * chaque retour dans la partie. */
	grid-template-rows: auto minmax(0, 1fr) auto;
	height: 100%;
}
.hud-haut { grid-column: 1; grid-row: 1; }
#scene    { grid-column: 1; grid-row: 2; min-height: 0; position: relative; overflow: hidden; }
/* Les discussions occupent les deux memes rangees que la carte : c'est la
 * grille qui garantit l'egalite des hauteurs, et non un calcul a la main. */
.cote-fil { grid-column: 2; grid-row: 1 / 3; }
/* La barre de saisie tient toute la largeur, sous les deux boites : elle
 * flottait auparavant par-dessus la scene et masquait le bas de la carte. */
.hud      { grid-column: 1 / 3; grid-row: 3; }
/* Hors du flux : le canvas prend la taille que la scene lui donne, et ne
 * participe jamais au calcul de la hauteur de son parent. */
#scene canvas { display: block; position: absolute; top: 0; left: 0; }

.cote-fil {
	border-left: 1px solid var(--trait);
	min-height: 0;
	background: var(--fond-carte);
	display: flex;
	flex-direction: column;
	min-width: 0;
}
.fil-tete {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .6rem;
	padding: .7rem 1rem;
	border-bottom: 1px solid var(--trait);
	font-size: .9rem;
}
/* La case Debug, reservee a l'hote. Discrete : elle partage la ligne du titre
 * et ne doit pas la disputer — c'est un outil de reglage, pas une fonction du
 * jeu. */
.fil-debug {
	display: flex;
	align-items: center;
	gap: .3rem;
	margin: 0;
	font-size: .8rem;
	color: var(--texte-faible);
	cursor: pointer;
	white-space: nowrap;
}
.fil-debug input { width: auto; margin: 0; accent-color: var(--titre); }

/* Les lignes de debug : les chiffres bruts des quatre axes. Elles se lisent en
 * colonne de chiffres, d'ou la police a chasse fixe — « +4 -> -12 » aligne sous
 * « -8 -> -20 » se compare d'un coup d'oeil, ce qu'une police proportionnelle
 * interdit. */
.dit.debug {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .76rem;
	color: var(--attention);
	opacity: .85;
	white-space: pre-wrap;
	margin: .15rem 0;
}
#j-fil { flex: 1; overflow-y: auto; padding: .8rem 1rem 1.2rem; font-size: .9rem; }

/* Le texte par-dessus la scene, jamais dedans (D4). */
/* La barre du dessus : la piece ou l'on se trouve, comme un cartouche de
 * plan. Elle etait en bas, melee a l'interlocuteur et aux boutons, et c'est
 * l'information qu'on cherche le plus souvent. */
.hud-haut {
	flex: none;
	padding: .5rem 1rem;
	background: var(--fond-carte);
	border-bottom: 1px solid var(--trait);
	color: var(--titre);
	font-size: .95rem;
	letter-spacing: .03em;
	min-height: 2.1rem;
}

.hud {
	flex: none;
	padding: .7rem 1rem .8rem;
	background: var(--fond-carte);
	border-top: 1px solid var(--trait);
}
.hud-ligne { display: flex; justify-content: space-between; gap: 1rem; margin-bottom: .4rem; }

/* « Il est parti verifier ». Une ligne a part, et non un ajout a `#j-cible` :
 * celle-la dit a qui l'on parle MAINTENANT, celle-ci annonce quelque chose qui
 * arrivera — les melanger ferait lire l'une pour l'autre. Le liseré la
 * distingue d'une note ordinaire sans en faire une alerte : rien ne va mal,
 * quelqu'un travaille. */
.attente-pnj {
	margin: 0 0 .4rem;
	padding: .15rem 0 .15rem .6rem;
	border-left: 2px solid var(--titre);
	color: var(--texte-faible);
	font-size: .875rem;
}

.hud-saisie { display: flex; gap: .6rem; }
.hud-saisie input { flex: 1; }

/* ---------------------------------------------------------------- */
/* Le carnet : plein ecran, onglets sur la tranche                   */
/* ---------------------------------------------------------------- */

.carnet {
	position: fixed;
	inset: 0;
	z-index: 50;
	display: flex;
	/* Le carnet ET ses onglets sont centres ENSEMBLE. La page se centrait
	 * auparavant toute seule (margin: 0 auto), ce qui la decollait de ses
	 * onglets : deux objets flottants au lieu d'un carnet. */
	justify-content: center;
	background: rgba(6, 7, 10, .82);
	padding: 2.5rem 1.5rem;
}

/* Un papier, pas une fenetre : le carnet est un objet du jeu. */
.carnet-page {
	flex: 1 1 900px;
	max-width: 900px;
	background: #16151230;
	background-color: #1a1815;
	border: 1px solid #3a352c;
	border-radius: 4px 10px 10px 4px;
	box-shadow: 0 20px 60px rgba(0,0,0,.6), inset 22px 0 24px -22px rgba(0,0,0,.8);
	display: flex;
	flex-direction: column;
	position: relative;
	overflow: hidden;
}
/* La reliure. */
.carnet-page::before {
	content: '';
	position: absolute;
	left: 0; top: 0; bottom: 0;
	width: 26px;
	background: repeating-linear-gradient(
		to bottom, transparent 0 26px, #2a2620 26px 28px);
	border-right: 1px solid #322d26;
}

.carnet-tete {
	display: flex; justify-content: space-between; align-items: center;
	padding: 1rem 1.5rem 1rem 3.2rem;
	border-bottom: 1px solid #322d26;
	color: var(--titre);
}
#j-panneau-corps {
	flex: 1;
	overflow-y: auto;
	padding: 1.2rem 1.5rem 1.2rem 3.2rem;
	color: #e8e2d4;
	line-height: 1.65;
}
.carnet-pied {
	display: flex; justify-content: space-between; align-items: center;
	padding: .6rem 1.5rem .6rem 3.2rem;
	border-top: 1px solid #322d26;
	font-size: .85rem;
}
.carnet-pied button[hidden] { visibility: hidden; display: inline-block; }

/* Les onglets depassent sur la tranche, comme des intercalaires : colles a la
 * page, et glisses d'un pixel dessous pour que la bordure soit commune. */
.carnet-onglets {
	display: flex;
	flex-direction: column;
	gap: .4rem;
	padding-top: 2rem;
	margin-left: -1px;
	flex: none;
}
.carnet-onglets .onglet {
	writing-mode: vertical-rl;
	padding: 1rem .55rem;
	background: #1a1815;
	border: 1px solid #3a352c;
	border-left: none;
	border-radius: 0 8px 8px 0;
	color: var(--texte-faible);
	cursor: pointer;
	font-size: .85rem;
	letter-spacing: .04em;
}
.carnet-onglets .onglet:hover { color: var(--texte); }
.carnet-onglets .onglet.actif {
	background: #242019;
	color: var(--titre);
	border-color: var(--titre);
}

#j-panneau-corps h4 { margin: 1.3rem 0 .4rem; color: var(--intertitre); font-size: .95rem; }
#j-panneau-corps h4:first-child { margin-top: 0; }
#j-panneau-corps .fait { padding-left: 1.1rem; position: relative; margin: .2rem 0; }
#j-panneau-corps .fait::before { content: '·'; position: absolute; left: .3rem; }
#j-panneau-corps .fait.aveu { color: var(--danger); }
#j-panneau-corps .fait.aveu::before { content: '!'; }
#j-panneau-corps .personne { margin: .6rem 0; }

/* La premisse ouvre le dossier : c'est le seul paragraphe qu'on lit vraiment
 * d'un trait, il a droit a un peu d'air. */
#j-panneau-corps .premisse { margin: 0 0 1.1rem; }

/* La fiche : intitules a gauche, valeurs a droite, sur une grille.
 *
 * L'information se cherchait auparavant au milieu de phrases ponctuees
 * (« Fait : homicide dans Laboratoire central, entre 21h40 et 21h55 »). Alignee,
 * elle se parcourt : on descend la colonne des intitules jusqu'a celui qu'on
 * veut. Les lignes inconnues ne sont pas rendues du tout (voir fiche()). */
#j-panneau-corps .fiche {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: .18rem .9rem;
	margin: 0 0 1rem;
	font-size: .92rem;
}
#j-panneau-corps .fiche dt { color: var(--texte-faible); }
#j-panneau-corps .fiche dd { margin: 0; }

/* Le nombre annonce par un intertitre : « Ce que vous avez etabli » ne disait
 * pas combien, et l'on ouvrait la page pour compter. */
#j-panneau-corps .compteur {
	display: inline-block;
	min-width: 1.15rem;
	padding: 0 .3rem;
	margin-left: .3rem;
	border-radius: 999px;
	background: #241f19;
	border: 1px solid #3a352c;
	color: var(--texte-faible);
	font-size: .72rem;
	font-weight: 600;
	text-align: center;
	vertical-align: .1rem;
}

/* Les quatre axes de la relation, en jauges divergentes.
 *
 * Ils tenaient sur une seule ligne separee par des points medians : on lisait
 * « confiance faible affection moyenne peur nulle » d'un bloc, sans voir ou
 * finissait un axe. Et le mot seul ne disait pas de combien on s'etait
 * eloigne — cinq mots ne peuvent pas rendre une echelle de deux cents crans.
 *
 * Chaque jauge part du CENTRE : zero n'est pas « rien », c'est l'indifference,
 * et l'on s'en ecarte dans les deux sens. Une barre remplie depuis la gauche
 * ferait passer « hostile » pour « presque rien ». */
/* Une GRILLE, et non quatre boites qui se partagent la place.
 *
 * En flex, chaque libelle imposait sa largeur : « peur » est deux fois plus
 * court que « confiance », donc les quatre rails commencaient et finissaient a
 * des abscisses differentes, et la ligne partait en dents de scie. Quatre
 * colonnes egales, et dans chacune un gabarit fixe pour le libelle : les
 * barres sont alignees entre elles et ont toutes la meme longueur, ce qui est
 * la condition pour les comparer d'un coup d'oeil. */
#j-panneau-corps .attitude {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	align-items: center;
	gap: .35rem 1.1rem;
	margin-top: .5rem;
	font-size: .8rem;
}
#j-panneau-corps .attitude .axe {
	display: grid;
	grid-template-columns: 4.4rem 1fr;
	align-items: center;
	gap: .4rem;
	min-width: 0;
}
#j-panneau-corps .attitude .axe-nom {
	color: var(--texte-faible);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Sous cette largeur, quatre colonnes ecraseraient les barres jusqu'a
 * l'illisible : on passe a deux. */
@media (max-width: 760px) {
	#j-panneau-corps .attitude { grid-template-columns: repeat(2, 1fr); }
}

#j-panneau-corps .attitude .axe-rail {
	position: relative;
	display: block;
	height: .45rem;
	background: #201c17;
	border: 1px solid #322d26;
	/* Meme rayon que la jauge qui le remplit : deux rayons differents laissaient
	 * un lisere de fond visible aux extremites d'une barre pleine. */
	border-radius: 2px;
}
/* `axe-rail`, `axe-zero`, `axe-barre` et non `rail`, `zero`, `jauge` : cette
 * feuille a un espace de noms PLAT, et `.jauge` y designe deja la barre de
 * progression du lancement. Sa `margin-top` poussait la barre d'attitude juste
 * SOUS son rail — un defaut invisible a la lecture des deux regles, qui ne se
 * croisent nulle part dans le fichier. Tout ce qui appartient a un axe porte
 * donc son prefixe, comme `axe-nom`.
 *
 * Le repere du milieu, visible meme quand la jauge est a zero : c'est lui qui
 * dit d'ou l'on part. */
#j-panneau-corps .attitude .axe-zero {
	position: absolute; top: -1px; bottom: -1px; left: 50%;
	width: 1px; background: #4a4238;
}
#j-panneau-corps .attitude .axe-barre {
	position: absolute; top: 0; bottom: 0;
	border-radius: 2px;
	min-width: 0;
}
/* Le COTE vient du signe, la COULEUR de ce que la valeur vaut pour l'enqueteur.
 * Les deux sont separes parce qu'ils ne coincident pas : une confiance qui monte
 * lui profite, une suspicion qui monte lui nuit, et les deux vont pourtant vers
 * la droite. Le mot et le chiffre restent dans l'infobulle : la couleur seule ne
 * dit rien a qui la distingue mal. */
#j-panneau-corps .attitude .gauche  .axe-barre { right: 50%; }
#j-panneau-corps .attitude .droite  .axe-barre { left: 50%; }
#j-panneau-corps .attitude .bon     .axe-barre { background: var(--bon); }
#j-panneau-corps .attitude .mauvais .axe-barre { background: var(--danger); }

/* Le sommaire des personnes : un jeton par nom, dans SA couleur — celle de
 * la scene et du fil — pour sauter directement a quelqu'un au lieu de
 * feuilleter une a une une enquete qui peut en compter vingt. */
.sommaire-gens {
	display: flex; flex-wrap: wrap; gap: .4rem;
	margin-bottom: 1.1rem; padding-bottom: 1rem;
	border-bottom: 1px solid #322d26;
}
.jeton-personne {
	background: #1a1815; border: 1px solid color-mix(in srgb, var(--c) 55%, #3a352c);
	color: var(--c); border-radius: 999px;
	padding: .3rem .8rem; font-size: .82rem; cursor: pointer;
}
.jeton-personne:hover { border-color: var(--c); }
.jeton-personne.actif { background: color-mix(in srgb, var(--c) 22%, #1a1815); border-color: var(--c); }
/* Personne a qui l'on n'a pas encore parle : grise, et en trait interrompu.
 *
 * Les deux, parce que la couleur ne suffit pas — c'est elle qui IDENTIFIE la
 * personne partout ailleurs (scene, fil, titre de page), et la retirer prive
 * d'un repere au moment ou l'on cherche justement quelqu'un. Le pointille dit
 * « pas encore » sans rien coûter a la lecture, et il reste visible pour qui
 * distingue mal les couleurs. La couleur revient au premier mot echange. */
.jeton-personne.jamais-vu {
	color: var(--texte-faible);
	border-style: dashed;
	border-color: color-mix(in srgb, var(--texte-faible) 45%, transparent);
	opacity: .75;
}
.jeton-personne.jamais-vu:hover { color: var(--c); border-color: var(--c); opacity: 1; }
/* Coche, elle reprend sa couleur : c'est la page qu'on lit, et la griser
 * reviendrait a effacer le titre qu'on vient d'ouvrir. */
.jeton-personne.jamais-vu.actif { color: var(--c); opacity: 1; }

/* La deduction : le detective pense a voix haute.
 *
 * Une note epinglee dans le dossier, et non un paragraphe de plus : elle ne
 * vient pas de l'enquete mais de quelqu'un qui la relit, et cette difference-la
 * doit se voir avant d'etre lue. D'ou le cartouche, le filet de la couleur des
 * titres, et l'intertitre qui dit qui parle.
 *
 * Tout est en variables de theme : les couleurs en dur tenaient sur le theme
 * sombre et devenaient illisibles sur les autres. */
.deduction-bloc {
	margin-top: 1.2rem;
	padding: .85rem 1rem .95rem;
	background: #201c17;
	border: 1px solid #322d26;
	border-left: 3px solid var(--titre);
	border-radius: 5px;
}
.deduction-qui {
	color: var(--titre);
	font-size: .74rem;
	letter-spacing: .09em;
	text-transform: uppercase;
	margin-bottom: .55rem;
}
/* `pre-wrap` parce que le modele separe ses paragraphes par des sauts de ligne
 * et qu'on les lui a demandes : les ecraser rendrait un pave. Le texte est pose
 * par textContent, donc rien n'y est interprete — c'est aussi ce qui le met a
 * l'abri de ce que le modele pourrait ecrire. */
.deduction-bloc .deduction {
	white-space: pre-wrap;
	margin: 0;
	line-height: 1.7;
	font-style: italic;
	color: var(--texte);
}
.deduction-bloc .deduction:empty { display: none; }
.deduction-bloc .erreur { margin: .6rem 0 0; }

.deduction-attente {
	display: flex; align-items: center; gap: .5rem;
	margin: .7rem 0 0;
	color: var(--texte-faible);
	font-size: .88rem;
}
/* Trois points qui respirent. L'attente dure plusieurs secondes — le temps d'un
 * appel au modele — et un ecran fige pendant ce temps-la se lit comme une
 * panne : on reclique, et la seconde demande est refusee. */
.pense { display: inline-flex; gap: .3rem; }
.pense i {
	width: .4rem; height: .4rem; border-radius: 50%;
	background: var(--titre);
	animation: pense 1.25s ease-in-out infinite;
}
.pense i:nth-child(2) { animation-delay: .16s; }
.pense i:nth-child(3) { animation-delay: .32s; }
@keyframes pense {
	0%, 65%, 100% { opacity: .25; transform: translateY(0); }
	32%           { opacity: 1;   transform: translateY(-3px); }
}
/* Une animation qui pulse sans fin est exactement ce que ce reglage systeme
 * demande d'eviter. Les points restent, et disent la meme chose. */
@media (prefers-reduced-motion: reduce) {
	.pense i { animation: none; opacity: .55; }
}

/* La chronologie du carnet : une colonne de moments, le long d'un fil.
 *
 * Verticale et non horizontale : le panneau est etroit et haut, et une frise
 * couchee aurait entasse cinq mots par moment ou defile de cote — alors que ce
 * qu'on vient y lire, ce sont les faits, en entier. Le fil est un trait continu
 * derriere les pastilles, et non un trait par moment : c'est lui qui dit que
 * les moments se suivent.
 *
 * `--pastille` sert deux fois — le rayon du point et le retrait du texte — pour
 * que le fil tombe au centre des pastilles quelle que soit sa valeur. */
.chrono {
	--pastille: .55rem;
	list-style: none;
	margin: .2rem 0 0;
	padding: 0 0 0 calc(var(--pastille) * 2);
	position: relative;
}

/* Le fil. Il s'arrete au DERNIER moment plutot que de courir jusqu'en bas :
 * une chronologie qui se prolonge dans le vide promet une suite qu'on n'a pas.
 * D'ou le trait porte par la liste et borne par son dernier element. */
.chrono::before {
	content: '';
	position: absolute;
	left: calc(var(--pastille) - 1px);
	top: .6rem;
	bottom: .6rem;
	width: 2px;
	background: var(--trait);
}

.chrono-moment {
	position: relative;
	padding: 0 0 .9rem .9rem;
}

.chrono-moment::before {
	content: '';
	position: absolute;
	left: calc(var(--pastille) * -1);
	top: .45rem;
	width: calc(var(--pastille) * 2 - 2px);
	height: calc(var(--pastille) * 2 - 2px);
	border-radius: 50%;
	background: var(--fond);
	border: 2px solid var(--trait);
}

/* Les moments qui tombent DANS la fenetre du crime. C'est la seule chose qu'on
 * cherche en ouvrant cette page : ils portent donc la couleur d'alerte, et une
 * pastille pleine — le contour seul ne se distingue pas assez du reste. */
.chrono-moment.pendant::before {
	background: var(--danger);
	border-color: var(--danger);
}

.chrono-heure {
	display: block;
	font-variant-numeric: tabular-nums;
	color: var(--titre);
	font-size: .95rem;
	letter-spacing: .04em;
}

.chrono-moment.pendant .chrono-heure { color: var(--danger); }

.chrono-faits { margin-top: .15rem; }

.chrono-fenetre {
	margin: 0 0 .8rem;
	padding: .2rem 0 .2rem .6rem;
	border-left: 2px solid var(--danger);
	color: var(--texte-faible);
	font-size: .875rem;
}

/* Le plan du carnet : les pieces parcourues, dessinees case par case.
 *
 * Un dessin de carnet, pas une minicarte de jeu : encre sur papier, sans
 * relief. Ce qu'on n'a pas vu n'est pas grise, il est simplement ABSENT — un
 * vide dit « je ne sais pas » la ou un gris dit « il y a quelque chose ». */
.plan {
	display: block; width: 100%; max-height: 46vh;
	margin: 0 0 .4rem; overflow: visible;
}
.plan .plan-sol { fill: #2b2620; }
.plan .plan-mur { fill: var(--titre); opacity: .5; }
/* Le joueur reprend le blanc franc qui le designe partout ailleurs. */
.plan .plan-moi { fill: var(--joueur, #ffffff); }
.plan .plan-nom {
	fill: var(--titre); font-size: 7px; font-weight: 600;
	text-anchor: middle; dominant-baseline: middle;
	/* Le contour reprend le fond du panneau : le nom reste lisible quel que
	 * soit ce qu'il recouvre, et sur n'importe quel theme. */
	paint-order: stroke; stroke: #1a1815; stroke-width: 2.5px;
	stroke-linejoin: round;
}

/* Qui se trouve ou : le nom de la piece, puis les gens, sur la meme ligne. */
.plan-piece {
	display: flex; justify-content: space-between; gap: 1rem;
	padding: .25rem 0; border-bottom: 1px solid #322d26;
}
.plan-piece .nom { color: var(--titre); }
.plan-piece .qui { text-align: right; }

/* Ce qui se dit — dans le fil de droite comme dans le carnet. */
.dit { margin: .5rem 0; }
.dit .qui { color: var(--titre); font-weight: 600; }
/* Le joueur en blanc franc : c'est lui, il ne se confond avec personne. La
 * valeur passe par une variable, sinon un theme CLAIR ecrirait son nom en blanc
 * sur du creme — et son portrait, qui reprend `currentColor`, disparaitrait
 * avec. */
.dit.player .qui { color: var(--joueur, #ffffff); }
.dit.action { color: var(--texte-faible); font-style: italic; padding-left: .8rem; }
.dit.systeme { color: var(--texte-faible); font-size: .85rem; }
.dit.note { color: var(--bon); font-size: .85rem; }

@media (max-width: 900px) {
	.plateau { grid-template-columns: 1fr; grid-template-rows: 2fr 1fr; }
	.cote-fil { border-left: none; border-top: 1px solid var(--trait); }
}

/* ------------------------------------------------------------------ */
/* L'etat du serveur, et son journal                                   */
/* ------------------------------------------------------------------ */

/* Deux colonnes, le nom a gauche : on parcourt la colonne des noms jusqu'a
 * celui qu'on cherche, et l'on lit en face. Une liste de phrases obligerait a
 * tout lire pour trouver une ligne. */
.etat-grille {
	display: grid;
	grid-template-columns: 12rem 1fr;
	gap: .35rem .9rem;
	align-items: baseline;
}

.etat-nom { color: var(--texte-faible); font-size: .9rem; }
.etat-valeur { font-variant-numeric: tabular-nums; }

.titre-carte { margin: 0 0 .8rem; font-size: 1rem; color: var(--titre); }

.journal-barre {
	display: flex;
	flex-wrap: wrap;
	gap: .8rem;
	align-items: center;
	margin-bottom: .8rem;
}

.journal-auto {
	display: flex;
	gap: .4rem;
	align-items: center;
	color: var(--texte-faible);
	font-size: .9rem;
}
.journal-auto input[type=checkbox] { width: auto; accent-color: var(--titre); }
.journal-auto select { width: auto; padding: .35rem .5rem; font-size: .85rem; }

/* Le journal lui-meme : une fenetre haute et defilante, en chasse fixe. Les
 * lignes ne sont PAS repliees — une trace de serveur est une suite de champs
 * alignes, et les replier melange tout. On defile horizontalement. */
.journal {
	max-height: 60vh;
	overflow: auto;
	margin: 0;
	padding: .7rem .9rem;
	background: var(--fond-creux);
	border: 1px solid var(--trait);
	border-radius: 6px;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .78rem;
	line-height: 1.5;
	color: var(--texte);
	white-space: pre;
	tab-size: 4;
}

/* Une ligne par element : c'est ce qui permet au niveau de la colorer. Les
 * deux seules couleurs sont celles qui appellent l'oeil — le reste d'un journal
 * est du bruit qu'on parcourt, et tout colorer revient a ne rien signaler. */
.jr-ligne { white-space: pre; }
.jr-attention { color: var(--attention); }
.jr-erreur { color: var(--danger); }

/* ------------------------------------------------------------------ */
/* Les reglages du serveur (administrateur)                            */
/* ------------------------------------------------------------------ */

.srv-grille {
	display: grid;
	grid-template-columns: 14rem 1fr;
	gap: .3rem .9rem;
	align-items: center;
	margin: .8rem 0;
}

.srv-grille label { color: var(--texte-faible); font-size: .9rem; }

/* Ce que l'environnement fixe est montre, mais pas modifiable : accepter une
 * saisie qui ne changerait rien est pire que la refuser. */
.srv-grille input[disabled] { opacity: .5; }
/* Un port ou un plafond n'a pas besoin de toute la largeur, et un champ long
 * pour trois chiffres laisse croire qu'on en attend davantage. */
.srv-grille input[type=number] { width: 10rem; }
.srv-grille input[type=checkbox] { width: auto; accent-color: var(--titre); }
.srv-grille .fixe { font-size: .8rem; color: var(--texte-faible); }

/* Le modele et son effort de raisonnement partagent une ligne : l'effort est
 * un reglage de CE modele, pas un voisin. Le nom prend la place, la liste
 * juste ce qu'il lui faut. */
.srv-grille .avec-effort { display: flex; gap: .5rem; align-items: center; }
.srv-grille .avec-effort input { flex: 1; min-width: 0; }
/* Le curseur de volume, dans la barre du jeu : assez court pour ne pas pousser
 * les boutons hors de la ligne, assez long pour se regler d'un geste. */
.actions input.volume { width: 6rem; flex: none; vertical-align: middle; }

.srv-grille select.effort {
	flex: none;
	width: auto;
	padding: .6rem .5rem;
	font-size: .8rem;
	letter-spacing: .06em;
	color: var(--texte-faible);
}
.srv-details { margin-top: .6rem; }
.srv-details div { padding: .5rem 0 0 .8rem; line-height: 1.5; }

/* ------------------------------------------------------------------ */
/* Les barres de defilement                                            */
/* ------------------------------------------------------------------ */

/* Discretes et de la couleur du reste : la barre par defaut de Chrome est
 * claire et large, et c'etait la chose la plus lumineuse d'un ecran sombre. */
* { scrollbar-width: thin; scrollbar-color: var(--trait) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
	background: var(--trait);
	border-radius: 6px;
	border: 3px solid transparent;
	background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: #3c4453; background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ------------------------------------------------------------------ */
/* La barre d'actions du bas                                           */
/* ------------------------------------------------------------------ */

/* Collee en bas de l'ecran qui defile. « Retour » et « Entrer » sont les
 * boutons qu'on cherche, et les reglages sont assez longs pour qu'aller les
 * chercher demande de derouler toute la page. */
/* La barre du bas : un PANNEAU, pas un degrade.
 *
 * Elle n'etait qu'un fondu vers la couleur du fond. Les boutons paraissaient
 * flotter dans le vide, et selon ce qui defilait derriere on ne voyait plus ou
 * commencait la barre. Un fond translucide avec son trait du haut dit ou elle
 * commence, et le flou derriere garde l'impression qu'il reste du contenu
 * dessous — ce qui est vrai.
 *
 * Elle porte parfois plus que des boutons : sur l'ecran de preparation, la
 * jauge et le temps ecoule sont dedans. `.actions` reste la rangee de boutons,
 * `.barre-bas` le panneau qui la tient. */
.barre-bas {
	position: sticky;
	bottom: 0;
	margin-top: 1rem;
	padding: .7rem .9rem;
	border: 1px solid var(--trait);
	border-radius: 10px;
	background: color-mix(in srgb, var(--fond-carte) 88%, transparent);
	/* Le flou n'est pas partout ; sans lui le fond translucide suffit, il est
	 * seulement moins joli. */
	backdrop-filter: blur(6px);
}
/* La rangee de boutons ne reprend pas la marge du haut quand elle EST le
 * panneau : le padding s'en charge. */
.barre-bas.actions { margin-top: 1rem; }
.barre-bas > .actions:first-child { margin-top: 0; }
/* Dans la barre, la preparation se serre : elle partage la place avec les
 * boutons, et 1,5 rem de marge la poussait hors de l'ecran. */
.barre-bas .lancement { margin: 0 0 .5rem; }
.barre-bas .erreur { min-height: 0; }
.barre-bas .erreur:empty { display: none; }

/* ------------------------------------------------------------------ */
/* Ce que la partie a consomme                                         */
/* ------------------------------------------------------------------ */

/* La barre du terminal, mot pour mot : « API 30 appels · entree 67.4k ·
 * sortie 13.8k · cache 62% · ~0.028 $ ». Les libelles s'effacent, les
 * nombres se lisent, le prix ressort. Une seule ligne « 92 919 jetons » ne
 * disait ni la part d'entree, ni celle du cache — c'est-a-dire rien de ce
 * qu'on regarde quand on se demande pourquoi une partie coute cher. */
.compteur { margin-left: .5rem; }
.compteur .etiq { color: var(--texte-faible); }
.compteur .val  { color: var(--texte); }
.compteur .cache { color: var(--bon); }
.compteur .cout { color: var(--attention); }

/* ------------------------------------------------------------------ */
/* Le resume d'une enquete                                             */
/* ------------------------------------------------------------------ */

/* Quatre lignes, puis des points de suspension. Une premisse de dix lignes
 * repoussait les enquetes suivantes hors de l'ecran, et l'on choisissait sans
 * voir ce qu'on avait le choix de prendre. La ligne du dessous — genre, lieu,
 * annee — reste entiere : c'est elle qui distingue deux enquetes au coup
 * d'oeil. */
#liste-enquetes .resume {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* ------------------------------------------------------------------ */
/* Les enquetes, vues par l'hote                                       */
/* ------------------------------------------------------------------ */

.adm-liste { margin: .8rem 0; }
.adm-ligne {
	display: flex;
	align-items: center;
	gap: .6rem;
	padding: .38rem .2rem;
	border-bottom: 1px solid var(--trait);
}
.adm-ligne:last-child { border-bottom: none; }
/* Une enquete fermee reste lisible, mais on voit au premier coup d'oeil
 * qu'elle ne compte pas : la griser sans autre signe la ferait passer pour un
 * defaut d'affichage. */
.adm-ligne.fermee .adm-titre { color: var(--texte-faible); text-decoration: line-through; }
.adm-titre { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adm-rang { width: 1.6rem; color: var(--texte-faible); font-size: .85rem; text-align: right; }
.adm-ligne button { padding: .2rem .55rem; font-size: .9rem; }
.adm-ligne input[type=checkbox] { width: auto; accent-color: var(--titre); }

/* Genre, lieu, annee, nombre de personnes : la ligne qui SITUE l'enquete. Elle
 * portait la meme grisaille que le resume juste au-dessus, si bien que les
 * deux se lisaient comme un seul bloc de texte — alors que celle-ci se
 * parcourt d'un coup d'oeil pour comparer deux enquetes. Le bleu des
 * intertitres l'en detache sans crier. */
#liste-enquetes .meta {
	color: var(--intertitre);
	font-size: .85rem;
	letter-spacing: .01em;
}

/* Une enquete que l'on ne peut pas ouvrir : le catalogue reste lisible — on
 * veut voir ce qui existe — mais rien d'autre ne se lance tant qu'une
 * generation est en cours. Celle qui genere, elle, reste cliquable et ramene
 * a son ecran de preparation. */
.item.indisponible { opacity: .45; cursor: not-allowed; }
.item.indisponible:hover { border-color: var(--trait); background: var(--fond-carte); }
.item.en-cours { border-color: var(--titre); }
.item .etiquette.generation { border-color: var(--titre); color: var(--titre); }

/* ---------------------------------------------------------------- */
/* Accueil                                                          */
/* ---------------------------------------------------------------- */

/* Deux boutons et une phrase : c'est tout ce qu'on doit lire en arrivant.
 * La liste des enquetes tenait ce role et disait trop peu — notamment qu'une
 * preparation etait en cours. */
/* ------------------------------------------------------------------ */
/* L'accueil                                                           */
/* ------------------------------------------------------------------ */

/* Deux colonnes : ce qu'on vient faire, et a quoi ca ressemble. En dessous de
 * 900 px il n'y a plus la place de les mettre cote a cote — le decor passe
 * alors sous le texte, et non l'inverse : c'est le titre qu'on doit lire en
 * premier sur un telephone. */
.hero {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 2.5rem;
	align-items: center;
	margin: 1rem 0 1.5rem;
}

.hero-titre {
	/* Grand, mais borne : sur un ecran large, un titre qui suit betement la
	 * largeur finit par occuper la moitie de la page. */
	font-size: clamp(2.8rem, 7vw, 4.5rem);
	line-height: 1.05;
	letter-spacing: .02em;
	margin: 0 0 .6rem;
}

.hero-accroche {
	font-size: clamp(1.05rem, 2.2vw, 1.35rem);
	color: var(--texte);
	margin: 0 0 .5rem;
	/* `min(...)` et non `34ch` seul : sur un telephone, 34 caracteres sont plus
	 * larges que l'ecran, et la phrase sortait par la droite. */
	max-width: min(34ch, 100%);
}

.hero-sous {
	color: var(--texte-faible);
	margin: 0 0 1.4rem;
	max-width: min(44ch, 100%);
}

.hero-actions { margin-bottom: .8rem; }
.hero-etat { margin: 0; }

/* Le cadre du decor. Sa taille vient du decor lui-meme (--dio-l, --dio-h,
 * poses par peindreDiorama) : ecrire des pixels ici les ferait mentir des que
 * la piece change d'une case. */
.hero-scene {
	position: relative;
	/* Le decor est dessine au pixel, puis AGRANDI d'un bloc.
	 *
	 * Le facteur suit la HAUTEUR de la fenetre, pas sa largeur : c'est elle qui
	 * decide s'il reste de la place sous le titre. A deux sur un ecran de
	 * portable, l'accueil gagnait une barre de defilement pour trois
	 * centimetres de trop — et une page d'accueil qui defile, on la lit mal. */
	--dio-z: 2;
	width: calc(var(--dio-l, 0px) * var(--dio-z));
	height: calc(var(--dio-h, 0px) * var(--dio-z));
	flex: none;
	/* Un halo tres sourd, pour que la piece ne flotte pas dans le vide.
	 *
	 * La lueur est le FOND de la boite, et non un pseudo-element deborde : un
	 * `inset: -12%` sortait du cadre, et tout ce qui sort d'un ecran allonge sa
	 * barre de defilement — on gagnait 50 px de vide sous un accueil qui tient
	 * pourtant dans la page. La couleur vient du theme : un ambre ecrit en dur
	 * jurait sur les themes violets et disparaissait sur le theme clair. */
	background: radial-gradient(ellipse at 50% 55%,
		color-mix(in srgb, var(--titre) 13%, transparent), transparent 70%);
	filter: drop-shadow(0 18px 28px rgba(0, 0, 0, .5));
}


/* Le plan porte la taille du decor AVANT agrandissement, et le cadre celle
 * d'apres : c'est la meme boite, vue de part et d'autre du `scale`.
 *
 * `inset: 0` lui donnait la taille du CADRE — deja multipliee — puis le `scale`
 * la multipliait une seconde fois. Un `transform` ne deplace rien dans la mise
 * en page, mais il compte dans ce qu'un parent doit pouvoir faire defiler :
 * l'accueil se retrouvait avec 200 px de vide a droite, une barre horizontale
 * pour les atteindre, et une barre verticale par-dessus le marche — la premiere
 * mange de la hauteur, et la page ne tenait plus a quinze pixels pres. */
.hero-scene .dio-plan {
	position: absolute;
	top: 0;
	left: 0;
	width: var(--dio-l, 0px);
	height: var(--dio-h, 0px);
	transform: scale(var(--dio-z));
	transform-origin: top left;
}

.hero-scene .dio {
	position: absolute;
	background-repeat: no-repeat;
	/* Du pixel art : l'interpolation le rendrait flou des qu'on l'agrandit. */
	image-rendering: pixelated;
}

/* Les trois gestes. `auto-fit` plutot qu'un nombre de colonnes : a l'etroit,
 * elles se rangent d'elles-memes sans qu'on ait a nommer un point de rupture
 * de plus. */
.trois {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: 1rem;
	margin-bottom: 1rem;
}

.trois .geste { margin: 0; }
.trois .geste h2 {
	font-size: 1.05rem;
	margin: 0 0 .4rem;
	color: var(--intertitre);
}
.trois .geste p { margin: 0; }

/* Les deux precisions. 22rem de plancher : la phrase compte deux lignes de plus
 * qu'un geste, et une colonne plus etroite la ferait courir sur cinq.
 *
 * `min(22rem, 100%)` et non `22rem` seul : sur un telephone, ce plancher est
 * plus large que l'ecran, et une colonne ne peut pas descendre en dessous de
 * son minimum — la rangee sortait par la droite au lieu de se resserrer. */
.precisions {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
	gap: .5rem 1.4rem;
}

.precision {
	margin: 0;
	padding: .05rem 0 .05rem .8rem;
	border-left: 2px solid var(--trait);
	color: var(--texte-faible);
	font-size: .875rem;
}

.precision strong { color: var(--intertitre); font-weight: 600; }

/* Sous 1000 px de haut — un portable, en somme — la piece se contente d'une
 * fois et demie. Le facteur n'est plus entier, donc les pixels ne sont plus
 * tous carres ; sur un dessin dont chaque pixel fait deja deux points, cela ne
 * se voit pas, et cela vaut mieux qu'un accueil qu'il faut faire defiler. */
@media (max-height: 1000px) {
	.hero-scene { --dio-z: 1.5; }
}

/* Un ecran vraiment court — une fenetre a demi hauteur, un portable ancien.
 * Tout se resserre d'un cran, et le titre cesse d'etre grand : ce qu'on veut
 * lire ici, c'est la page ENTIERE d'un seul coup d'oeil, et un « Offscript » de
 * sept centimetres coutait exactement les deux precisions du bas. */
@media (max-height: 760px) {
	.hero { margin: .5rem 0 1rem; gap: 1.8rem; }
	.hero-titre { font-size: clamp(2.2rem, 5vw, 3rem); }
	.hero-sous { margin-bottom: 1rem; }
	.hero-scene { --dio-z: 1.25; }
	.trois { gap: .7rem; margin-bottom: .8rem; }
}

@media (max-width: 900px) {
	.hero {
		/* `minmax(0, 1fr)` et non `1fr` : une colonne `1fr` prend pour plancher
		 * la largeur de son contenu le plus large, et laissait le texte sortir
		 * par la droite au lieu de le faire revenir a la ligne. */
		grid-template-columns: minmax(0, 1fr);
		gap: 1.5rem;
	}
	/* Le decor apres le texte, et centre : sur un telephone, c'est une
	 * illustration, plus une mise en page. A l'echelle 1, aussi — a deux, la
	 * piece est plus large que l'ecran et on n'en voit qu'un quart. */
	.hero-scene {
		order: 2;
		margin: 0 auto;
		--dio-z: 1;
	}
}

.accueil { margin-top: 1.5rem; }
.accueil .actions { margin-top: .8rem; }

/* ---------------------------------------------------------------- */
/* Le badge des signalements                                        */
/* ---------------------------------------------------------------- */

/* Un compte, pas une pastille muette : « 3 » se comprend sans survol. Il ne
 * porte QUE les tickets ouverts, sinon il ne redescendrait jamais. */
.badge {
	display: inline-block;
	min-width: 1.1rem;
	padding: 0 .3rem;
	margin-left: .25rem;
	border-radius: 999px;
	background: var(--danger);
	color: var(--fond);
	font-size: .72rem;
	font-weight: 700;
	text-align: center;
	line-height: 1.35;
}

/* ---------------------------------------------------------------- */
/* Signalements                                                     */
/* ---------------------------------------------------------------- */

/* Un ticket se replie : la liste sert a voir CE QUI RESTE a traiter, et dix
 * descriptions ouvertes la rendent illisible. Le titre, l'auteur et la date
 * suffisent a decider si l'on ouvre. */
.ticket {
	background: var(--fond-carte);
	border: 1px solid var(--trait);
	border-left: 3px solid var(--attention);
	border-radius: 8px;
	padding: .6rem .9rem;
	margin: .45rem 0;
}
/* Resolu et ignore ne se confondent pas d'un coup d'oeil : l'un est un travail
 * fait, l'autre un travail refuse. */
.ticket.resolved { border-left-color: var(--bon); opacity: .75; }
.ticket.ignored  { border-left-color: var(--texte-faible); opacity: .6; }

.ticket summary {
	cursor: pointer;
	display: flex;
	gap: .6rem;
	align-items: baseline;
	flex-wrap: wrap;
}
.ticket .tk-titre { font-weight: 600; }
.ticket .tk-qui { font-size: .82rem; }
.ticket .tk-statut { color: var(--texte-faible); }
/* Le texte du joueur, tel qu'il l'a ecrit — retours a la ligne compris. */
.ticket .tk-corps { white-space: pre-wrap; margin: .6rem 0; }
.ticket .actions { margin-top: .5rem; }
.ticket .actions button { padding: .25rem .6rem; font-size: .85rem; }

/* ---------------------------------------------------------------- */
/* Invitations                                                      */
/* ---------------------------------------------------------------- */

.inv-ligne {
	display: grid;
	grid-template-columns: auto 1fr auto;
	gap: .8rem;
	align-items: baseline;
	padding: .4rem 0;
	border-bottom: 1px solid var(--trait);
}
.inv-ligne:last-child { border-bottom: none; }
.inv-ligne .inv-nom { color: var(--texte); }
/* Un code deja consomme n'est plus a distribuer : il reste pour la trace. */
.inv-ligne.utilise { opacity: .55; }
.inv-ligne.utilise code { text-decoration: line-through; }

/* ---------------------------------------------------------------- */
/* Supprimer une sauvegarde                                         */
/* ---------------------------------------------------------------- */

/* Le bouton est SEPARE de la zone qui reprend la partie : les deux gestes sont
 * voisins et l'un est irreversible. */
/* « Ce nom mene deja cette enquete ». En ambre et non en rouge : rien n'est
 * casse, et la sortie est juste a cote — c'est un renseignement, pas une
 * faute. Le bouton de reprise est sur la meme ligne pour qu'on n'ait pas a le
 * chercher plus haut dans la liste des parties. */
.nom-pris {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .5rem;
	margin: .4rem 0 0;
	font-size: .9rem;
	color: var(--attention);
}
.nom-pris button { flex: none; }

.sauvegarde { display: flex; gap: .5rem; align-items: stretch; }
.sauvegarde .item { flex: 1; }
.sauvegarde .jeter {
	flex: none;
	color: var(--texte-faible);
	border: 1px solid var(--trait);
	border-radius: 8px;
	white-space: nowrap;
}
.sauvegarde .jeter:hover { color: var(--danger); border-color: var(--danger); }

/* Quitter la partie n'est pas anodin — on retourne a l'accueil, la scene est
 * detruite. Un rouge PALE : assez pour marquer une hesitation, pas assez pour
 * crier au danger comme le fait `--danger` sur les vraies erreurs. */
/* Derive de `--danger` et non ecrit en dur : deux couleurs figees ici ne
 * suivaient aucun theme, et ce bouton restait rose sur un ecran sepia. */
#j-quitter {
	color: color-mix(in srgb, var(--danger) 72%, var(--texte));
	border-color: color-mix(in srgb, var(--danger) 42%, var(--trait));
}
#j-quitter:hover:not(:disabled) {
	color: var(--danger);
	border-color: var(--danger);
}

/* ---------------------------------------------------------------- */
/* Les comptes                                                      */
/* ---------------------------------------------------------------- */

/* Un compte se replie, comme un ticket : la liste sert a voir QUI joue, et
 * huit fiches depliees ne se parcourent pas. L'entete porte donc ce qui se
 * compare d'un coup d'oeil — le nom, sous quel nom il enquete, et ou il en
 * est — le detail attend qu'on le demande. */
.compte {
	background: var(--fond-carte);
	border: 1px solid var(--trait);
	border-radius: 8px;
	padding: .6rem .9rem;
	margin: .45rem 0;
}
.compte.proprietaire { border-left: 3px solid var(--titre); }
.compte summary {
	cursor: pointer;
	display: flex;
	gap: .6rem;
	align-items: baseline;
	flex-wrap: wrap;
}
.compte .usr-nom { font-weight: 600; }
.compte .usr-pseudo { color: var(--intertitre); }
/* Pousse le resume a droite : les chiffres s'alignent d'une ligne a l'autre et
 * se comparent sans les lire un par un. */
.compte .usr-resume { margin-left: auto; font-size: .82rem; }
.compte .usr-role { color: var(--titre); }

.usr-grille {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: .3rem .9rem;
	margin-top: .7rem;
	padding-top: .6rem;
	border-top: 1px solid var(--trait);
	font-size: .9rem;
}

/* Le sommaire de l'administration : quatre entrees, chacune disant ce qu'elle
 * contient. Ce sont les memes fiches que le catalogue des enquetes — un
 * sommaire n'a pas besoin d'un dessin a lui. */
.sommaire { margin-top: 1rem; }

/* Les codes en attente. Le code, a qui il est destine, depuis quand, et de quoi
 * le retirer : la ligne se lit de gauche a droite dans cet ordre. */
.inv-ligne {
	grid-template-columns: auto 1fr auto auto auto;
}
/* Ce que le code ouvrira. Discret : c'est une precision sur le code, pas le
 * code lui-meme. */
.inv-ligne .inv-groupes-ligne { font-size: .85rem; white-space: nowrap; }

/* Les groupes d'enquetes, en cases a cocher. Ils tiennent sur une ligne tant
 * qu'ils sont peu nombreux, et passent a la suivante sans rien casser. */
.groupes {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem .9rem;
	margin: .3rem 0 .6rem;
}
.groupe-case {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	font-size: .9rem;
	cursor: pointer;
}
.groupe-case input { width: auto; margin: 0; }

/* Les groupes d'un compte : au-dessus des actions, et separes d'elles — decider
 * ce que quelqu'un voit n'est pas du meme ordre que supprimer son compte. */
.usr-groupes {
	margin-top: .7rem;
	padding-top: .6rem;
	border-top: 1px solid var(--trait);
}
.usr-groupes .actions { gap: .5rem; }
.usr-groupes button { padding: .35rem .7rem; font-size: .85rem; }
.inv-ligne .jeter {
	color: var(--texte-faible);
	padding: .2rem .5rem;
	font-size: .85rem;
}
.inv-ligne .jeter:hover { color: var(--danger); }

/* Le serveur ne repond plus. Fixe en haut, par-dessus le bandeau : c'est la
 * seule chose qui compte tant qu'elle est la, et elle doit se voir depuis
 * n'importe quel ecran — y compris le jeu, qui occupe toute la fenetre. */
.alerte-reseau {
	/* Dans le FLUX, en tete du corps : il pousse le bandeau vers le bas au lieu
	 * de le recouvrir. Fixe, il masquait le bouton « Accueil » — cacher la
	 * sortie au moment ou l'on annonce une panne est le pire moment pour le
	 * faire. Le corps est une colonne flex : `flex: none` suffit. */
	flex: none;
	padding: .45rem .9rem;
	text-align: center;
	font-size: .9rem;
	font-weight: 600;
	background: var(--danger);
	color: var(--fond);
}
.alerte-reseau.revenu { background: var(--bon); }

/* Les liens du texte courant. Aucun n'etait style — il n'y en avait aucun — et
 * le bleu du navigateur sur ce fond sombre se lit mal. Le meme ambre que les
 * titres, souligne : sur une page sans autre lien, il faut qu'il se voie. */
.carte a, .carnet a { color: var(--titre); text-decoration: underline; }
.carte a:hover, .carnet a:hover { color: var(--intertitre); }

/* Les parties en cours, en tete de la page des comptes. Une ligne par partie :
 * qui, quoi, et de quoi la regarder. */
.live-ligne {
	display: flex;
	gap: .8rem;
	align-items: center;
	flex-wrap: wrap;
	padding: .5rem .8rem;
	border: 1px solid var(--trait);
	border-radius: 6px;
	margin-bottom: .4rem;
}
.live-ligne .discret { flex: 1; min-width: 12rem; font-size: .9rem; }
.live-ligne button { padding: .35rem .7rem; font-size: .85rem; white-space: nowrap; }

/* On regarde la partie de quelqu'un d'autre. Un bandeau franc au-dessus du
 * jeu : sans lui, l'hote finit par oublier que l'ecran n'est pas le sien et
 * s'etonne que rien ne reponde. */
.observation {
	/* La couleur d'accent du theme, comme le bouton d'action : `--accent` n'est
	 * pose que par les themes qui veulent autre chose que leur couleur de
	 * titre. */
	background: var(--accent, var(--titre));
	color: var(--fond);
	font-size: .85rem;
	font-weight: 600;
	padding: .3rem .7rem;
	border-radius: 5px;
	margin-bottom: .4rem;
}

/* Le credit accorde a un compte. Meme dessin que les groupes juste au-dessus :
 * c'est un reglage de ce compte, pas une action irreversible comme celles du
 * bloc suivant. */
.usr-credit {
	margin-top: .7rem;
	padding-top: .6rem;
	border-top: 1px solid var(--trait);
	display: flex;
	gap: .5rem;
	align-items: center;
	flex-wrap: wrap;
}
.usr-credit .usr-mdp { display: flex; gap: .5rem; flex: 1; min-width: 14rem; }
.usr-credit input { flex: 1; min-width: 0; padding: .4rem .6rem; font-size: .9rem; }
.usr-credit button { padding: .35rem .7rem; font-size: .85rem; white-space: nowrap; }
.usr-credit p { flex-basis: 100%; margin: 0; }

/* Ce que l'hote peut faire d'un compte. Separe du detail par un trait : ce sont
 * des actions, dont une irreversible, et non des informations de plus. */
.usr-actions {
	display: flex;
	gap: .6rem;
	align-items: center;
	flex-wrap: wrap;
	margin-top: .7rem;
	padding-top: .6rem;
	border-top: 1px solid var(--trait);
}
.usr-actions .usr-mdp { display: flex; gap: .5rem; flex: 1; min-width: 18rem; }
.usr-actions input { flex: 1; min-width: 0; padding: .4rem .6rem; font-size: .9rem; }
.usr-actions button { padding: .35rem .7rem; font-size: .85rem; white-space: nowrap; }
.usr-actions .jeter { color: #d98c8c; border-color: #6b3b3b; }
.usr-actions .jeter:hover { color: var(--danger); border-color: var(--danger); }
.usr-actions p { flex-basis: 100%; margin: 0; }

/* Les comptes du sommaire d'administration. Ils restent affiches a zero — une
 * pastille qui disparait laisse croire que le chiffre n'existe pas, alors que
 * « aucun ticket » est justement ce qu'on venait verifier. */
.sommaire .compte-de {
	min-width: 1.6rem;
	text-align: center;
	color: var(--texte-faible);
	font-variant-numeric: tabular-nums;
}
/* Ce qui reclame une action, et seulement quand il y en a une : un « 0 » en
 * rouge appelle l'oeil pour rien. */
.sommaire .compte-de.alerte {
	color: var(--danger);
	font-weight: 700;
}

/* ---------------------------------------------------------------- */
/* Les enquetes, vues par l'hote                                    */
/* ---------------------------------------------------------------- */

/* Une enquete sans tampon a jour n'est pas jouable : le moteur refuse de la
 * lancer et les joueurs ne la voient meme pas. Elle doit donc se reperer d'un
 * coup d'oeil dans la liste. */
.adm-ligne.non-verifiee { border-left: 3px solid var(--attention); }
.etiquette.non-analysee { color: var(--attention); }
.adm-ligne .adm-analyser { padding: .2rem .55rem; font-size: .85rem; white-space: nowrap; }

/* Un geste qui ne se refait pas en rechargeant la page se signale AVANT d'etre
 * clique. Ces boutons restent sobres au repos — un rouge permanent dans une
 * liste de dix lignes devient un fond d'ecran qu'on n'oit plus — et ne
 * s'allument qu'au survol, quand la main est deja dessus. */
button.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
button.danger:hover:not(:disabled) { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 14%, transparent); }
button.principal.danger { background: var(--danger); border-color: var(--danger); color: var(--fond); }
button.principal.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 85%, white); }

/* Reordonner : la poignee, et ou l'element va tomber.
 *
 * Deux fleches par ligne demandaient un clic par rang — dix pour descendre de
 * dix, en repointant la souris a chaque fois puisque la ligne bouge sous le
 * curseur. La poignee se glisse d'un geste, et garde le clavier : c'est un
 * `button`, donc il prend le focus et repond aux fleches. */
.adm-poignee {
	cursor: grab;
	padding: .1rem .35rem;
	color: var(--texte-faible);
	border-color: transparent;
	background: transparent;
	font-size: 1.05rem;
	line-height: 1;
}
.adm-poignee:hover { color: var(--titre); }
.adm-poignee:active { cursor: grabbing; }
.adm-ligne.glisse { opacity: .4; }
/* Le trait de depose. Il tient sur la BORDURE de la ligne survolee, sans
 * decaler quoi que ce soit : une ligne qui s'ecarte pour faire de la place
 * ferait bouger la cible sous le curseur, et l'on deposerait ailleurs. */
.adm-ligne.cible-avant { box-shadow: inset 0 2px 0 0 var(--titre); }
.adm-ligne.cible-apres { box-shadow: inset 0 -2px 0 0 var(--titre); }

/* Les enquetes dont le fichier a disparu. Elles ne sont pas une liste
 * d'enquetes : ce sont des restes, et la carte le dit avant de les lire. */
.carte.manquantes { margin-top: .8rem; border-left: 3px solid var(--attention); }
.carte.manquantes h2 { margin-top: 0; font-size: 1rem; color: var(--attention); }
.adm-ligne.manquante .adm-titre { color: var(--texte-faible); }
.adm-ligne.manquante code { font-size: .9rem; }

/* La confirmation de suppression. */
.carte.suppression { margin-top: .8rem; border-left: 3px solid var(--danger); }
.carte.suppression h2 { margin-top: 0; font-size: 1rem; }
.adm-supp-liste { margin: .4rem 0 .8rem; padding-left: 1.1rem; color: var(--texte); }
.adm-supp-liste li { margin: .2rem 0; }

/* Le rapport de l'outil, tel qu'il l'ecrit : sa mise en page est la sienne. */
.rapport { margin-top: .8rem; }
.rapport .rapport-tete {
	display: flex;
	gap: .6rem;
	align-items: center;
	margin-bottom: .6rem;
}
.rapport .rapport-tete button { margin-left: auto; }
.rapport .rapport-corps {
	margin: 0;
	max-height: 24rem;
	overflow: auto;
	padding: .7rem .9rem;
	background: var(--fond-creux);
	border: 1px solid var(--trait);
	font-family: ui-monospace, "DejaVu Sans Mono", monospace;
	font-size: .82rem;
	line-height: 1.5;
	white-space: pre-wrap;
	word-break: break-word;
}

/* ---------------------------------------------------------------- */
/* Le visualisateur d'assets                                        */
/* ---------------------------------------------------------------- */

.as-section { margin: 1.4rem 0; }
.as-section h2 { margin-bottom: .2rem; }

.as-grille { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }

/* Une case : le cadre fin tombe sur ses limites REELLES, c'est tout l'objet.
 * `align-items: flex-end` colle le dessin au bas de sa fenetre, comme la scene
 * le pose sur le sol. */
.as-case {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .15rem;
	padding: .25rem;
	background: var(--fond-creux);
}
.as-case:hover { border-color: var(--titre); }
.as-vue {
	display: block;
	border: 1px solid color-mix(in srgb, var(--titre) 45%, transparent);
	background-repeat: no-repeat;
	/* Ces dessins sont des pixels : les lisser les salit. */
	image-rendering: pixelated;
}
.as-nom {
	font-family: ui-monospace, "DejaVu Sans Mono", monospace;
	font-size: .66rem;
	color: var(--texte-faible);
	max-width: 9rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Un objet par LIGNE, avec ses rotations. */
.as-objet {
	display: flex;
	align-items: flex-start;
	gap: .8rem;
	padding: .5rem 0;
	border-top: 1px solid var(--trait);
}
.as-objet-nom {
	flex: 0 0 7rem;
	font-weight: 600;
	padding-top: .5rem;
}

/* La barre du bas porte le detail ET le retour : le detail prend la place, le
 * bouton reste a droite. */
.as-barre { justify-content: flex-start; gap: 1rem; }
.as-barre #as-retour { margin-left: auto; }
.as-detail { display: flex; align-items: center; gap: .9rem; min-width: 0; flex: 1; }
.as-detail-nom { display: flex; flex-direction: column; gap: .1rem; flex: 0 0 auto; }
.as-detail-nom .discret { font-size: .72rem; }
.as-detail-json {
	margin: 0;
	flex: 1;
	min-width: 0;
	overflow-x: auto;
	padding: .35rem .55rem;
	background: var(--fond-creux);
	border: 1px solid var(--trait);
	border-radius: 6px;
	font-family: ui-monospace, "DejaVu Sans Mono", monospace;
	font-size: .78rem;
	white-space: pre;
}
/* La page defile sous une barre fixe : sans cette reserve, les dernieres cases
 * restent cachees dessous. */
#ecran-assets { padding-bottom: 5rem; }

/* ---------------------------------------------------------------- */
/* L'editeur de carte                                               */
/* ---------------------------------------------------------------- */

/* La scene occupe la meme place que celle du jeu : c'est le meme plateau, et
 * l'on doit y reconnaitre la carte qu'on jouera. */
#scene-carte { min-height: 0; overflow: hidden; }
/* La case sous la souris. En chasse fixe et a largeur reservee : un compteur
 * qui change de largeur a chaque case fait sautiller ce qui le suit. */
.ce-case {
	font-family: ui-monospace, "DejaVu Sans Mono", monospace;
	font-size: .8rem;
	color: var(--titre);
	min-width: 8.5rem;
}
#ce-aide { margin-left: auto; font-size: .78rem; }

/* Le titre et le selecteur de theme sur la meme ligne : c'est un reglage de
 * CETTE carte, pas une entree de la palette. */
.ce-tete { display: flex; align-items: center; gap: .4rem; }
.ce-onglet { padding: .25rem .55rem; font-size: .85rem; background: none; border-color: transparent; }
.ce-onglet.actif { background: var(--fond-creux); border-color: var(--titre); color: var(--titre); }

/* Les personnages, un par ligne : l'apercu a gauche, les reglages a droite. */
#ce-pnj { overflow-y: auto; padding: .4rem; display: grid; gap: .45rem; }
.ce-perso {
	border: 1px solid var(--trait);
	border-radius: 6px;
	background: var(--fond-carte);
	padding: .4rem .5rem;
	display: grid;
	grid-template-columns: auto 1fr;
	gap: .5rem;
	align-items: start;
}
/* L'apercu : le meme empilement que la scene — jambes, torse, visage, cheveux —
 * chacun decoupe dans sa planche. Hauteur fixe, sinon les lignes sautent. */
/* 54 px de silhouette a l'echelle 2 : la hauteur exacte de l'empilement de la
 * scene, sinon les jambes sont coupees en bas. */
.ce-apercu { position: relative; width: 60px; height: 108px; flex: 0 0 auto; }
.ce-apercu span {
	position: absolute;
	background-repeat: no-repeat;
	image-rendering: pixelated;
}
.ce-perso-nom { font-size: .82rem; font-weight: 600; }
.ce-perso-role { font-size: .7rem; color: var(--texte-faible); }
.ce-reglages { display: grid; grid-template-columns: auto auto auto auto; gap: .1rem .25rem;
	align-items: center; margin-top: .25rem; }
.ce-reglages .lbl { font-size: .68rem; color: var(--texte-faible); }
.ce-reglages button { padding: 0 .3rem; font-size: .8rem; line-height: 1.35; }
.ce-reglages .val { font-size: .72rem; font-family: ui-monospace, monospace;
	text-align: center; min-width: 1.7rem; }
.ce-tete select { width: auto; flex: 1; min-width: 0; padding: .25rem .4rem; font-size: .82rem; }

/* Le rapport de verification, PAR-DESSUS la carte. L'ecran de l'editeur est en
 * plein ecran (`overflow: hidden`) et son plateau prend toute la hauteur : un
 * bloc pose a la suite n'etait jamais visible, donc une carte refusee ne disait
 * pas pourquoi. Flottant, au-dessus de la barre du bas, avec sa propre hauteur
 * bornee pour ne pas manger l'ecran quand le rapport est long. */
.ce-rapport-flottant {
	position: absolute;
	left: 1rem;
	right: 1rem;
	/* En HAUT, sous le cartouche : ancre en bas, il recouvrait le milieu de la
	 * carte et interceptait les clics — on ne pouvait plus poser un objet la ou
	 * on venait de lire une erreur. Le centre et le bas restent libres. */
	top: 3.2rem;
	z-index: 30;
	max-height: 40%;
	overflow-y: auto;
	box-shadow: 0 8px 28px #0009;
}

#ce-palette { overflow-y: auto; padding: .4rem; display: grid; gap: .3rem; }
.ce-objet {
	display: flex;
	align-items: center;
	gap: .55rem;
	text-align: left;
	padding: .35rem .5rem;
	line-height: 1.25;
}
.ce-texte { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.ce-objet .nom { font-weight: 600; }

/* La vignette : UNE case de la planche, celle du sud. La planche fait
 * 4 x 128 px de large ; on la reduit de moitie et l'on decale de la largeur
 * d'une case et demie pour amener la troisieme colonne dans la fenetre.
 * `pixelated` : ces dessins sont des pixels, les lisser les salit. */
.ce-vignette {
	flex: 0 0 auto;
	position: relative;
	width: 64px;
	height: 56px;
	overflow: hidden;
	border: 1px solid var(--trait);
	border-radius: 4px;
	background: var(--fond-creux);
}
.ce-vignette img {
	position: absolute;
	top: 0;
	left: -128px;          /* colonne 2 (sud), a l'echelle 1/2 */
	width: 256px;          /* 512 / 2 : les planches font toujours 4 x 128 */
	/* La hauteur est LIBRE, et c'est important : une planche animee a plusieurs
	 * lignes (l'ordinateur en a quatre, la borne deux). Lui imposer 56 px les
	 * ecrasait toutes dans la hauteur d'une seule. En laissant l'aspect, la
	 * fenetre de 56 px montre la premiere ligne — l'image au repos. */
	height: auto;
	image-rendering: pixelated;
}
.ce-vignette.vide { opacity: .3; }
.ce-objet .discret { font-size: .74rem; }
/* Celui qu'on tient au bout de la souris. */
.ce-objet.actif {
	border-color: var(--titre);
	background: color-mix(in srgb, var(--titre) 18%, var(--fond-creux));
}
.ce-actions { display: flex; gap: .5rem; justify-content: flex-end; }

/* ---------------------------------------------------------------- */
/* Generation d'enquetes                                            */
/* ---------------------------------------------------------------- */

#carte-generation, #gen-export, #gen-resultat { margin-bottom: 1rem; }
.gen-ligne {
	display: flex;
	gap: .8rem;
	align-items: flex-end;
	flex-wrap: wrap;
}
.gen-ligne label { flex: 0 0 auto; }
.gen-ligne input, .gen-ligne select { width: auto; min-width: 9rem; }
.gen-ligne input#gen-modele { flex: 1; min-width: 14rem; }
#gen-description { min-height: 10rem; }
#gen-json, #gen-export-texte {
	font-family: ui-monospace, "DejaVu Sans Mono", monospace;
	font-size: .82rem;
	min-height: 20rem;
}
#gen-export-texte { min-height: 16rem; }

/* La reflexion du modele : elle defile pendant l'attente, donc elle a une
 * hauteur FIXE — une boite qui grandit de plusieurs milliers de lignes pousse
 * tout le reste de la page hors de vue. */
#gen-reflexion { margin-bottom: 1rem; }
#gen-reflexion-texte {
	height: 14rem;
	max-height: 14rem;
	overflow-y: auto;
	color: var(--texte-faible);
	font-size: .78rem;
}
#gen-reflexion .rapport-tete { margin-bottom: .6rem; }
#gen-reflexion .rapport-tete .discret { margin-left: auto; }

/* Le JSON lu en clair. */
#gen-resume { margin-bottom: .4rem; }
.resume-tete { display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; }
.resume-tete code { font-size: .8rem; color: var(--texte-faible); }
.resume-premisse { margin: .35rem 0 .7rem; }

.resume-chiffres {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
	gap: .5rem;
	margin: .7rem 0;
}
.resume-chiffre {
	background: var(--fond-creux);
	border: 1px solid var(--trait);
	border-radius: 6px;
	padding: .5rem .6rem;
	display: flex;
	flex-direction: column;
	gap: .1rem;
}
.resume-chiffre strong { font-size: 1.25rem; line-height: 1.1; }
.resume-chiffre span { font-size: .76rem; color: var(--texte-faible); }
/* Un zero se remarque : c'est souvent lui qui rend une enquete injouable. */
.resume-chiffre.vide { border-color: var(--attention); }
.resume-chiffre.vide strong { color: var(--attention); }

.resume-gens {
	width: 100%;
	border-collapse: collapse;
	margin: .7rem 0;
	font-size: .82rem;
}
.resume-gens th, .resume-gens td {
	text-align: left;
	padding: .32rem .5rem;
	border-bottom: 1px solid var(--trait);
}
.resume-gens th { color: var(--texte-faible); font-weight: 600; font-size: .76rem; }
.resume-gens tr.coupable td { color: var(--attention); }

/* ---------------------------------------------------------------- */
/* Choisir son personnage                                           */
/* ---------------------------------------------------------------- */

/* Au milieu de l'ecran, par-dessus ce qu'on regardait. `position: fixed` : on y
 * vient depuis les reglages comme depuis la partie, et la partie ne defile
 * pas. */
.modale {
	position: fixed;
	inset: 0;
	z-index: 60;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1rem;
	background: rgba(0, 0, 0, .6);
}
.modale .perso-boite { width: min(26rem, 100%); }

/* Trois rangees, une par piece : la fleche de gauche, la piece, la fleche de
 * droite. Chaque rangee est haute comme SA piece, donc les fleches tombent en
 * face de ce qu'elles changent — c'est tout l'objet de cette grille.
 *
 * Le personnage reste d'un seul tenant parce que les trois pieces se touchent :
 * aucun ecart entre les rangees, et l'empilement se lit comme un corps. */
.perso-vue {
	display: grid;
	grid-template-columns: auto auto auto;
	justify-content: center;
	align-items: center;
	column-gap: 1.2rem;
	row-gap: 0;
	margin: 1.2rem 0;
}
/* La tete occupe la cellule du milieu, comme une piece ; visage et cheveux s'y
 * superposent (le visage en flux donne la taille, les cheveux par-dessus). */
.perso-vue .tete {
	grid-column: 2;
	position: relative;
	display: block;
	justify-self: center;
	/* Pas d'interligne : sans cela un fantome de ligne s'insererait sous la tete
	 * et la decollerait du buste, alors que les pieces DOIVENT se toucher. */
	line-height: 0;
	font-size: 0;
}
.perso-vue .tete #perso-cheveux {
	position: absolute;
	top: 0;
	left: 0;
}
.perso-vue .sprite {
	display: block;
	grid-column: 2;
	background-repeat: no-repeat;
	/* Du pixel art : on l'agrandit sans le lisser. L'agrandissement lui-meme
	 * est fait sur la taille et le fond (voir ZOOM dans app.js), pas par une
	 * transformation — celle-ci grossit l'image sans changer la place occupee,
	 * et les fleches ne tombaient plus en face de rien. */
	image-rendering: pixelated;
}
.perso-fleche {
	padding: .25rem .65rem;
	font-size: 1.3rem;
	line-height: 1;
	/* La fleche est centree sur la hauteur de sa piece. */
	align-self: center;
}

/* Le teint : une rangee a part, sous le personnage. Il ne se choisit pas comme
 * une piece — c'est la meme peau sur les trois — et le montrer dans la colonne
 * laisserait croire qu'il n'affecte que le visage. */
.perso-teint {
	display: grid;
	grid-template-columns: auto auto auto;
	justify-content: center;
	align-items: center;
	column-gap: 1.2rem;
	margin-top: .8rem;
}

/* Une enquete d'atelier : dispensee de tampon, donc signalee. Elle ne doit
 * jamais se confondre avec une enquete validee. */
.etiquette.atelier { color: var(--intertitre); }
/* Le groupe qui range une enquete. Discret : c'est un rangement, pas un etat —
 * a la difference de « non analysee », qui dit qu'elle ne se joue pas. */
.etiquette.groupe { color: var(--texte-faible); }

/* ------------------------------------------------------------------ */
/* Le menu d'un objet pose, dans l'editeur de carte                    */
/* ------------------------------------------------------------------ */

/* Il est pose sur la PAGE, au-dessus du canvas, et non peint dans la scene :
 * un menu dessine par Phaser n'aurait ni clavier, ni lecteur d'ecran, ni le
 * style du reste du site, et il faudrait le redessiner a chaque zoom. */
.ce-menu {
	position: fixed;
	z-index: 60;
	min-width: 11rem;
	padding: .3rem;
	background: var(--fond-carte);
	border: 1px solid var(--trait);
	border-radius: 8px;
	box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
}
.ce-menu-titre {
	padding: .3rem .5rem .4rem;
	font-size: .78rem;
	color: var(--texte-faible);
	border-bottom: 1px solid var(--trait);
	margin-bottom: .25rem;
	white-space: nowrap;
}
.ce-menu-action {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 1rem;
	width: 100%;
	padding: .35rem .5rem;
	background: transparent;
	border: none;
	border-radius: 5px;
	color: var(--texte);
	font-size: .88rem;
	text-align: left;
	cursor: pointer;
}
.ce-menu-action:hover:not(:disabled) { background: color-mix(in srgb, var(--titre) 16%, transparent); }
.ce-menu-action.danger { color: var(--danger); }
.ce-menu-action.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 16%, transparent); }
/* Le raccourci, a droite et en retrait : il se lit quand on le cherche, et ne
 * dispute pas la place au libelle. */
.ce-menu-raccourci { font-size: .72rem; color: var(--texte-faible); }

/* Le motif d'une enquete perdue. En rouge et en un seul bloc : c'est la
 * derniere chose qu'on lit d'une partie, et elle doit se distinguer d'une note
 * de plus — sans quoi « perdu » passe pour un defaut du jeu au lieu d'une
 * consequence de ce qu'on a fait. */
.perdu {
	color: var(--danger);
	border-left: 3px solid var(--danger);
	padding-left: .8rem;
	margin: 0 0 1rem;
}
