/* LA FEUILLE DU SITE — ET ELLE PARLE LA GRAMMAIRE DU HUD DU JEU.
 *
 * ⚠️ ELLE A ÉTÉ RÉÉCRITE LE 31 AOÛT 2026, ET LE MOTIF EST UN REPROCHE JUSTE : « tu n'as pas
 * respecté le design du jeu, tu as gardé ce qui existait déjà ». La première version prenait
 * les JETONS du jeu — palette de D-40, Michroma et Oxanium — et les posait sur une mise en page
 * éditoriale ordinaire : grandes colonnes de texte, blancs généreux, filets sobres. Un site de
 * magazine peint aux couleurs d'Odyssea.
 *
 * OR LE JEU A UNE FORME, ET ELLE EST ÉCRITE : `scripts/hud.css` porte sa grammaire, pièce par
 * pièce — le panneau à COIN COUPÉ dont le contour s'atténue au lieu de se fermer, la BOÎTE DE
 * VISÉE à quatre équerres, la LIAISON coudée qui relie une étiquette à ce qu'elle nomme,
 * l'ÉTIQUETTE À CROCHET qui porte un code, le RAIL dont le trait s'éteint, la TRAME et le
 * BALAYAGE. Ce sont ces pièces qui font qu'un écran ressemble à Odyssea, pas ses couleurs.
 *
 * CE QU'ON N'EMPRUNTE PAS À `hud.css` : ses polices. Le banc de largeur y emploie une chasse
 * fixe, mais le jeu n'en embarque AUCUNE — les chiffres d'Oxanium sont de largeur égale, donc
 * une colonne de nombres s'aligne sans monospace (`theme.ts`). Michroma tient le chrome, petite
 * et très écartée ; Oxanium porte la taille et la donnée.
 */

:root {
  color-scheme: dark;

  /* Les sols, D-40 : neutres, pour que l'or et le turquoise soient les seules couleurs. */
  --fond: #000000;
  --panneau: #0a0a0a;
  --carte: #111113;

  --bord: #54575a;
  --bord-vif: #5c5f62;

  --encre: #eaebeb;
  --discret: #9ea0a2;
  --efface: #7a8085;

  --signal: #fbb225;
  --signal-vif: #fedd58;
  --sur-action: #101010;

  --peuple: #58dbdb;
  --metal: #e7a04c;
  --iridium: #b48ce0;
  --antimatiere: #e7c04c;
  --vivres: #7fc07f;
  --bon: #7fc07f;
  --alerte-vive: #fc8d29;
  --danger: #e05c48;

  /* L'ACCENT EST LE GRIS, ET C'EST TOUTE LA DÉCISION D-40. L'ossature ne concurrence plus les
     identités : sur du gris, une flotte cyan et un chantier doré sont les seules choses vivantes. */
  --accent: #9aa7b4;

  /* L'OSSATURE SE DÉRIVE, ELLE NE S'ÉCRIT PAS — la leçon de `hud.css` : des gris de séparation
     écrits en littéraux venaient tous du bleu, si bien qu'essayer une palette grise laissait le
     squelette en bleu. Tout descend ici de l'accent et du fond de panneau. */
  --faible: color-mix(in srgb, var(--accent) 26%, transparent);
  --structure: color-mix(in srgb, var(--accent) 20%, var(--panneau));
  --structure-vive: color-mix(in srgb, var(--accent) 34%, var(--panneau));
  --creux: color-mix(in srgb, var(--accent) 14%, var(--panneau));
  --voile-panneau: color-mix(in srgb, var(--panneau) 60%, transparent);
  --voile-plein: color-mix(in srgb, var(--panneau) 88%, transparent);

  --sortie: cubic-bezier(0.16, 1, 0.3, 1);
  --large: 96rem;
  --marge: clamp(0.9rem, 2.2vw, 2.4rem);
}

