/* Site Kepler.
   ---------------------------------------------------------------------------
   La palette est relevée sur le logo, pas inventée à côté : marine profond,
   bleu acier de la planète, et le turquoise de l'anneau comme seul accent.
   Un site qui ne ressemble pas à sa propre marque se remarque tout de suite.

   Le turquoise nous sépare aussi de la concurrence, qui est à l'ambre sur
   noir. Deux sites de bots OGame avec la même couleur d'accent, ce serait
   nous qui aurions l'air d'être la copie.

   Un seul accent, et il ne sert qu'à désigner : l'action à faire, la page où
   l'on est, la formule mise en avant. Dès qu'on en met partout, il ne désigne
   plus rien. */

/* Space Grotesk, hébergée ici et pas chez Google.
   ---------------------------------------------------------------------------
   Une page qui appelle un serveur tiers pour s'afficher lui raconte qui la
   visite, et tombe avec lui. Sur un site qui vend de la discrétion, ce
   serait mal venu.

   Police variable de 400 à 700 : un fichier par sous-ensemble, et non un par
   graisse. Latin et latin étendu seulement - le grec, le russe et le bulgare
   n'ont pas de dessin dans cette police. « unicode-range » les renvoie tout
   seuls à la grotesque du système, caractère par caractère : rien à prévoir
   de plus, et aucune requête inutile pour les autres langues.

   Licence SIL Open Font 1.1, texte complet dans polices/OFL.txt. */
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/polices/space-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/polices/space-grotesk-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Les fonds. Le ciel étoilé est peint derrière, par ciel.js ; ce dégradé
     est ce qu'on voit au travers. */
  --bg: #060B18;
  --bg-haut: #0B1730;

  /* Les surfaces posées sur le ciel : translucides, pour que les étoiles
     restent là-dessous. Une carte opaque ferait un trou dans le fond. */
  --panel: rgba(13, 25, 45, .74);
  --panel-plein: #0D192D;
  --panel-head: rgba(20, 37, 64, .82);
  --border: #1D3155;
  --champ: #0A1526;

  --text: #C4D2E6;
  --text-strong: #F1F6FC;
  --muted: #7D90AC;

  /* L'anneau du logo. */
  --accent: #24C0C0;
  --accent-clair: #55DEDE;
  --accent-sombre: #128A8F;
  /* La planète du logo : une profondeur, pas un accent. */
  --acier: #0C5478;

  --green: #23b07a;
  --red: #d9534f;

  /* Les titres. Space Grotesk s'il est déposé dans le dossier des polices,
     sinon la meilleure grotesque du système - la mise en page ne change pas,
     seul le dessin des lettres. */
  --police-titre: "Space Grotesk", "Segoe UI Variable Display", "Segoe UI",
    -apple-system, Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  color: var(--text);
  font: 16px/1.65 -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* Le dégradé s'arrête vite : plus bas, c'est le marine plein, sinon la
     page a l'air de s'éclaircir sans raison à mesure qu'on descend. */
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(36, 192, 192, .10), transparent 60%),
    linear-gradient(180deg, var(--bg-haut) 0, var(--bg) 620px);
  background-color: var(--bg);
  background-attachment: fixed;
}

/* Le ciel, derrière tout le reste. Il ne prend aucun clic : c'est un fond,
   pas une surface. */
#ciel {
  position: fixed;
  inset: 0;
  /* La largeur et la hauteur sont posées, pas déduites de « inset ».
     Un canevas est un élément remplacé : en position fixe et en largeur
     automatique, le navigateur prend sa taille intrinsèque - l'attribut
     « width », trois cents par défaut - et ignore le « right ». Le ciel se
     réduisait alors à un timbre de 300 sur 150 dans un coin, invisible
     derrière la page. En position fixe, 100 % vaut la fenêtre, sans compter
     la barre de défilement comme le ferait 100vw. */
  width: 100%;
  height: 100%;
  z-index: -1;
  display: block;
  pointer-events: none;
}

a { color: var(--accent-clair); text-decoration: none; }
a:hover { text-decoration: underline; }

/* La barre reste en haut et laisse voir le ciel au travers. Le flou n'est pas
   un effet : sans lui, les étoiles passent derrière le texte du menu et le
   rendent illisible par endroits. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(6, 11, 24, .78);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.topbar .inner {
  display: flex; align-items: center; gap: 18px;
  max-width: 1400px; margin: 0 auto; padding: 0 28px; height: 56px;
}
.marque {
  font-family: var(--police-titre);
  font-size: 18px; font-weight: 700; letter-spacing: .01em;
  color: var(--text-strong);
  display: inline-flex; align-items: center; gap: 8px;
}
/* La marque est décorative : le nom est écrit juste à côté, en texte. Un alt
   vide et aria-hidden évitent qu'un lecteur d'écran l'annonce deux fois. */