@font-face { font-family: 'Michroma'; src: url('/p/michroma.ttf') format('truetype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Oxanium'; src: url('/p/oxanium-regular.ttf') format('truetype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Oxanium'; src: url('/p/oxanium-medium.ttf') format('truetype'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'Oxanium'; src: url('/p/oxanium-semibold.ttf') format('truetype'); font-weight: 600; font-display: swap; }
@font-face { font-family: 'Oxanium'; src: url('/p/oxanium-bold.ttf') format('truetype'); font-weight: 700; font-display: swap; }

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  min-width: 20rem;
  background: var(--fond);
  color: var(--encre);
  font-family: Oxanium, ui-sans-serif, system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
ol, ul { list-style: none; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ═══ LES PIÈCES DE BASE ══════════════════════════════════════════════════════════════════ */

/* ⚠️ MICHROMA NE SERT QU'À UN SEUL RÔLE, ET C'EST `theme.ts` QUI LE DIT — pas une préférence.
 *
 * Le jeton `titrePanneau` est le SEUL de la table à porter `POLICE.titre` : Michroma, dix
 * points, deux d'interlettrage, en ENCRE. Tous les autres — étiquette, valeur, corps, note,
 * verbe, donnée — sont en Oxanium.
 *
 * J'AVAIS MIS DU MICHROMA PARTOUT, ET EN EFFACÉ. Michroma est un display à lettres carrées :
 * sous dix points, ses fûts fins se ferment et le mot devient une frise. Posé en plus sur
 * `efface`, le troisième cran d'encre, il ne restait rien à lire — « COMMANDEMENT GALACTIQUE »
 * et « LE JEU » étaient des textures, pas des mots.
 *
 * L'ENCRE A TROIS CRANS ET CHACUN A SON EMPLOI : `encre` pour ce qu'on lit en premier — titres
 * et valeurs ; `discret` pour ce qui accompagne — étiquettes et corps ; `efface` pour ce qui
 * est présent mais tu. Une étiquette est en DISCRET, jamais en effacé.
 */

/* `etiquette` — Oxanium-Medium 10,5 · +1,6 · discret. C'est l'étiquette au-dessus d'une valeur. */
.etiq, .lib {
  display: block;
  font-family: Oxanium, ui-sans-serif, system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.11em;
  line-height: 1.45;
  text-transform: uppercase;
  color: var(--discret);
}
.etiq--accent { color: var(--accent); }
.etiq--signal { color: var(--signal); }
.etiq--encre { color: var(--encre); }

/* `note` — ce qui accompagne sans concurrencer. Le seul emploi d'`efface`. */
.micro {
  font-family: Oxanium, sans-serif;
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--efface);
}

/* `valeur` — Oxanium-SemiBold, en encre. C'est le chiffre qu'on vient lire. */
.val, .valeur { font-weight: 600; font-size: 1.35rem; letter-spacing: 0.01em; line-height: 1; color: var(--encre); }
.valeur--grande { font-size: clamp(1.9rem, 3vw, 2.9rem); }

/* L'ÉTIQUETTE À CROCHET — `B2`, `ACT_07`. Un bloc plein, une amorce épaisse devant. */
.crochet {
  display: inline-flex;
  align-items: stretch;
  font-family: Oxanium, sans-serif;
  font-weight: 700;
  font-size: 0.63rem;
  letter-spacing: 0.05em;
  flex: none;
}
.crochet > i { width: 3px; background: var(--accent); }
.crochet > span { background: var(--accent); color: var(--fond); padding: 3px 7px 2px; }
.crochet--creux > span { background: var(--creux); color: var(--accent); }

/* LE RAIL — un trait qui s'éteint aux deux bouts. Il sépare sans encadrer. */
.rail { display: flex; align-items: center; gap: 0.6rem; }
.rail__trait {
  flex: 1;
  height: 1px;
  opacity: 0.8;
  background: linear-gradient(90deg,
    var(--bord) 0 24%, transparent 24% 30%, var(--accent) 30% 36%, transparent 36% 44%,
    var(--bord) 44% 68%, var(--accent) 68% 73%, var(--bord) 73% 100%);
}

/* ═══ LE PANNEAU — UN CONTOUR QUI NE SE FERME PAS ═════════════════════════════════════════
 *
 * ⚠️ PORTÉ DE `scripts/hud.css`, SEGMENT PAR SEGMENT (31 août 2026). J'en avais fait une
 * approximation — un seul coin coupé, quatre bordures pleines — et ce n'était pas le même objet.
 *
 * L'ŒIL FERME LA FIGURE TOUT SEUL (loi de clôture), donc le trait n'a plus qu'à indiquer les
 * ANGLES. Ça ALLÈGE — un rectangle cerné pèse comme une boîte — et ça DÉSIGNE : on garde le
 * trait où le panneau COMMENCE, on le lâche où il ne fait que continuer.
 *
 * LE CONTOUR NE SE TROUE PAS, IL S'ATTÉNUE. Un contour à trous laisse des bouts de panneau
 * ouverts : à petite taille on ne lit plus une forme, on lit un accident. Un liseré COMPLET mais
 * à 26 % ferme la figure ; les segments vifs posés dessus disent où elle commence. L'ORDRE DES
 * COUCHES COMPTE — en CSS la première est au-dessus : les vifs d'abord, le faible dessous.
 *
 * LA COUPE EST DOUBLE, et je n'en avais vu qu'une : haut-droit ET bas-gauche. C'est ce qui
 * empêche la forme d'être un simple rectangle biseauté.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.cadre {
  --coupe: 13px;
  position: relative;
  background: var(--voile-panneau);
  clip-path: polygon(
    0 0, calc(100% - var(--coupe)) 0, 100% var(--coupe),
    100% 100%, var(--coupe) 100%, 0 calc(100% - var(--coupe)));
}
.cadre::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  /* La lueur est portée par le tracé lui-même, à trois pixels : de quoi allumer une ligne d'un
     pixel, pas de quoi la flouter. */
  filter: drop-shadow(0 0 3px var(--faible));
  background:
    linear-gradient(var(--accent), var(--accent)) 0 0 / 42% 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 100% 0 / 22% 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 0 100% / 28% 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 100% 100% / 40% 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 0 0 / 1px 34% no-repeat,
    linear-gradient(var(--accent), var(--accent)) 0 100% / 1px 24% no-repeat,
    linear-gradient(var(--accent), var(--accent)) 100% 0 / 1px 26% no-repeat,
    linear-gradient(var(--accent), var(--accent)) 100% 100% / 1px 36% no-repeat,
    linear-gradient(var(--faible), var(--faible)) 0 0 / 100% 1px no-repeat,
    linear-gradient(var(--faible), var(--faible)) 0 100% / 100% 1px no-repeat,
    linear-gradient(var(--faible), var(--faible)) 0 0 / 1px 100% no-repeat,
    linear-gradient(var(--faible), var(--faible)) 100% 0 / 1px 100% no-repeat;
}
/* LA COUPE EST TRACÉE : c'est la signature de la forme, et la silhouette d'un fond translucide
   ne la dirait pas assez fort. Le `clip-path` du cadre rogne ce trait pile sur la diagonale. */
.cadre::before {
  content: "";
  position: absolute;
  right: -3px;
  top: 3px;
  width: calc(var(--coupe) * 1.7);
  height: 1px;
  background: var(--accent);
  transform: rotate(45deg);
  transform-origin: right center;
  opacity: 0.9;
  z-index: 5;
}
.cadre--plein { background: var(--voile-plein); }
.cadre--opaque { background: var(--panneau); }

/* LA BARRE DE TITRE GARDE SON TRAIT ENTIER. Un panneau dont TOUT serait interrompu flotterait :
   il faut une arête franche là où il commence. */
.cadre__titre {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: stretch;
  gap: 0.7rem;
  border-bottom: 1px solid var(--accent);
  padding-right: 0.6rem;
  min-height: 1.85rem;
  opacity: 0.96;
}
.cadre__nom {
  flex: 1;
  display: flex;
  align-items: center;
  font-family: Michroma, ui-sans-serif, system-ui, sans-serif;
  font-size: 0.63rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--encre);
}
.cadre__suffixe { display: flex; align-items: center; }
.cadre__corps { position: relative; z-index: 2; padding: 0.9rem 0.95rem 1.05rem; }

/* LA BOÎTE DE VISÉE — quatre équerres et rien au milieu. Elle DÉSIGNE sans masquer. */
.visee { position: relative; }
.visee > i { position: absolute; width: 10px; height: 10px; border: 0; border-color: var(--accent); z-index: 6; }
.visee > i:nth-child(1) { left: -1px; top: -1px; border-left: 1px solid; border-top: 1px solid; }
.visee > i:nth-child(2) { right: -1px; top: -1px; border-right: 1px solid; border-top: 1px solid; }
.visee > i:nth-child(3) { left: -1px; bottom: -1px; border-left: 1px solid; border-bottom: 1px solid; }
.visee > i:nth-child(4) { right: -1px; bottom: -1px; border-right: 1px solid; border-bottom: 1px solid; }

/* LA TRAME ET LE BALAYAGE — ce qui fait « écran » plutôt que « page ». Discrets : au-delà,
   ils salissent le texte au lieu de l'installer. */
.trame, .balayage { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.trame {
  opacity: 0.4;
  background:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--accent) 7%, transparent) 0 1px, transparent 1px 4px);
}
.balayage {
  opacity: 0.35;
  background: repeating-linear-gradient(180deg, transparent 0 2px, color-mix(in srgb, var(--fond) 55%, transparent) 2px 3px);
}
.hachure {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  opacity: 0.45;
  background: repeating-linear-gradient(45deg, var(--faible) 0 1px, transparent 1px 5px);
}