.marque img { display: block; }
.spacer { flex: 1; }

main { max-width: 1400px; margin: 0 auto; padding: 26px 28px 72px; }

h1, h2, h3 { font-family: var(--police-titre); }
h1 {
  font-size: 30px; font-weight: 600; margin: 0 0 20px;
  color: var(--text-strong); letter-spacing: -.01em;
}
h2 { font-size: 20px; font-weight: 600; margin: 0 0 10px; color: var(--text-strong); }

.panel {
  background: var(--panel);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 12px; margin-bottom: 18px;
  overflow: hidden;
}
.panel-head {
  background: var(--panel-head); padding: 12px 16px;
  color: var(--text-strong); border-bottom: 1px solid var(--border);
  font-family: var(--police-titre); font-weight: 600;
}
.panel-body { padding: 18px; }
/* Le texte garde une longueur de ligne lisible meme si le panneau
   s'etale : au-dela d'environ quatre-vingts caracteres, on saute des
   lignes en revenant a gauche. */
.panel-body p, .panel-body li { max-width: 82ch; }

.muted { color: var(--muted); }
.petit { font-size: 13px; }

input[type=text], input[type=password], input[type=number], select {
  padding: 8px 11px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--champ); color: var(--text); font-size: 15px; font-family: inherit;
}
input:focus, select:focus {
  outline: none;
  border-color: var(--accent-sombre);
  box-shadow: 0 0 0 3px rgba(36, 192, 192, .16);
}
label { display: block; margin-bottom: 4px; }

button {
  border: 1px solid var(--border); border-radius: 8px;
  color: var(--text-strong); background: rgba(28, 48, 80, .7);
  padding: 10px 19px; font-size: 15px; cursor: pointer;
  font-family: var(--police-titre); font-weight: 500;
  transition: border-color .15s, box-shadow .15s, transform .12s;
}
button:hover { border-color: var(--accent-sombre); }
button:active { transform: translateY(1px); }

/* L'action principale est la seule chose turquoise plein sur son écran :
   c'est ce qui la rend principale. Texte sombre dessus, parce qu'un blanc sur
   turquoise ne passe aucun seuil de lisibilité. */
button.principal {
  background: linear-gradient(180deg, var(--accent-clair), var(--accent-sombre));
  border-color: transparent;
  color: #04141C;
  font-weight: 700;
}
button.principal:hover {
  box-shadow: 0 0 0 3px rgba(36, 192, 192, .18), 0 6px 22px rgba(36, 192, 192, .18);
}
button.danger { background: var(--red); border-color: transparent; color: #fff; }
button:disabled { opacity: .45; cursor: default; box-shadow: none; }
button:disabled:hover { border-color: var(--border); }

table { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--border); }
th { color: var(--text-strong); font-weight: 600; }

/* Tableau des serveurs : la colonne des actions porte des boutons, elle ne
   doit pas s'étirer, et les cellules restent alignées en haut pour que la
   note d'une ligne suspendue ne décale pas le reste. */
table.serveurs td, table.serveurs th { vertical-align: top; }
table.serveurs td:last-child { width: 1%; white-space: nowrap; }
table.serveurs .rang { gap: 6px; align-items: center; }
table.serveurs code.cle { display: inline-block; margin-top: 4px; }

/* La clé d'activation se recopie dans un autre logiciel : elle doit être
   lisible caractère par caractère, sans confusion possible. */
.cle {
  font-family: Consolas, "Liberation Mono", monospace;
  font-size: 16px; letter-spacing: 1px;
  background: var(--champ); border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 13px; color: var(--text-strong); user-select: all;
  display: inline-block;
}