/* LA JAUGE ET LES CRANS — deux façons de dire une part. On LIT un cran, on estime un trait. */
.jauge { height: 3px; background: color-mix(in srgb, var(--creux) 60%, transparent); }
.jauge > i { display: block; height: 100%; background: var(--ton, var(--accent)); }
.crans { display: flex; gap: 2px; }
.crans > i { flex: 1; height: 4px; background: color-mix(in srgb, var(--creux) 60%, transparent); }
.crans > i.on { background: var(--ton, var(--accent)); }

/* ═══ LE GESTE — LA MARQUE EST DEHORS ═════════════════════════════════════════════════════
 *
 * ⚠️ C'EST LA PIÈCE QUE J'AVAIS LE PLUS MAL COPIÉE. J'en avais fait une boîte à coin coupé avec
 * une bordure et un fond doré. Dans les planches de référence, l'amorce n'est JAMAIS dans le
 * bouton : une courte barre posée sur le dessus, un index minuscule à côté, des crans qui
 * débordent à droite, une équerre au coin bas. Le bouton reste un rectangle propre ; ce qui
 * l'accroche vit AUTOUR de lui.
 *
 * ET SA COUPE EST L'INVERSE DE CELLE DU PANNEAU — bas-droit, quand le panneau coupe haut-droit.
 * Deux objets qui se coupent du même côté se confondent ; coupés à l'opposé, on sait lequel se
 * presse.
 *
 * SON CORPS PREND UN DIXIÈME DU VERBE, et c'est un retour de playtest : « le bouton quand
 * cliquable ne ressort pas assez, je n'ai pas compris que je pouvais cliquer dessus ». Un
 * rectangle sombre à liseré fin est une BOÎTE ; il faut qu'un peu de la couleur passe dans la
 * matière pour qu'on lise un OBJET en or. Pas plus : l'aplat plein reste réservé à ce qui est
 * CHOISI.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.geste { position: relative; display: inline-block; }
.geste__dehors {
  position: absolute;
  top: -9px;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 8px;
}
.geste__idx { font-family: Oxanium, sans-serif; font-weight: 500; font-size: 0.6rem; letter-spacing: 0.1em; color: var(--efface); }
.geste__barre { height: 2px; width: 26px; background: var(--ton, var(--accent)); }
.geste__file { flex: 1; height: 1px; background: var(--bord); opacity: 0.55; }
.geste__crans { position: absolute; right: -5px; top: 6px; display: flex; flex-direction: column; gap: 3px; }
.geste__crans > i { width: 3px; height: 6px; background: var(--ton, var(--accent)); opacity: 0.55; }
.geste__equerre {
  position: absolute; right: -4px; bottom: -4px; width: 10px; height: 10px;
  border-right: 1px solid var(--ton, var(--accent));
  border-bottom: 1px solid var(--ton, var(--accent));
  opacity: 0.7;
}

/* SES SEGMENTS SONT PLUS LONGS QUE CEUX D'UN PANNEAU, et son bord bas reste ENTIER — c'est
   celui que le pouce vise. On allège une boîte qu'on presse, on ne la dissout pas. */
.plaque {
  --coupe: 14px;
  --fb-ton: color-mix(in srgb, var(--ton, var(--accent)) 26%, transparent);
  position: relative;
  display: block;
  background: color-mix(in srgb, var(--ton, var(--accent)) 12%, transparent);
  cursor: pointer;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--coupe)), calc(100% - var(--coupe)) 100%, 0 100%);
  transition: background 180ms ease;
}
.plaque::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--ton, var(--accent)) 22%, transparent));
  background:
    linear-gradient(var(--ton, var(--accent)), var(--ton, var(--accent))) 0 0 / 58% 1px no-repeat,
    linear-gradient(var(--ton, var(--accent)), var(--ton, var(--accent))) 100% 0 / 24% 1px no-repeat,
    linear-gradient(var(--ton, var(--accent)), var(--ton, var(--accent))) 0 100% / 100% 1px no-repeat,
    linear-gradient(var(--ton, var(--accent)), var(--ton, var(--accent))) 0 0 / 1px 100% no-repeat,
    linear-gradient(var(--ton, var(--accent)), var(--ton, var(--accent))) 100% 0 / 1px 46% no-repeat,
    linear-gradient(var(--fb-ton), var(--fb-ton)) 100% 0 / 1px 100% no-repeat;
}
.plaque > span {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  height: 42px;
  padding: 0 12px;
  color: var(--ton, var(--accent));
  font-family: Oxanium, sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.plaque > span > .txt { flex: 1; text-align: center; }
.plaque svg { width: 1.05rem; flex: none; fill: currentColor; }
.plaque:hover { background: color-mix(in srgb, var(--ton, var(--accent)) 20%, transparent); }

/* L'APLAT PLEIN EST RÉSERVÉ À CE QUI EST CHOISI — ici la porte principale du site. */
.plaque--retenu { background: var(--ton, var(--accent)); }
.plaque--retenu > span { color: var(--fond); }
.plaque--retenu:hover { background: var(--signal-vif); }

/* ÉTEINTE, ELLE PERD LA TEINTE DE SON CORPS ET SON SOL FRANC — c'est ce qui la distingue
   vraiment de la vivante, plus une simple opacité. Et les marques du DEHORS s'éteignent avec
   elle : sinon une plaque morte garderait la marque la plus vive de l'objet. */
.plaque--eteint {
  opacity: 0.4;
  cursor: default;
  pointer-events: none;
  background: color-mix(in srgb, var(--panneau) 70%, transparent);
}
.geste--eteint .geste__barre, .geste--eteint .geste__crans > i { opacity: 0.3; }
.geste--eteint .geste__idx { opacity: 0.42; }

/* ═══ LA BARRE DE TÊTE ════════════════════════════════════════════════════════════════════ */

.tete {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.2rem;
  padding: 0.6rem var(--marge);
  background: color-mix(in srgb, var(--fond) 92%, transparent);
  backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--structure-vive);
}
/* LA MARQUE EST UNE PLANCHE, DONC ELLE SE DIMENSIONNE PAR SA HAUTEUR et garde son rapport.
   Le lockup livré porte déjà le mot ODYSSEA : le rôle se pose à côté, derrière un filet, et
   non dessous — un texte aligné sous un mot déjà dessiné ne s'aligne jamais tout à fait. */