.erreur { color: #e06c6c; min-height: 20px; margin: 8px 0; }
.ok { color: var(--green); }

.centre { max-width: 380px; margin: 60px auto; }
.rang { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.champ { margin-bottom: 12px; }

.badge {
  display: inline-block; padding: 2px 8px; border-radius: 10px;
  font-size: 12px; background: rgba(29, 49, 85, .9); color: var(--text);
}
.badge.vert { background: #1d5c45; }
/* Gris : rien ne tourne, et rien ne va mal non plus. Le rouge criait une
   panne là où il n'y a qu'un abonnement fini. */
.badge.gris { background: #2b3444; color: #9aa4b2; }

/* Texte vert, pour un avis favorable hors badge : le nom d'adresse libre. */
.vert { color: #6cc49a; }

/* Texte orange, hors badge : ce qui appelle un regard sans être une panne -
   une adresse payée sur laquelle aucun robot ne tourne. Le rouge est pris par
   ce qui casse, et le gris se lirait comme une absence d'information. */
.orange { color: #d3a35c; }

/* Le total d'une commande : c'est le chiffre que le client cherche des yeux,
   il doit se lire sans effort au milieu des menus déroulants. */
.montant-total { color: #6cc49a; font-size: 24px; font-weight: 600; }
.badge.rouge { background: #6b2f2d; }
/* L'essai : ni bon ni mauvais, mais à distinguer d'un coup d'oeil d'une
   licence achetée - elles ont sinon exactement la même carte. */
.badge.orange { background: #6b5730; }

/* Les deux offres. Ni vert ni rouge : ces pastilles ne portent aucun jugement,
   elles nomment. Le vert et le rouge sont pris par l'état - activée, révoquée -
   et les mélanger ferait lire « hébergé » comme une bonne nouvelle.

   Assez soutenues pour se repérer d'un coup d'oeil : un compte neuf reçoit ses
   deux licences, et c'est cette pastille qui dit laquelle on regarde.

   Le bleu était trop sombre : posé sur l'en-tête de panneau, lui-même bleu
   nuit, il se fondait dedans quand le violet ressortait. Un bleu ciel s'en
   détache, et son texte est éclairci pour rester lisible dessus. */
.badge.bleu { background: #2C7FBF; color: #EAF4FD; }
.badge.violet { background: #4f3a7a; }

/* ---------- menu et pied ---------- */

.lien {
  color: var(--muted); padding: 4px 2px; position: relative;
  font-size: 15px;
}
.lien:hover { color: var(--text-strong); text-decoration: none; }
/* La page où l'on est se marque d'un trait turquoise sous le mot, pas d'un
   gras : le gras déplace les liens voisins à chaque changement de page. */
.lien.actif { color: var(--text-strong); }
.lien.actif::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -6px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

/* Le resume servi dans le HTML, avant que le script ne prenne la main.

   Il ne se voit qu'un instant, ou pas du tout. Mais si le script echoue - un
   reseau qui coupe, un bloqueur trop zele -, c'est tout ce que le visiteur
   aura : autant qu'il soit lisible plutot que colle en haut a gauche. */
.resume-statique {
  max-width: 70ch;
  margin: 60px auto;
  padding: 0 24px;
  color: var(--muted);
  font-size: 17px;
  line-height: 1.7;
}

/* Le titre du résumé, que le JavaScript remplace aussitôt dessiné.

   Il est là pour les moteurs, et pour le visiteur dont le script a échoué :
   sans habillage il arriverait en taille de navigateur par défaut, énorme
   au-dessus d'un paragraphe gris. */
.resume-statique h1 {
  margin: 0 0 16px;
  font-size: 28px;
  line-height: 1.3;
  color: var(--text);
}

/* ---------- onglets d'une page ---------- */

/* La rangee d'onglets de la page du compte. Le trait turquoise sous l'onglet
   ouvert est celui du menu du haut : c'est la meme idee - ou l'on est - et
   deux facons de la dire auraient fait deux langages a apprendre.

   Sur un telephone, la rangee defile lateralement plutot que de se replier en
   liste deroulante : elle ne tronque aucun libelle, ne demande aucun script,
   et un doigt la fait glisser sans rien ouvrir. */
.onglets {
  display: flex;
  gap: 22px;
  border-bottom: 1px solid var(--border);
  margin: 0 0 20px;
  overflow-x: auto;
  scrollbar-width: none;
}
.onglets::-webkit-scrollbar { display: none; }
.onglet {
  position: relative;
  color: var(--muted);
  padding: 10px 2px 12px;
  font-size: 15px;
  white-space: nowrap;
  flex: 0 0 auto;
}
.onglet:hover { color: var(--text-strong); text-decoration: none; }
.onglet.actif { color: var(--text-strong); }
.onglet.actif::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

.pied { border-top: 1px solid var(--border); margin-top: 40px; }
/* Le pied passe à la ligne. Il ne le faisait pas : à 390 pixels, « contact@
   keplerbot.net » et les conditions de vente le poussaient à 638 de large, et
   tout le site défilait de côté sur téléphone (mesuré le 02/10/2026, en
   production, sur /de). */
.pied .inner {
  display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap;
  max-width: 1400px; margin: 0 auto; padding: 18px 28px;
}

/* La rangee des langues, sous le reste du pied.

   Elle porte les seuls liens cliquables vers les traductions : sans eux, aucun
   chemin ne mene aux pages des autres langues, ni pour un moteur ni pour un
   visiteur dont le script n'a pas demarre. Discrete, mais presente partout. */
.pied-langues {
  padding-top: 0; gap: 14px; flex-wrap: wrap;
  border-top: 1px solid var(--border); margin-top: 0; padding-bottom: 18px;
}
.pied-langues a { color: var(--muted); }
.pied-langues a:hover { color: var(--text); }

/* ---------- page d'accueil ---------- */

/* La première chose que voit un visiteur : ce que fait le produit, en une
   phrase, et de quoi agir tout de suite. Le reste peut attendre le défilement. */
/* Deux anneaux inclinés derrière le titre, repris du logo, et une lueur au
   centre. C'est le seul geste graphique de la page : il est en haut, il est
   grand, et il ne se répète nulle part ailleurs. Un motif qu'on revoit à
   chaque section cesse d'être une signature et devient un papier peint. */
.hero {
  position: relative;
  overflow: hidden;
  padding: 84px 0 64px;
  /* La lueur s'éteint avant d'atteindre les bords du bloc.
     Débordante, elle était tranchée net par « overflow: hidden » : on
     voyait alors le rectangle du hero se détacher du fond, à gauche et
     en haut. Rayon et centre sont tous deux en pourcentage de la même
     boîte, donc le calcul tient à n'importe quelle taille. */
  background: radial-gradient(46% 60% at 34% 45%, rgba(36, 192, 192, .085), transparent 72%);
}
.hero::before, .hero::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}
/* L'anneau turquoise, celui du logo. L'aplatissement vient d'un scaleY après
   la rotation : les bords haut et bas s'amincissent avec, ce qui donne
   exactement le trait d'une orbite vue de biais. */
.hero::before {
  top: -186px; right: -120px;
  width: 780px; height: 780px;
  border: 1px solid rgba(36, 192, 192, .26);
  transform: rotate(-18deg) scaleY(.34);
}
/* Le second, bleu acier : la profondeur. */
.hero::after {
  top: -84px; right: 30px;
  width: 500px; height: 500px;
  border: 1px solid rgba(12, 84, 120, .55);
  transform: rotate(-18deg) scaleY(.34);
}
.hero > * { position: relative; z-index: 1; }

.hero h1 {
  font-size: clamp(30px, 4.4vw, 62px);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.026em;
  margin-bottom: 18px;
  max-width: 16ch;
  /* Du blanc vers le turquoise pâle : la marque traverse le titre sans qu'on
     ait à découper la phrase, ce qui la rendrait intraduisible. */
  background: linear-gradient(102deg, var(--text-strong) 30%, #9BE7E7 92%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* En contraste forcé, le système impose ses couleurs et le dégradé disparaît :
   il ne resterait qu'un titre transparent, c'est-à-dire pas de titre. */
@media (forced-colors: active) {
  .hero h1 { background: none; color: CanvasText; }
}

.accroche { font-size: 20px; color: var(--muted); max-width: 660px; margin: 0 0 28px; }

button.grand { padding: 14px 28px; font-size: 17px; }

/* La courbe de transit : une ligne plate, un creux, la ligne reprend.
   C'est la mesure qui a donné son nom au télescope Kepler - et c'est aussi
   ce que font les outils du bot, remarquer un creux que personne ne regarde.
   Elle sert de séparation, à la place d'un filet. */
.courbe-transit {
  height: 40px;
  margin: 30px 0 6px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1200' height='40' viewBox='0 0 1200 40' preserveAspectRatio='none'%3E%3Cpath d='M0 20 H470 C500 20 505 33 528 33 H672 C695 33 700 20 730 20 H1200' fill='none' stroke='%2324C0C0' stroke-width='1.5' stroke-opacity='.5'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  /* Le dégradé efface les deux bouts : une ligne qui s'arrête net a l'air
     coupée, une ligne qui s'éteint a l'air de continuer. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}

.grille {
  display: grid; gap: 14px; margin-bottom: 18px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.atout {
  background: var(--panel);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 12px; padding: 17px;
  transition: border-color .16s;
}
.atout:hover { border-color: var(--accent-sombre); }
.atout h2 { margin-bottom: 6px; }
.atout h3 { margin: 0 0 6px; font-size: 17px; color: var(--text-strong); }
.atout p { margin: 0; }
.atout p + p { margin-top: 10px; }

/* Les questions de l'accueil (02/10/2026) : la nuit, le risque, où il
   tourne, l'essai. Plus d'air entre deux questions qu'entre deux cartes :
   ce sont des sujets, pas une seule liste. */
.argument { margin: 56px 0 0; }
.argument > .accroche { font-size: 18px; margin: -2px 0 18px; }
.argument .grille { margin-bottom: 0; }
.argument .grille-deux { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 780px) {
  .argument .grille-deux { grid-template-columns: 1fr; }
}
.argument-suite { color: var(--muted); max-width: 72ch; margin: 16px 0 0; }
/* L'essai ferme la page : centré, une seule carte qui ne s'étire pas sur
   toute la largeur, et ses deux boutons dessous. */
.argument-essai { text-align: center; margin-bottom: 20px; }
.argument-essai .atout { max-width: 640px; margin: 0 auto 22px; text-align: left; }
.argument-essai .rang { justify-content: center; }

/* ---------- tarifs ---------- */

.tarif {
  background: var(--panel);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 12px; padding: 20px; display: flex; flex-direction: column; gap: 10px;
}
/* La formule mise en avant se distingue par la bordure, pas par la taille :
   agrandir une carte décale les autres et rend la comparaison pénible. */
.tarif.populaire {
  border-color: var(--accent-sombre);
  box-shadow: 0 0 0 1px rgba(36, 192, 192, .18), 0 10px 40px rgba(36, 192, 192, .07);
}
.montant {
  font-size: 36px; color: var(--text-strong);
  font-family: var(--police-titre); font-weight: 600;
}
.liste { list-style: none; margin: 0; padding: 0; color: var(--muted); }
.liste li { padding: 3px 0; }
.liste li::before { content: "· "; color: var(--accent); }

/* Les notes de version : un texte qu'on lit, pas une liste survolee.
   Le gris des mentions secondaires convient a trois mots dans une carte de
   tarif ; sur dix lignes il fatigue. D'ou la couleur du texte fort, de l'air
   entre les entrees, et le retrait pendu qui aligne les lignes suivantes sur
   la premiere plutot que sous la puce. */
.liste.notes { color: var(--text-strong); }
.liste.notes li { padding: 0 0 14px 16px; text-indent: -16px; line-height: 1.65; }
.liste.notes li:last-child { padding-bottom: 0; }
.tarif a { margin-top: auto; }

/* Le curseur du nombre de robots.
   Dessine a la main : celui du navigateur arrive en bleu systeme sur un fond
   sombre, et c est la seule commande de la page de vente. */
/* Le nombre de robots, dans la carte : lisible sans voler la vedette au prix,
   qui reste le plus gros caractere de la carte. */
.compte-robots {
  font-family: var(--police-titre); font-weight: 600;
  font-size: 21px; color: var(--text-strong);
}
.curseur {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 4px; margin: 12px 0 6px;
  border-radius: 2px; background: var(--border); outline: none; cursor: pointer;
}
.curseur::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent); border: none; cursor: pointer;
}
.curseur::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent); border: none; cursor: pointer;
}
.rond {
  width: 32px; height: 32px; flex: none; padding: 0;
  border-radius: 50%; font-size: 18px; line-height: 1;
}
.rond:disabled { opacity: .35; cursor: default; }

/* ---------- étapes ---------- */

.etape { display: flex; gap: 12px; padding: 8px 0; }
.etape + .etape { border-top: 1px solid var(--border); }
.etape .num {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: var(--accent); color: #04141C; font-weight: 700;
  display: flex; align-items: center; justify-content: center; font-size: 13px;
}

/* Un tableau d'administration déborde vite : le faire défiler seul évite que
   toute la page parte en largeur. */
.large { overflow-x: auto; }

/* Le sélecteur de langue, dans la barre du haut.
   Discret : c'est un réglage qu'on cherche une fois, pas un lien du menu. */
.langue {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: inherit;
  font: inherit;
  font-size: 14px;
  padding: 5px 7px;
  margin-left: 12px;
  cursor: pointer;
}
.langue:hover { border-color: var(--muted); }
/* Les options héritent du fond du système, pas de celui de la barre : sans
   cette règle, elles sortaient en texte clair sur fond clair. */
.langue option { background: var(--panel-plein); color: var(--text); }

/* ------------------------------------------------- fiches de fonctionnalité

   Deux colonnes sur un écran large : la capture d'un côté, le texte de
   l'autre, et l'ordre s'inverse d'une fiche à la suivante pour que la page ne
   défile pas comme une liste.

   Sur un téléphone, tout se replie en une colonne et l'image passe devant -
   c'est elle qu'on regarde d'abord. */
.fiche {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 46px;
  align-items: center;
  margin: 34px 0;
}
.fiche:nth-child(odd) .capture { order: 2; }

.capture {
  border: 1px solid var(--border);
  border-radius: 12px;
  transition: border-color .16s, box-shadow .16s;
  overflow: hidden;
  background: var(--panel);
  min-height: 190px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.capture img { width: 100%; display: block; }

/* Le cadre d'attente nomme le fichier manquant. Il occupe la même place que
   l'image, pour que la page ne bouge pas quand la capture arrive. */
.capture-vide {
  padding: 40px 16px;
  text-align: center;
  color: var(--muted);
}
.capture-vide code {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  opacity: .75;
}

/* La colonne s'élargit avec la page, le texte non.
   La capture avait besoin de la largeur - c'était tout le problème - mais une
   ligne de quatre-vingt-six caractères se relit mal : en revenant à gauche,
   l'oeil retombe une ligne trop bas. Le titre, lui, garde la pleine largeur :
   il tient sur une ligne. */
.fiche-texte p, .fiche-texte li { max-width: 72ch; }

.fiche-texte h2 { margin-bottom: 8px; }
.accroche-petite { margin: 0 0 12px; }
.puces { margin: 0; padding-left: 18px; color: var(--muted); }
.puces li { margin-bottom: 7px; }

/* ----------------------------------------------------- la vitrine d'accueil

   Les quatre titres à gauche, l'écran de celui qu'on désigne à droite. Le
   tout tient sur une hauteur d'écran : on sait ce que fait le logiciel sans
   rien dérouler.

   L'image est un aperçu, pas une pièce à conviction : le clic l'ouvre en
   grand pour qui veut y lire les chiffres. C'est ce qui permet de la garder
   à cette taille sans rien perdre. */
.vitrine {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 42px;
  align-items: start;
  margin: 30px 0 0;
}

.fonction-liste { display: flex; flex-direction: column; gap: 4px; }

.fonction-ligne {
  display: block;
  text-align: left;
  font: inherit;
  background: none;
  border: 0;
  /* Un filet à gauche plutôt qu'un cadre : quatre cartes empilées feraient
     une liste lourde, alors qu'il ne s'agit que de désigner laquelle on
     regarde. */
  border-left: 2px solid var(--border);
  border-radius: 0 10px 10px 0;
  padding: 14px 18px;
  cursor: pointer;
  transition: background .16s, border-color .16s;
}
.fonction-ligne:hover, .fonction-ligne.actif {
  background: rgba(20, 37, 64, .55);
  border-left-color: var(--accent);
}
.fonction-ligne:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.fonction-titre {
  display: block;
  font-family: var(--police-titre);
  font-size: 19px;
  font-weight: 600;
  color: var(--muted);
  transition: color .16s;
}
.fonction-ligne:hover .fonction-titre,
.fonction-ligne.actif .fonction-titre { color: var(--text-strong); }
.fonction-phrase { display: block; margin-top: 5px; color: var(--muted); font-size: 15px; }

/* Le cadre garde la même hauteur d'une fonction à l'autre.
   Sans ça, passer de l'écran de défense - presque carré - au bandeau de
   pillage ferait sauter la page de trois cents pixels à chaque survol. */
.vitrine-image .capture {
  min-height: 0;
  height: 470px;
  padding: 14px;
  background: rgba(11, 22, 41, .72);
}
.vitrine-image .capture img {
  width: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.vitrine-legende { margin-top: 9px; text-align: right; }

@media (max-width: 900px) {
  .vitrine { grid-template-columns: 1fr; gap: 18px; }
  /* L'aperçu passe au-dessus : sur un téléphone, une image placée sous la
     liste serait hors de l'écran au moment où on appuie sur un titre. */
  .vitrine-colonne { order: -1; }
  .vitrine-image .capture { height: 240px; }
  .vitrine-legende { text-align: left; }
}

/* Une alerte d'outil : l'image est petite, le texte tient à côté.
   Une notification fait quelques lignes ; l'étirer sur une demi-page la
   ferait passer pour un écran de réglages, ce qu'elle n'est pas. */
/* La colonne prend la largeur de l'image, pas une largeur fixe : une
   notification de 342 pixels dans un cadre de 560 laissait un grand
   rectangle vide bordé à côté du texte. */
.fiche-alerte { grid-template-columns: minmax(0, max-content) 1fr; gap: 32px; margin: 26px 0; }
.fiche-alerte .capture { min-height: 0; align-items: flex-start; padding: 10px; max-width: 560px; }
/* Une notification est une petite image. L'etirer sur toute la largeur la
   rendrait floue : on la laisse a sa taille, quitte a ce qu'elle soit plus
   petite que le cadre. */
.fiche-alerte .capture img { width: auto; max-width: 100%; }
.fiche-alerte .fiche-texte h3 { margin-bottom: 7px; font-size: 19px; }

/* Jamais inversée : les trois alertes se lisent en colonne, image à gauche,
   et alterner les côtés donnerait un zigzag sans raison. */
.fiche-alerte:nth-child(odd) .capture { order: 0; }

/* ------------------------------------------------------------------ loupe

   Ramenée à la largeur d'une colonne, une capture du jeu ne se lit plus. Le
   clic la rouvre par-dessus la page, à sa taille d'origine - sans mise à
   l'échelle, puisque c'est la mise à l'échelle qui la rendait illisible. Trop
   grande pour l'écran, elle défile. */
.capture-cliquable { cursor: zoom-in; }
.capture-cliquable:hover {
  border-color: var(--accent-sombre);
  box-shadow: 0 0 0 1px rgba(36, 192, 192, .15);
}
.capture-cliquable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.loupe {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, .82);
  overflow: auto;
  padding: 56px 16px 16px;
  display: grid;
  place-items: center;
  /* « safe » pour que le débordement parte vers le bas et la droite : centrée
     sans lui, une image plus large que l'écran a son bord gauche hors du
     cadre défilant, donc hors d'atteinte. Ignorée par les navigateurs qui ne
     la connaissent pas, qui gardent la ligne précédente. */
  place-items: safe center;
}

.loupe-image {
  display: block;
  /* Sa taille d'origine, et rien d'autre. */
  width: auto;
  height: auto;
  max-width: none;
  border-radius: 6px;
  cursor: default;
}

.loupe-fermer {
  position: fixed;
  top: 12px;
  right: 16px;
  width: 38px;
  height: 38px;
  padding: 0;
  font-size: 22px;
  line-height: 1;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.loupe-fermer:hover { border-color: var(--muted); }

/* La page derrière ne défile plus : deux zones défilantes imbriquées font
   partir la mauvaise sous la molette. */
body.loupe-ouverte { overflow: hidden; }

/* Une fonction de la page « Fonctionnalités ». */
/* L'intitule d'une rubrique, dans le fil des fonctionnalites.
   ---------------------------------------------------------------------------
   Assez gros pour ne pas se confondre avec un titre de fonctionnalite - c'est
   exactement ce qui rendait les six familles d'origine illisibles - et sans
   cadre, pour ne pas redecouper la page en cartes. */
/* Le cadre d'une rubrique, dans le panneau des fonctionnalites.
   ---------------------------------------------------------------------------
   Un cadre plus clair que le panneau qui le porte, et non plus sombre : deux
   niveaux d'encadrement se lisent mieux quand le plus interieur avance vers
   le lecteur au lieu de s'enfoncer. */
.rubrique-bloc {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px 18px;
  background: rgba(255, 255, 255, .02);
}
.rubrique-bloc + .rubrique-bloc { margin-top: 22px; }

.rubrique {
  margin: 0 0 6px;
  padding-bottom: 8px;
  text-align: center;
  font-family: var(--police-titre);
  font-size: 23px;
  color: var(--text-strong);
  /* Un filet plutot qu'un text-decoration : le souligne d'un titre suit les
     jambages des lettres et se colle au texte, alors qu'un filet court sur
     toute la largeur du cadre et separe l'intitule de ce qu'il annonce. */
  border-bottom: 1px solid var(--border);
}
/* Pas de filet sous un intitule : il separe deja. */
.rubrique + .fonction { border-top: 0; padding-top: 8px; }

/* Deux colonnes : le texte a gauche, les captures a droite.
   ---------------------------------------------------------------------------
   Les captures s'empilaient sous chaque texte, et la moitie droite de la page
   restait vide sur toute sa hauteur. Dix-huit fonctionnalites faisaient une
   page deux fois plus haute qu'elle n'avait besoin de l'etre.

   La colonne de droite se dimensionne sur son contenu, sans depasser la
   moitie : une fonctionnalite a une seule capture ne doit pas ecraser son
   propre texte. */
.fonction {
  display: flex;
  gap: 26px;
  align-items: flex-start;
  padding: 22px 0;
  border-top: 1px solid var(--border);
}
.fonction-texte { flex: 1 1 0; min-width: 0; }
.fonction .vignettes { flex: 0 0 44%; max-width: 44%; margin-top: 0; }
.fonction:first-child { border-top: 0; padding-top: 0; }
.fonction h3 { margin-bottom: 9px; font-size: 17px; }

/* Un blanc entre les paragraphes d'une meme fonctionnalite.
   ---------------------------------------------------------------------------
   Il n'y en avait aucun : une description en quatre paragraphes - la
   Construction et ses deux modes - sortait en un seul pave ou les modes ne se
   distinguaient plus. Le gras des etiquettes ne suffit pas a aerer un bloc.

   Le dernier paragraphe garde sa marge quand des vignettes suivent : c'est ce
   qui empeche les captures de coller au texte. Il la perd quand il termine le
   bloc, ou le padding de .fonction prend le relais. */
.fonction p { margin: 0 0 16px; }
.fonction p:last-child { margin-bottom: 0; }

/* Les captures d'une fonction, toutes sur une ligne.
   ---------------------------------------------------------------------------
   Hauteur fixe et largeur libre : chaque vignette garde ses proportions, donc
   le bandeau du pillage reste un bandeau et l'écran de défense reste presque
   carré. Les ramener toutes au même rectangle les aurait déformées ou
   rognées, et une capture rognée ment sur ce qu'elle montre.

   À cette taille on ne lit rien, et ce n'est pas ce qu'on leur demande :
   elles disent combien il y a d'écrans et à quoi ils ressemblent. Le clic les
   ouvre en grand. */
.vignettes { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }

/* Les captures se dimensionnent sur la largeur, pas sur la hauteur.
   ---------------------------------------------------------------------------
   A hauteur fixe, une capture large s'etale d'autant : la bande d'une
   notification prenait trois fois la place d'un ecran de reglages, et les
   captures etroites laissaient du vide a cote d'elles.

   Chacune prend donc une part de la colonne - deux par ligne, une seule si
   elle est seule - et sa hauteur suit ses proportions. Rien n'est rogne, et
   il ne reste plus de blanc au bout d'une ligne. */
.vignettes .capture {
  flex: 0 1 calc(50% - 6px);
  min-width: 0;
  min-height: 0;
  height: auto;
  padding: 5px;
  border-radius: 8px;
  background: rgba(11, 22, 41, .72);
}
.vignettes-1 .capture { flex-basis: 100%; }
.vignettes .capture img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}
/* Le cadre d'attente n'a pas de hauteur imposée : sinon son texte déborderait
   d'une vignette de cent soixante-dix pixels. */
.vignettes .capture:has(.capture-vide) { height: auto; padding: 10px; }

/* Le menu sur petit écran.
   ---------------------------------------------------------------------------
   Sept pages, la connexion et le choix de la langue font huit cents pixels de
   large : sur un téléphone, la barre poussait toute la page de côté et les
   dernières entrées sortaient de l'écran sans que rien ne le laisse voir.

   Elle passe donc sur plusieurs lignes. Un menu déroulant serait plus
   compact, mais il cacherait derrière un bouton les six pages qui sont
   justement ce qu'on est venu regarder. */
@media (max-width: 900px) {
  /* Trop etroit pour deux colonnes : les captures repassent sous le texte. */
  .fonction { display: block; }
  .fonction .vignettes { max-width: 100%; margin-top: 14px; }
}

/* Le seuil est celui de la barre, pas celui du telephone.
   Mesure sur la page allemande le 04/09/2026 : la barre demande 1252 px pour
   tenir sur une ligne, et debordait donc entre 900 et 1252 - la page entiere
   defilait de cote. Elle s empile maintenant avant de deborder. */
@media (max-width: 1250px) {
  .topbar .inner {
    flex-wrap: wrap;
    height: auto;
    padding: 10px 16px;
    gap: 8px 14px;
  }
  /* L'écarteur poussait la connexion tout à droite : sur plusieurs lignes il
     ne pousse plus rien, il crée juste un trou. */
  .spacer { display: none; }
  .marque { width: 100%; }
  .lien { font-size: 14px; }
  .langue { margin-left: auto; }
}

@media (max-width: 780px) {
  main { padding: 18px 16px 56px; }
  .pied .inner { padding: 16px; }
  .hero { padding: 44px 0 36px; }
  .fiche { grid-template-columns: 1fr; gap: 16px; }
  .fiche-alerte { grid-template-columns: 1fr; }
  /* L'inversion n'a plus de sens en une colonne : elle mettrait le texte
     avant l'image sur une fiche sur deux, sans raison visible. */
  .fiche:nth-child(odd) .capture { order: 0; }
}

/* Empreinte SHA-256 sous chaque bouton de telechargement.
   Discrete par choix : elle sert a qui la cherche, et ne doit pas encombrer
   la page pour les autres. Le mot cesure evite qu'une chaine de soixante-
   quatre caracteres force la page a defiler de cote sur un telephone. */
.empreinte {
	margin: 8px 0 0;
	font-size: 11px;
	line-height: 1.5;
	color: var(--muted);
}

.empreinte .algo {
	margin-right: 8px;
	letter-spacing: .04em;
	opacity: .8;
}

.empreinte code {
	font-size: 11px;
	word-break: break-all;
	background: none;
	padding: 0;
	color: inherit;
}