.marque { display: inline-flex; align-items: center; flex: none; }
.marque__logo { height: 2.05rem; width: auto; flex: none; }
.tete__nav { order: 4; display: flex; width: 100%; gap: 1.4rem; overflow-x: auto; scrollbar-width: none; }
.tete__nav::-webkit-scrollbar { display: none; }
.tete__nav a {
  white-space: nowrap;
  font-family: Oxanium, sans-serif;
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--discret);
  padding-block: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}
.tete__nav a:hover, .tete__nav a[aria-current='page'] { color: var(--encre); border-color: var(--signal); }
.tete__droite { display: flex; align-items: center; gap: 1rem; margin-left: auto; }
/* DANS LA BARRE, LE GESTE PERD SES MARQUES DU DEHORS. Elles vivent à neuf pixels au-dessus du
   bouton et débordent à droite : dans une barre de trois rem et demie, l'index se fait couper par
   le bord et les crans mordent sur le sélecteur de langue. Une barre est du CHROME — ce qui s'y
   presse est une plaque, pas un geste mis en scène. */
.tete__droite .geste__dehors,
.tete__droite .geste__crans,
.tete__droite .geste__equerre { display: none; }
.tete__droite .plaque { --coupe: 10px; }
.tete__droite .plaque > span { height: 2.3rem; padding: 0 0.9rem; font-size: 0.66rem; letter-spacing: 0.16em; }
.geste--large .plaque > span { height: 3rem; padding: 0 1.2rem; }
.geste--large { min-width: 15rem; }

@media (min-width: 62rem) {
  .tete { flex-wrap: nowrap; gap: 1.6rem; }
  .tete__nav { order: 0; width: auto; overflow: visible; }
}

.langues { display: inline-flex; align-items: center; gap: 0.3rem; flex: none; }
.langues a {
  font-family: Oxanium, sans-serif;
  font-weight: 600;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--efface);
  padding: 0.3rem 0.4rem;
  border: 1px solid transparent;
}
.langues a:hover { color: var(--encre); }
.langues a[aria-current='true'] { color: var(--encre); border-color: var(--bord-vif); }

/* ═══ LA PAGE ═════════════════════════════════════════════════════════════════════════════ */

.pont { max-width: var(--large); margin: 0 auto; padding: var(--marge); display: grid; gap: var(--marge); }

.saut {
  position: absolute; top: 0; left: 0; z-index: 100;
  transform: translateY(-140%);
  padding: 0.7rem 1.1rem;
  background: var(--signal); color: var(--sur-action);
  font-family: Oxanium, sans-serif; font-weight: 700; font-size: 0.78rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  transition: transform 160ms var(--sortie);
}
.saut:focus { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition-duration: 0ms !important; animation: none !important; }
}

/* ═══ LE HÉROS — UN MODULE, PAS UNE AFFICHE ═══════════════════════════════════════════════
 *
 * Le mockup le dit clairement : la première surface du site n'est pas une image plein écran
 * avec un titre posé dessus, c'est un PANNEAU DE CONSOLE qui contient une image. La
 * différence n'est pas décorative — un panneau a un cadre, un code, un fil d'Ariane et des
 * relevés en marge, et c'est cela qui fait qu'on regarde un instrument.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.heros { --coupe: 22px; position: relative; overflow: hidden; }
.heros__fond {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url('/p/heros.webp') 68% center / cover no-repeat;
}
/* LE VOILE N'EST PAS UNE COMMODITÉ : sans lui, aucune donnée ne tient sur une illustration.
   Il est deux fois plus opaque à gauche qu'à droite — c'est ce qui laisse la planche
   RESPIRER là où il n'y a pas de texte. */
.heros__voile {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(100deg, #000 0%, color-mix(in srgb, #000 92%, transparent) 30%,
                    color-mix(in srgb, #000 40%, transparent) 64%, color-mix(in srgb, #000 12%, transparent) 100%),
    linear-gradient(180deg, color-mix(in srgb, #000 62%, transparent), transparent 26%,
                    color-mix(in srgb, #000 55%, transparent) 82%, #000 100%);
}
.heros__dedans {
  position: relative;
  z-index: 3;
  display: grid;
  gap: 1.4rem;
  padding: 1rem 1.1rem 1.6rem;
  min-height: min(38rem, 78svh);
  grid-template-rows: auto 1fr;
}
.heros__fil { display: flex; align-items: center; gap: 0.8rem; }
.heros__fil .micro { color: var(--discret); }
.heros__fil .rail__trait { max-width: 9rem; }
.heros__grille { display: grid; gap: 1.6rem; align-items: end; }
@media (min-width: 64rem) { .heros__grille { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); } }

.heros__mot { display: grid; gap: 1.15rem; align-content: end; max-width: 34rem; }
.heros h1 {
  font-family: Oxanium, sans-serif;
  font-weight: 700;
  font-size: clamp(2.15rem, 5.4vw, 4.15rem);
  letter-spacing: -0.005em;
  line-height: 0.98;
  text-transform: uppercase;
}
/* LA HACHURE SÉPARE LE TITRE DE L'ARGUMENT. Un filet plein ferait une règle de document ;
   une hachure oblique appartient au dessin technique, donc à la console. */
.heros__hachure { height: 9px; opacity: 0.5;
  background: repeating-linear-gradient(45deg, var(--faible) 0 1px, transparent 1px 6px); }
.heros__pitch { color: var(--discret); font-size: clamp(0.95rem, 1.15vw, 1.06rem); line-height: 1.7; max-width: 40ch; }
.heros__pitch b { color: var(--encre); font-weight: 600; }
.heros__portes { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 0.3rem; }

/* LES RELEVÉS EN MARGE — ils flottent sur la planche, reliés à ce qu'ils nomment. */
.releves { display: grid; gap: 0.7rem; justify-items: end; align-content: end; }
.releve { --coupe: 10px; width: min(15rem, 100%); }
.releve .cadre__corps { padding: 0.55rem 0.7rem 0.7rem; }
.ligne { display: flex; align-items: center; gap: 0.6rem; padding: 0.16rem 0; }
.ligne > span:first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ligne > b { font-weight: 700; font-size: 0.78rem; letter-spacing: 0.02em; }
.ligne--ton > b { color: var(--ton); }

/* ═══ LA BANDE DE FAITS ═══════════════════════════════════════════════════════════════════
 *
 * C'est la pièce la plus importante du site, et c'est là que le mockup se corrige tout seul :
 * il y montrait le relevé d'une PARTIE FICTIVE — « niveau d'empire 13 », « 83 / 143 systèmes ».
 * Or le dépôt a déjà tranché ce point une fois, en retirant les chiffres des tuiles du menu
 * parce qu'AUCUN N'ÉTAIT VRAI. La bande garde donc sa forme et change de contenu : ce sont
 * les faits du JEU, comptés dans le catalogue à la construction.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.faits { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 46rem) { .faits { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 68rem) { .faits { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.fait { padding: 0.95rem 1rem 1.05rem; display: grid; gap: 0.3rem; box-shadow: inset 1px 0 0 var(--structure); }
.fait:first-child { box-shadow: none; }
.fait__valeur { font-weight: 600; font-size: clamp(1.3rem, 2vw, 1.72rem); line-height: 1; letter-spacing: 0.01em; color: var(--encre); }
.fait--signal .fait__valeur { color: var(--signal); }

/* ═══ LES QUATRE MODULES ══════════════════════════════════════════════════════════════════ */

.modules { display: grid; gap: var(--marge); }
@media (min-width: 44rem) { .modules { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 74rem) { .modules { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.module { --coupe: 15px; display: flex; flex-direction: column; }
.module__vue { position: relative; height: 11rem; overflow: hidden; flex: none; }
.module__vue img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--sortie); }
.module:hover .module__vue img { transform: scale(1.04); }
.module__vue::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, color-mix(in srgb, #000 18%, transparent), color-mix(in srgb, var(--panneau) 92%, transparent));
}
.module .cadre__corps { flex: 1; display: grid; gap: 0.5rem; align-content: start; }
.module__claim { font-weight: 700; font-size: 1.02rem; letter-spacing: 0.01em; }
.module__body { color: var(--discret); font-size: 0.88rem; line-height: 1.62; }
.module__verbe {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: 0.55rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--structure);
  color: var(--signal);
}
.module__verbe span {
  font-family: Oxanium, sans-serif;
  font-weight: 700;
  font-size: 0.76rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.module__verbe svg { width: 1rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; }
.module:hover .module__verbe { color: var(--signal-vif); }

/* ═══ LA CLÔTURE ET LE PIED ═══════════════════════════════════════════════════════════════ */

.cloture { --coupe: 18px; position: relative; overflow: hidden; }
.cloture__dedans { position: relative; z-index: 2; padding: clamp(1.6rem, 4vw, 3.2rem); display: grid; gap: 1.1rem; justify-items: start; }
.cloture h2 { font-weight: 700; font-size: clamp(1.5rem, 3vw, 2.4rem); line-height: 1.1; text-transform: uppercase; max-width: 24ch; }
.cloture p { color: var(--discret); max-width: 46ch; line-height: 1.7; }
.cloture__astre {
  position: absolute; right: -14%; top: -46%; z-index: 1;
  width: min(38vw, 27rem); opacity: 0.3; border-radius: 50%;
  filter: saturate(0.7) contrast(1.05);
  mask-image: radial-gradient(circle at 50% 50%, #000 34%, transparent 68%);
}

.pied { border-top: 1px solid var(--structure-vive); padding: 1.3rem var(--marge) 2rem; }
.pied__pont { max-width: var(--large); margin: 0 auto; display: grid; gap: 1rem; }
.pied__rang { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; }
.pied__liens { display: flex; flex-wrap: wrap; gap: 1.1rem; }
.pied__liens a {
  font-family: Oxanium, sans-serif; font-weight: 500; font-size: 0.78rem;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--discret);
}
.pied__liens a:hover { color: var(--encre); }

/* ═══ LES PAGES DE FOND ═══════════════════════════════════════════════════════════════════ */

/* UN GESTE NE S'ÉTIRE PAS. Dans une grille, il prenait toute la largeur du panneau : un bouton
   large comme un écran ne ressemble plus à un bouton, il ressemble à une barre. */
.entete__corps { display: grid; gap: 1rem; padding: 1.3rem 1.2rem 1.5rem; justify-items: start; }
.entete__corps > .geste { justify-self: start; }
.entete h1 {
  font-weight: 700;
  font-size: clamp(1.7rem, 3.4vw, 2.9rem);
  line-height: 1.05;
  text-transform: uppercase;
  max-width: 24ch;
}
.entete__pitch { max-width: 62ch; font-size: 0.97rem; }
.pont__suite { display: flex; justify-content: flex-start; }

.citation {
  color: var(--encre);
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  font-style: italic;
  line-height: 1.6;
  max-width: 40ch;
  padding-left: 0.9rem;
  border-left: 2px solid var(--signal);
}

.regles { display: grid; gap: var(--marge); }
@media (min-width: 52rem) { .regles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 82rem) { .regles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.regle { --coupe: 13px; }
.regle .cadre__nom { color: var(--signal); }

/* LA FICHE D'UN PEUPLE — un panneau, le portrait à gauche, le récit à droite. */
.fiche { --coupe: 18px; }
.fiche__grille { display: grid; gap: 0; }
@media (min-width: 58rem) { .fiche__grille { grid-template-columns: minmax(14rem, 22rem) minmax(0, 1fr); } }
.fiche__portrait { position: relative; overflow: hidden; }
.fiche__portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }
.fiche__mot { padding: 1.2rem 1.2rem 1.5rem; display: grid; gap: 0.85rem; align-content: start; }
.fiche__accroche {
  color: var(--peuple);
  font-size: clamp(1.02rem, 1.4vw, 1.2rem);
  font-style: italic;
  line-height: 1.55;
  max-width: 42ch;
}
.fiche__resume { color: var(--encre); font-size: 1rem; line-height: 1.68; max-width: 56ch; }
.definitions { display: grid; gap: 0.9rem; margin-top: 0.4rem; }
.definitions > div { padding-left: 0.85rem; box-shadow: inset 1px 0 0 var(--structure-vive); }
.definitions dt { color: var(--accent); }
.definitions dd { margin-top: 0.25rem; color: var(--discret); font-size: 0.9rem; line-height: 1.62; }

/* LA GRILLE DES COQUES — des silhouettes et leur nom. Aucune fiche : le détail est dans le jeu. */
.coques { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 1px; }
.coque {
  display: grid;
  gap: 0.5rem;
  justify-items: center;
  padding: 0.8rem 0.6rem 0.9rem;
  box-shadow: inset 0 0 0 1px var(--structure);
}
.coque img { width: 100%; height: auto; }
.coque .etiq { text-align: center; font-size: 0.72rem; color: var(--encre); }

.ressources { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: 1px; margin-top: 0.4rem; }
.ressource {
  padding: 0.9rem 0.8rem;
  box-shadow: inset 0 0 0 1px var(--structure);
  border-top: 2px solid var(--ton);
}
.ressource .etiq { color: var(--ton); }

/* LA PAGE D'ERREUR */
.perdu { min-height: 100svh; display: grid; align-content: center; padding: var(--marge); }
.perdu__pont { max-width: 46rem; margin: 0 auto; display: grid; gap: 1.1rem; justify-items: start; }
.perdu h1 { font-weight: 700; font-size: clamp(1.6rem, 3.4vw, 2.6rem); text-transform: uppercase; }
.perdu p { color: var(--discret); }
.perdu__portes { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 0.6rem; }
.marque--seule { width: 4.2rem; height: 4.2rem; }

/* LE RÉCIT D'UN PEUPLE SE MESURE EN CARACTÈRES PAR LIGNE, PAS EN PIXELS. Étalé sur toute la
   largeur d'un panneau il faisait cent-dix signes par ligne : l'œil perd la ligne suivante. */
.fiche__mot .module__body { max-width: 74ch; }

/* ═══ LES TROIS PROMESSES ═════════════════════════════════════════════════════════════════
 *
 * Aucune image : ce qui se PROMET se lit. Une illustration derrière une promesse la transforme
 * en légende de photo, et le visiteur regarde l'image au lieu de lire ce qu'on lui offre.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.promesses { display: grid; gap: var(--marge); }
@media (min-width: 52rem) { .promesses { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.promesse { --coupe: 13px; }
.promesse .cadre__nom { color: var(--signal); }
.promesse .cadre__corps { padding: 1.1rem 1.1rem 1.3rem; }
.promesse .module__body { font-size: 0.95rem; line-height: 1.7; }

.modules--trois { grid-template-columns: repeat(1, minmax(0, 1fr)); }
@media (min-width: 52rem) { .modules--trois { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.faits--trois { grid-template-columns: repeat(1, minmax(0, 1fr)); }
@media (min-width: 40rem) { .faits--trois { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* L'ÉCHELLE N'A PLUS QUE TROIS NOMBRES : ils ont donc le droit d'être grands. */
.faits--trois .fait__valeur { font-size: clamp(1.7rem, 3.4vw, 2.7rem); }
.faits--trois .fait { padding: 1.3rem 1.2rem 1.4rem; }

/* Les peuples vivent dans un panneau, donc leurs cartes n'ont plus besoin du leur. */
.cadre__corps > .peuples { margin-top: 1.1rem; }
.cadre__corps > .peuples .peuple { --coupe: 11px; }

/* ═══ LES CARTES DE PEUPLE ════════════════════════════════════════════════════════════════
 *
 * ⚠️ CES RÈGLES AVAIENT DISPARU dans la réécriture de la feuille du 31 août 2026, et le panneau
 * des peuples est sorti VIDE : les cartes sont des `<a>`, donc en ligne par défaut, et un
 * `clip-path` posé sur une boîte en ligne rogne son contenu au lieu de la découper. Un composant
 * qui n'a plus de règles ne rend pas « sans style », il ne rend pas du tout.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.peuples { display: grid; gap: var(--marge); }
@media (min-width: 44rem) { .peuples { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 74rem) { .peuples { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.peuple { display: flex; flex-direction: column; }
.peuple__portrait { position: relative; aspect-ratio: 4 / 5; overflow: hidden; flex: none; }
.peuple__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 20%;
  transition: transform 600ms var(--sortie);
}
.peuple:hover .peuple__portrait img { transform: scale(1.04); }
/* La planche s'éteint vers le bas pour que la barre de titre s'y pose au lieu de la couper. */
.peuple__portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, color-mix(in srgb, #000 12%, transparent),
              color-mix(in srgb, var(--panneau) 92%, transparent));
}
.peuple .cadre__corps { flex: 1; display: grid; gap: 0.5rem; align-content: start; }
.peuple__accroche {
  color: var(--peuple);
  font-size: 0.95rem;
  font-style: italic;
  line-height: 1.55;
}

/* Le récit d'un peuple respire : ses paragraphes viennent du catalogue, ils ne sont pas décoratifs. */
.fiche__recit { display: grid; gap: 0.85rem; max-width: 74ch; }

/* ═══ LA CARTE DU SYSTÈME ═════════════════════════════════════════════════════════════════
 *
 * Elle remplace le bandeau de démonstration : cinq tuiles racontaient qu'il se passe des
 * choses, celle-ci le montre. Le canvas porte le dessin du jeu ; la fiche flotte dessus, dans
 * un panneau visé, et répond au clic.
 * ═════════════════════════════════════════════════════════════════════════════════════════ */

.carte {
  position: relative;
  margin-top: 1.1rem;
  /* LE CIEL EST NOIR, PAS TRANSPARENT : le rendu éteint ses ombres sur la couleur qui les
     porte, et un fond translucide leur rendrait un bord. C'est la leçon de `theme.ts`. */
  background: var(--fond);
  box-shadow: inset 0 0 0 1px var(--structure);
  overflow: hidden;
}
.carte__toile {
  display: block;
  width: 100%;
  /* Une carte doit être PLUS VASTE QUE HAUTE pour qu'on lise des distances, et rester
     jouable au doigt : deux tiers de large sur petit écran, deux sur cinq sur grand. */
  aspect-ratio: 3 / 4;
  touch-action: manipulation;
}
/* ⚠️ ON S'EST ARRÊTÉ À 16/10 SUR GRAND ÉCRAN, ET UN 21/9 A ÉTÉ ESSAYÉ AVANT. Un système est un
   DISQUE : le cadrage tient sur la hauteur, donc plus la toile est large, plus il reste de noir
   à gauche et à droite. En 21/9 le système occupait le tiers central. */
@media (min-width: 46rem) { .carte__toile { aspect-ratio: 16 / 10; } }
.carte__toile { cursor: grab; }

.carte__fiche {
  --coupe: 11px;
  position: absolute;
  left: 0.7rem;
  bottom: 0.7rem;
  width: min(15rem, calc(100% - 1.4rem));
  pointer-events: none;
}
.carte__fiche .cadre__corps { padding: 0.7rem 0.8rem 0.8rem; display: grid; gap: 0.25rem; }
