/* Glatax's own skin, rebuilt on `docs/maquette/Glatax.dc.html`. The module shares nothing
   with the rest of FamGuiGau: this sheet carries its fonts, its two palettes, its reset, its
   page transition and all of its components. The pawns are not here — they live in the board's
   own shadow DOM, with their own recipe.

   Two layers of tokens. `--gx-*` is the maquette's, and the whole new interface is measured in
   it. `--g-*` is the previous one, kept as **aliases** of the new: the screens the maquette does
   not cover — a battle, the discovery game, the sign-in — keep their markup and still change
   skin, and still follow the light theme, without a single one of their rules being rewritten. */

@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("../fonts/space-grotesk-latin-ext-NXGsJlG.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-20C4, U+2113,
        U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("../fonts/space-grotesk-latin-Dr-cltI.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: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-400-latin-ext-WlFXyXd.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-20C4, U+2113,
        U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-400-latin-78NWkmx.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: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-500-latin-ext-Uqu9TNw.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;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-500-latin-QJNNIVc.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: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-600-latin-ext-Wa6oxBk.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;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-600-latin-uhfYm1a.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;
}

/* ------------------------------------------------------------------ jetons */

:root {
    --gx-titre-police: 'Space Grotesk', system-ui, -apple-system, sans-serif;
    --gx-mono: 'IBM Plex Mono', ui-monospace, Menlo, Monaco, monospace;

    /* The two colours that belong to no theme: a refusal is the same red on both skins, and the
       festive red of the contest banner is a decoration, not a surface. */
    --gx-danger: #ff6b4a;
    --gx-rouge: #d4441f;
    --gx-sur-rouge: #fff3da;

    /* Les deux couleurs d'un camp sont celles de ses pions : elles vivent dans le composant du
       plateau, qui les dessine seul, et sont redites ici pour l'avatar d'un camp, l'en-tête de
       sa colonne de coups et la pastille d'un spectateur. Ce sont les seules couleurs du module
       qui ne suivent pas le thème — un camp ne change pas de camp parce qu'on allume la
       lumière —, et l'encre posée dessus ne le suit pas davantage. */
    --gx-camp-a: #4cb3ee;
    --gx-camp-b: #e9a13e;
    --gx-encre-camp: #0f1822;

    --gx-duree: 380ms;
    --gx-courbe: cubic-bezier(0.22, 0.85, 0.22, 1);
}

:root,
[data-theme='dark'] {
    --gx-fond: #141e2b;
    --gx-surface: #1c2938;
    --gx-texte: #eaf0f6;
    --gx-faible: #8fa0b2;
    --gx-bord: #2c3b4c;
    --gx-survol: #243344;
    --gx-contre: #0f1822;
    --gx-vert: #3fd9a8;
    --gx-ambre: #ffc53d;
    --gx-violet: #9a8cff;
    --gx-voile: rgba(10, 16, 24, 0.52);
    --gx-hachure: rgba(143, 160, 178, 0.18);
    --gx-jauge: rgba(255, 255, 255, 0.1);
}

[data-theme='light'] {
    --gx-fond: #f5f6f1;
    --gx-surface: #ffffff;
    --gx-texte: #17190f;
    --gx-faible: #696e60;
    --gx-bord: #e1e3d9;
    --gx-survol: #f0f2ea;
    --gx-contre: #ffffff;
    --gx-vert: #118463;
    --gx-ambre: #8a6207;
    --gx-violet: #5b4cc4;
    --gx-voile: rgba(23, 25, 15, 0.38);
    --gx-hachure: rgba(105, 110, 96, 0.22);
    --gx-jauge: rgba(23, 25, 15, 0.1);
}

/* The previous palette, now an alias of the new one. Nothing reads these but the screens the
   maquette does not cover; they are declared in the same blocks so they turn with the theme. */
:root,
[data-theme='dark'],
[data-theme='light'] {
    --g-fond: var(--gx-fond);
    --g-creux: var(--gx-fond);
    --g-surface: var(--gx-surface);
    --g-surface-2: var(--gx-surface);
    --g-surface-3: var(--gx-survol);
    --g-surface-4: var(--gx-fond);
    --g-survol: var(--gx-survol);
    --g-avatar: var(--gx-survol);

    --g-bord: var(--gx-bord);
    --g-bord-fort: var(--gx-bord);
    --g-bord-vif: var(--gx-vert);

    --g-texte: var(--gx-texte);
    --g-titre: var(--gx-vert);
    --g-second: var(--gx-faible);
    --g-faible: var(--gx-faible);
    --g-tres-faible: var(--gx-faible);

    --g-accent: var(--gx-vert);
    --g-accent-clair: var(--gx-vert);
    --g-bandeau: var(--gx-vert);
    --g-bandeau-survol: var(--gx-vert);
    --g-bandeau-creux: var(--gx-survol);
    --g-bleu-sourd: var(--gx-survol);

    --g-vert: var(--gx-vert);
    --g-or: var(--gx-ambre);
    --g-ambre: var(--gx-ambre);
    --g-rouge: var(--gx-danger);
    --g-alerte: var(--gx-danger);
    --g-violet: var(--gx-violet);

    --g-danger-fond: var(--gx-surface);
    --g-danger-fond-2: var(--gx-survol);
    --g-danger-plein: var(--gx-rouge);
    --g-danger-bord: var(--gx-danger);
    --g-danger-texte: var(--gx-danger);
    --g-danger-sourd: var(--gx-faible);

    --g-rayon: 10px;
    --g-mono: var(--gx-mono);
    --g-ombre-flottante: 0 6px 16px rgba(0, 0, 0, 0.3);
    --g-ombre-dialogue: 0 10px 30px rgba(0, 0, 0, 0.35);
}

/* The one place a text sits on `--g-bandeau`, which is now the green of the new palette: on the
   light skin it is dark enough for white, on the dark one it is not, and the maquette's answer
   to « text on an accent » is `--gx-contre`. */
[data-theme='dark'] {
    --g-bandeau-texte: var(--gx-contre);
}

[data-theme='light'] {
    --g-bandeau-texte: #ffffff;
}

@keyframes gx-pulse {
    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.25;
    }
}

@keyframes g-tourne {
    to {
        transform: rotate(360deg);
    }
}

@keyframes g-pulse {
    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.35;
    }
}

/* ------------------------------------------------------------------- reset */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
}

body {
    margin: 0;
    background: var(--gx-fond);
    color: var(--gx-texte);
    font-family: var(--gx-titre-police);
    font-size: 15px;
    line-height: 1.4;
    -webkit-font-smoothing: antialiased;
    -webkit-text-size-adjust: 100%;
}

a {
    color: var(--gx-vert);
    text-decoration: none;
}

a:hover {
    color: var(--gx-texte);
}

::selection {
    background: var(--gx-vert);
    color: var(--gx-contre);
}

h1,
h2,
h3,
p {
    margin: 0;
}

button,
input,
select,
textarea {
    font-family: inherit;
    font-size: inherit;
    color: inherit;
}

:focus-visible {
    outline: 2px solid var(--gx-vert);
    outline-offset: 2px;
}

[hidden] {
    display: none !important;
}

svg {
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* The two strokes the maquette thickens: the back chevron and the one on the contest's button,
   both small and both read as an arrow rather than as a hairline. */
.gx-retour svg,
.gx-noel__oui svg {
    stroke-width: 2.4;
}

/* --------------------------------------------- le visage d'un joueur */

/* Un avatar, et la couronne de son classement **posée dessus**. **Partout où un pseudo est
   écrit, ce bloc est à côté** : la bande, les listes, un classement, une carte, les deux camps
   d'une battle.

   La couronne se porte, elle n'encadre pas : elle est posée en absolu sur le crâne et ne pousse
   donc rien. Elle fait un peu moins des deux tiers de la largeur de l'avatar, et son bord
   inférieur mord d'un dixième sur le disque — c'est là que les deux coins d'une couronne de
   cette largeur rencontrent un cercle, et elle s'y assoit. Ce qui dépasse, un tiers de la
   hauteur de l'avatar, dépasse **vers le haut**, dans la gouttière de la ligne. */
.gx-face {
    /* La taille d'une liste, qui est le cas courant : les quelques exceptions — la bande, le
       tchat, les deux portraits — la disent, et l'en-tête d'un classement la retrouve sans
       qu'on la lui recopie. */
    --gx-face: 38px;
    /* La teinte d'un avatar sans photo, et l'encre posée dessus. Quatre jeux : le neutre, les
       deux camps, le lecteur. */
    --gx-face-fond: var(--gx-survol);
    --gx-face-encre: var(--gx-texte);
    position: relative;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--gx-face);
    height: var(--gx-face);
}

.gx-face__disque {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: var(--gx-face-fond);
    color: var(--gx-face-encre);
    font: 700 calc(var(--gx-face) * 0.4) / 1 var(--gx-titre-police);
    object-fit: cover;
    overflow: hidden;
}

/* La couronne est large : elle porte cinq pointes, leurs boules et un bandeau serti, et c'est
   le détail le plus fin qui décide de la taille sous laquelle le dessin tient encore. Aux deux
   tiers de l'avatar elle se réduisait à une tache. */
.gx-face__couronne {
    position: absolute;
    bottom: 84%;
    left: 50%;
    width: 78%;
    height: auto;
    /* **Portée de travers**, comme un chapeau qu'on ne redresse pas. Le pivot n'est pas la
       couronne mais le **centre de l'avatar**, à 157 % de la hauteur de l'image sous son
       bord haut : elle glisse alors le long du crâne au lieu de décoller d'un côté, et elle
       touche la tête penchée comme elle la touchait droite. */
    transform-origin: 50% 157%;
    transform: translateX(-50%) rotate(-16deg);
    pointer-events: none;
}

/* Les trois teintes d'un avatar sans photo : le camp A, le camp B, et le lecteur lui-même. Les
   deux premières sont les couleurs des pions, qui ne suivent pas le thème. */
.gx-face--a {
    --gx-face-fond: var(--gx-camp-a);
    --gx-face-encre: var(--gx-encre-camp);
}

.gx-face--b {
    --gx-face-fond: var(--gx-camp-b);
    --gx-face-encre: var(--gx-encre-camp);
}

.gx-face--moi {
    --gx-face-fond: var(--gx-vert);
    --gx-face-encre: var(--gx-contre);
}

/* Ce qui est trop serré pour qu'une couronne dépasse dedans s'ouvre de sa hauteur, et seulement
   quand il y en a une : les deux portraits, posés au milieu d'un texte, et la carte d'un camp,
   que la maquette dessine à l'étroit. */
.gx-camp:has(.gx-face--couronne) {
    padding-block: 17px;
}

.gx-identite:has(.gx-face--couronne) {
    padding-top: 40px;
}

.gx-carte__identite:has(.gx-face--couronne) {
    padding-top: 36px;
}

/* ------------------------------------------------- la coquille et sa bande */

.gx-app {
    position: relative;
    height: 100dvh;
    overflow: hidden;
    background: var(--gx-fond);
    color: var(--gx-texte);
}

.gx-bande {
    position: absolute;
    inset: 0 0 auto;
    z-index: 200;
    background: var(--gx-fond);
    border-bottom: 1px solid var(--gx-bord);
}

.gx-bande__rang {
    max-width: 860px;
    margin: 0 auto;
    padding: 14px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.gx-bande__gauche {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

.gx-bande__droite {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: none;
}

.gx-retour {
    display: flex;
    align-items: center;
    gap: 7px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    padding: 8px 13px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    white-space: nowrap;
    transition:
        color 0.18s ease,
        border-color 0.18s ease;
}

.gx-retour:hover {
    color: var(--gx-texte);
    border-color: var(--gx-texte);
}

.gx-marque {
    display: flex;
    align-items: center;
    gap: 14px;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    color: var(--gx-texte);
    transition: opacity 0.18s ease;
}

.gx-marque:hover {
    color: var(--gx-texte);
    opacity: 0.65;
}

/* Le logo est rond et porte son fond : rien à arrondir ni à colorer sous lui, et il se lit tel
   quel sur les deux peaux. Il prend presque toute la hauteur de la bande, et la marge négative
   l'y fait tenir sans la pousser : la bande reste à 67 px, hauteur sur laquelle se cale l'écran
   d'une battle. */
.gx-marque__blason {
    display: block;
    width: 46px;
    height: 46px;
    margin-block: -4px;
    flex: none;
}

.gx-marque__nom {
    font: 700 20px/1 var(--gx-titre-police);
    letter-spacing: 0.2em;
}

.gx-moi {
    display: flex;
    align-items: center;
    gap: 9px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    /* Serrée autour d'un visage de 26 px : la bande ne doit pas changer de hauteur, l'écran
       d'une battle se cale dessous. */
    padding: 4px 13px 4px 4px;
    cursor: pointer;
    color: var(--gx-texte);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    white-space: nowrap;
    transition: border-color 0.18s ease;
}

.gx-moi:hover {
    color: var(--gx-texte);
    border-color: var(--gx-vert);
}

/* The guest's seat in the bar: the same pill, without an initial to put in it. */
.gx-moi--invite {
    padding: 7px 13px;
    color: var(--gx-faible);
}

.gx-rond {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    cursor: pointer;
    color: var(--gx-faible);
    transition:
        color 0.18s ease,
        border-color 0.18s ease;
}

.gx-rond:hover {
    color: var(--gx-texte);
    border-color: var(--gx-texte);
}

.gx-rond__point {
    position: absolute;
    top: 7px;
    right: 8px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gx-danger);
    border: 2px solid var(--gx-fond);
}

/* ----------------------------------------- la page, et son glissement */

.gx-page {
    position: absolute;
    inset: 0;
    background: var(--gx-fond);
    overflow-y: auto;
    overscroll-behavior: contain;
}

.gx-colonne {
    max-width: 860px;
    margin: 0 auto;
    padding: 68px 24px 60px;
}

/* Les écrans que la maquette ne couvre pas — une battle, la partie découverte — attendaient une
   coquille à hauteur fixe : leur plateau se dimensionne sur la hauteur qu'on lui donne
   (`container-type: size`), et une colonne de hauteur automatique ne lui en donne aucune. On la
   leur rend, sur la fenêtre moins la bande. */
.gx-colonne--plein {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
    padding-bottom: 24px;
}

/* La maquette fait glisser une page sur l'autre : celle qui arrive entre par la droite, celle
   qu'on laisse recule. Turbo le pilote — la balise `view-transition` de l'en-tête demande la
   transition, et `data-turbo-visit-direction` dit le sens. Turbo coupe lui-même l'animation sous
   `prefers-reduced-motion` : il n'y a rien à éteindre ici.

   **C'est la page qui arrive qui porte le mouvement**, et pas le couple. Les deux instantanés
   d'une transition de vue se peignent l'un sur l'autre sans que `z-index` ne les départage de
   façon sûre, et la page entrante est opaque sur toute la fenêtre : elle recouvre la sortante,
   dont le mouvement ne se verrait pas. On la fait donc entrer par la droite à l'aller, par la
   gauche au retour, et la sortante ne fait que s'écarter derrière elle. Le sens est alors lisible
   dans les deux cas, ce que le parallaxe de la maquette ne donnait qu'à l'aller. */
.gx-page {
    view-transition-name: gx-page;
}

::view-transition-old(gx-page),
::view-transition-new(gx-page) {
    animation-duration: var(--gx-duree);
    animation-timing-function: var(--gx-courbe);
    animation-fill-mode: both;
    mix-blend-mode: normal;
}

@keyframes gx-entre-droite {
    from {
        transform: translateX(100%);
    }
}

@keyframes gx-entre-gauche {
    from {
        transform: translateX(-100%);
    }
}

@keyframes gx-recule-gauche {
    to {
        transform: translateX(-26%);
        opacity: 0.3;
    }
}

@keyframes gx-recule-droite {
    to {
        transform: translateX(26%);
        opacity: 0.3;
    }
}

/* L'aller : Turbo dit « forward ». */
html[data-turbo-visit-direction='forward']::view-transition-new(gx-page) {
    animation-name: gx-entre-droite;
}

html[data-turbo-visit-direction='forward']::view-transition-old(gx-page) {
    animation-name: gx-recule-gauche;
}

/* Le retour du navigateur : Turbo dit « back ». */
html[data-turbo-visit-direction='back']::view-transition-new(gx-page) {
    animation-name: gx-entre-gauche;
}

html[data-turbo-visit-direction='back']::view-transition-old(gx-page) {
    animation-name: gx-recule-droite;
}

/* Le bouton RETOUR de la bande est un lien : Turbo y voit une avancée. Le contrôleur
   `glatax-sens` marque la racine avant la visite (`data-gx-sens`, qui n'est pas le nom que porte
   le lien), et ces deux règles, posées après, gagnent. */
html[data-gx-sens='arriere']::view-transition-new(gx-page) {
    animation-name: gx-entre-gauche;
}

html[data-gx-sens='arriere']::view-transition-old(gx-page) {
    animation-name: gx-recule-droite;
}

/* The bar never moves: it is the frame the pages slide inside. */
.gx-bande {
    view-transition-name: gx-bande;
}

::view-transition-group(gx-bande) {
    animation-duration: 0ms;
}
/* --------------------------------------------- le bandeau du concours */

/* The contest banner wears its own colours on both skins: it is a decoration laid on the page,
   like a poster on a wall, and a poster does not change when the lights do. */
.gx-noel {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 48px 0 0;
    background: linear-gradient(135deg, #2a1420 0%, #1e1a2b 55%, #13241f 100%);
    border: 1px solid #ffc53d;
    border-radius: 14px;
    padding: 30px 26px 26px;
    box-shadow:
        0 0 0 1px rgba(255, 197, 61, 0.12),
        0 14px 40px -18px rgba(255, 197, 61, 0.45);
}

.gx-noel__ruban {
    position: absolute;
    inset: 0 0 auto;
    height: 5px;
    background: repeating-linear-gradient(115deg, #d4441f 0 14px, #f4ede2 14px 28px);
}

.gx-noel__lueur {
    position: absolute;
    top: -70px;
    right: -50px;
    width: 230px;
    height: 230px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 197, 61, 0.2) 0%, rgba(255, 197, 61, 0) 70%);
    pointer-events: none;
}

.gx-noel__tete {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}

.gx-noel__etiquette {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    background: #d4441f;
    border-radius: 999px;
    padding: 7px 13px;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.2em;
    color: #fff3da;
}

.gx-noel__etiquette::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #3fd9a8;
}

.gx-noel__espace {
    flex: 1;
}

.gx-noel__dates {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.18em;
    color: #ffc53d;
}

.gx-noel__titre {
    position: relative;
    font: 700 clamp(28px, 4.8vw, 44px) / 1.02 var(--gx-titre-police);
    letter-spacing: -0.02em;
    color: #ffc53d;
    text-shadow: 0 2px 18px rgba(255, 197, 61, 0.22);
}

.gx-noel__texte {
    position: relative;
    font: 400 15px/1.5 var(--gx-titre-police);
    color: #d8c9b4;
    max-width: 52ch;
    text-wrap: pretty;
}

.gx-noel__pied {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-top: 6px;
    padding-top: 20px;
    border-top: 1px solid rgba(255, 197, 61, 0.22);
}

.gx-noel__appel {
    flex: 1;
    min-width: 220px;
    font: 400 14px/1.5 var(--gx-titre-police);
    color: #d8c9b4;
    text-wrap: pretty;
}

.gx-noel__oui {
    display: flex;
    align-items: center;
    gap: 10px;
    background: #ffc53d;
    border: 0;
    border-radius: 999px;
    padding: 14px 22px;
    cursor: pointer;
    color: #241607;
    font: 700 12px/1 var(--gx-mono);
    letter-spacing: 0.18em;
    transition:
        transform 0.18s ease,
        box-shadow 0.18s ease;
}

.gx-noel__oui:hover {
    transform: translateY(-1px);
    box-shadow: 0 10px 24px -10px rgba(255, 197, 61, 0.9);
}

.gx-noel__tableau {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 18px;
    margin-top: 6px;
    padding-top: 20px;
    border-top: 1px solid rgba(255, 197, 61, 0.22);
}

.gx-noel__bloc {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.gx-noel__bloc--centre {
    justify-content: center;
}

.gx-noel__legende {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.2em;
    color: #d8c9b4;
}

.gx-noel__score {
    font: 500 clamp(26px, 4vw, 34px) / 1 var(--gx-mono);
    color: #ffc53d;
}

.gx-noel__rang {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    color: #3fd9a8;
}

.gx-noel__ligne {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.gx-noel__ligne .gx-noel__legende {
    flex: 1;
}

.gx-noel__avance {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    color: #3fd9a8;
}

.gx-noel__barre {
    display: flex;
    align-items: center;
    gap: 12px;
}

.gx-noel__rail {
    flex: 1;
    height: 8px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.1);
    overflow: hidden;
}

.gx-noel__jauge {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, #3fd9a8, #ffc53d);
}

.gx-noel__pourcent {
    font: 500 15px/1 var(--gx-mono);
    color: #3fd9a8;
}

.gx-noel__inscrit {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
}

.gx-noel__coche {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.2em;
    color: #3fd9a8;
}

.gx-noel__non {
    background: none;
    border: 1px solid rgba(255, 197, 61, 0.3);
    border-radius: 999px;
    padding: 9px 14px;
    cursor: pointer;
    color: #d8c9b4;
    white-space: nowrap;
    flex: none;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.18em;
    transition:
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-noel__non:hover {
    border-color: #ff6b4a;
    color: #ff6b4a;
}

/* ------------------------------------------- le menu, ses grandes entrées */

.gx-menu {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 28px 0 0;
}

.gx-menu--second {
    padding: 56px 0 0;
}

.gx-entree {
    display: flex;
    align-items: center;
    gap: 22px;
    width: 100%;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 14px;
    padding: 30px 26px;
    cursor: pointer;
    text-align: left;
    color: var(--gx-texte);
    font: 700 clamp(28px, 5vw, 44px) / 1 var(--gx-titre-police);
    letter-spacing: -0.015em;
    transition:
        border-color 0.2s ease,
        background 0.2s ease,
        transform 0.2s ease;
}

.gx-entree:hover {
    color: var(--gx-texte);
    background: var(--gx-survol);
    border-color: var(--gx-teinte);
    transform: translateX(6px);
}

/* « DECOUVRIR GLATAX » is the longest of the three, and the maquette gives it its own ceiling so
   the three lines keep one rhythm. */
.gx-entree--long {
    font-size: clamp(24px, 4.2vw, 38px);
}

.gx-entree--moyen {
    padding: 28px 26px;
    font-size: clamp(26px, 4.4vw, 38px);
    letter-spacing: -0.01em;
}

.gx-entree__pastille {
    width: 16px;
    height: 16px;
    border-radius: 5px;
    background: var(--gx-teinte);
    flex: none;
}

.gx-entree__nom {
    flex: 1;
}

.gx-entree__chevron {
    color: var(--gx-teinte);
    flex: none;
}

/* The three accents, carried as one token so a row says « I am the green one » in one place. */
.gx-vert {
    --gx-teinte: var(--gx-vert);
}

.gx-ambre {
    --gx-teinte: var(--gx-ambre);
}

.gx-violet {
    --gx-teinte: var(--gx-violet);
}

.gx-rouge {
    --gx-teinte: var(--gx-danger);
}

/* Le rouge plein de la zone de danger : celui d'une réponse qu'on ne reprend pas. */
.gx-sang {
    --gx-teinte: var(--gx-rouge);
}

/* -------------------------------------------- les groupes de l'écran Jouer */

.gx-groupe {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 36px 4px 12px;
}

.gx-groupe--premier {
    padding-top: 40px;
}

.gx-groupe__pastille {
    width: 9px;
    height: 9px;
    border-radius: 3px;
    background: var(--gx-teinte);
    flex: none;
}

.gx-groupe__nom {
    font: 500 11px/1.45 var(--gx-mono);
    letter-spacing: 0.24em;
    color: var(--gx-faible);
}

.gx-groupe__compte {
    font: 500 13px/1 var(--gx-mono);
    color: var(--gx-teinte);
}

.gx-groupe--fil {
    padding-bottom: 16px;
}

.gx-groupe--fil .gx-groupe__nom {
    flex: 1;
}

.gx-rangs {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.gx-rang {
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 11px;
    padding: 20px;
    cursor: pointer;
    text-align: left;
    color: var(--gx-texte);
    font: 500 clamp(19px, 2.8vw, 25px) / 1.1 var(--gx-titre-police);
    transition:
        border-color 0.18s ease,
        background 0.18s ease;
}

.gx-rang:hover {
    color: var(--gx-texte);
    border-color: var(--gx-teinte);
    background: var(--gx-survol);
}

.gx-rang__nom {
    flex: 1;
}

.gx-rang__chevron {
    color: var(--gx-teinte);
    flex: none;
}

.gx-rang__compte {
    font: 500 15px/1 var(--gx-mono);
    color: var(--gx-teinte);
}

.gx-rang__vif {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font: 500 15px/1 var(--gx-mono);
    color: var(--gx-teinte);
}

.gx-rang__vif::before,
.gx-rang__puce {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gx-teinte);
    flex: none;
}

/* Deux entrées qui vont par deux — attendre ou rejoindre une partie privée, attendre ou regarder
   qui attend dans l'arène — se posent côte à côte au lieu de s'empiler : la paire se lit alors
   comme un choix. La maquette les empile toutes ; le choix est noté dans docs/glatax.md. */
.gx-rangs__paire {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}

/* Le formulaire d'« attendre » est un calque de plus entre la grille et son bouton : il doit se
   laisser traverser, sinon le bouton ne remplit pas sa colonne. */
.gx-rangs__paire > form {
    display: flex;
}

/* Les trois niveaux solo : une rangée de trois cartes au lieu d'une pile de trois lignes.
   La maquette les empile comme le reste du menu — elle ne leur donnait pas de visage. Un visage
   se reconnaît d'un coup d'œil, et côte à côte les trois adversaires se comparent d'un regard. */
.gx-rangs--trio {
    flex-direction: row;
    align-items: stretch;
}

.gx-rang--solo {
    flex: 1 1 0;
    min-width: 0;
    flex-direction: column;
    gap: 12px;
    padding: 18px 12px 16px;
    text-align: center;
    font-size: clamp(15px, 2.2vw, 21px);
}

/* Le nom prend le vide : les trois badges s'alignent alors sur le bas des cartes, qu'un nom
   tienne sur une ligne ou sur deux. */
.gx-rang--solo .gx-rang__nom {
    display: flex;
    align-items: center;
    justify-content: center;
}

.gx-rang__visage {
    width: clamp(56px, 16vw, 104px);
    height: auto;
    border-radius: 50%;
    flex: none;
}

.gx-badge {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    color: var(--gx-contre);
    background: var(--gx-teinte);
    border-radius: 999px;
    padding: 6px 10px;
    white-space: nowrap;
}

/* « FORT » is the one badge the maquette takes out of the palette: a full red, and white on it. */
.gx-badge--fort {
    color: #fff;
    background: var(--gx-rouge);
}

/* ------------------------------------------------- un panneau au milieu */

.gx-panneau {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 26px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 16px;
    padding: 38px 28px 32px;
}

.gx-panneau--attente {
    gap: 22px;
    padding: 44px 28px 34px;
}

.gx-panneau--en-cours {
    border-color: var(--gx-ambre);
}

.gx-panneau--large {
    align-items: stretch;
    gap: 24px;
    padding: 32px 28px;
}

.gx-panneau__titre {
    font: 700 clamp(24px, 4vw, 34px) / 1 var(--gx-titre-police);
    letter-spacing: -0.01em;
    text-align: center;
}

.gx-panneau__titre--haut {
    font-size: clamp(22px, 3.6vw, 32px);
    line-height: 1.2;
    text-wrap: pretty;
}

.gx-panneau__mot {
    font: 400 15px/1.4 var(--gx-titre-police);
    color: var(--gx-faible);
    text-align: center;
    max-width: 34ch;
    text-wrap: pretty;
}

.gx-panneau__mot--large {
    max-width: 38ch;
}

.gx-panneau__mot--etroit {
    max-width: 36ch;
    margin: 0 auto;
}

.gx-panneau__temoin {
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--gx-bord);
}

.gx-panneau__temoin--vif {
    background: var(--gx-ambre);
    animation: gx-pulse 1.4s ease-in-out infinite;
}

/* ---------------------------------------------------- le QR et son code */

.gx-qr {
    width: min(276px, 68vw);
    aspect-ratio: 1;
    border-radius: 10px;
    background: #ffffff;
    padding: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.gx-qr svg,
.gx-qr img {
    display: block;
    width: 100%;
    height: 100%;
}

.gx-code {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

.gx-code__cases {
    display: grid;
    grid-template-columns: repeat(var(--gx-cases, 6), minmax(0, 1fr));
    gap: 6px;
    width: min(420px, 100%);
}

.gx-code__case {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 8px;
    padding: 12px 0;
    font: 500 clamp(17px, 3.4vw, 24px) / 1 var(--gx-mono);
    color: var(--gx-texte);
}

.gx-copier {
    display: flex;
    align-items: center;
    gap: 10px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 14px 18px;
    cursor: pointer;
    color: var(--gx-violet);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-copier:hover {
    color: var(--gx-violet);
    border-color: var(--gx-violet);
}

/* ------------------------------------------------- l'interrupteur et les boutons */

.gx-bascule {
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    max-width: 420px;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 12px;
    padding: 16px 18px;
    cursor: pointer;
    text-align: left;
    transition: border-color 0.18s ease;
}

.gx-bascule[aria-checked='true'] {
    border-color: var(--gx-ambre);
}

.gx-bascule__nom {
    flex: 1;
    min-width: 0;
    font: 500 15px/1.2 var(--gx-titre-police);
    color: var(--gx-texte);
}

.gx-bascule__rail {
    flex: none;
    width: 46px;
    height: 26px;
    border-radius: 999px;
    background: var(--gx-bord);
    padding: 3px;
    display: flex;
    justify-content: flex-start;
    transition: background 0.18s ease;
}

.gx-bascule[aria-checked='true'] .gx-bascule__rail {
    background: var(--gx-ambre);
    justify-content: flex-end;
}

.gx-bascule__bouton {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--gx-faible);
    transition: background 0.18s ease;
}

.gx-bascule[aria-checked='true'] .gx-bascule__bouton {
    background: var(--gx-contre);
}

.gx-plein {
    background: var(--gx-teinte, var(--gx-ambre));
    border: 1px solid var(--gx-teinte, var(--gx-ambre));
    border-radius: 10px;
    padding: 16px 26px;
    cursor: pointer;
    color: var(--gx-contre);
    font: 500 13px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition: filter 0.18s ease;
}

.gx-plein:hover {
    color: var(--gx-contre);
    filter: brightness(1.08);
}

.gx-nu {
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 15px 24px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-nu:hover {
    border-color: var(--gx-danger);
    color: var(--gx-danger);
}

.gx-pilule {
    display: flex;
    align-items: center;
    gap: 10px;
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    padding: 9px 15px;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    color: var(--gx-faible);
}

.gx-pilule__point {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gx-faible);
    flex: none;
}

.gx-pilule__etat {
    white-space: nowrap;
}

.gx-pilule--vive .gx-pilule__point {
    background: var(--gx-ambre);
}

.gx-pilule--vive .gx-pilule__etat:last-child {
    color: var(--gx-ambre);
}

/* ----------------------------------------------------------- les listes */

.gx-liste {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.gx-ligne {
    display: flex;
    align-items: center;
    gap: 18px;
    width: 100%;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 17px 20px;
    color: var(--gx-texte);
    font: 400 17px/1 var(--gx-mono);
    transition: border-color 0.18s ease;
}

.gx-ligne--vive {
    border-color: var(--gx-ambre);
}

.gx-ligne__puce {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gx-bord);
    flex: none;
}

.gx-ligne__puce--vive {
    background: var(--gx-ambre);
}

.gx-ligne__nom {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
    transition: color 0.18s ease;
}

.gx-ligne__nom:hover {
    color: var(--gx-ambre);
}

.gx-ligne__note {
    font: 400 13px/1 var(--gx-mono);
    color: var(--gx-faible);
}

.gx-ligne__action {
    flex: none;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 8px;
    padding: 9px 13px;
    cursor: pointer;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    white-space: nowrap;
    color: var(--gx-faible);
    transition: border-color 0.18s ease;
}

.gx-ligne__action:hover {
    color: var(--gx-ambre);
    border-color: var(--gx-ambre);
}

.gx-ligne__action--vive {
    color: var(--gx-ambre);
}

/* ------------------------------------------------- rejoindre : la caméra */

.gx-viseur {
    position: relative;
    width: min(320px, 74vw);
    aspect-ratio: 1;
    margin: 0 auto;
    border-radius: 12px;
    overflow: hidden;
    background: #0c141e;
    background-image: repeating-linear-gradient(
        135deg,
        transparent 0 9px,
        rgba(143, 160, 178, 0.12) 9px 18px
    );
    display: flex;
    align-items: center;
    justify-content: center;
}

.gx-viseur video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Les quatre coins occupent 38 px à 22 px du bord : une note plus longue que « flux caméra » —
   un refus de caméra — se replie entre eux plutôt que par-dessus. */
.gx-viseur__mot {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 18px;
    padding: 0 64px;
    font: 400 10px/1.4 var(--gx-mono);
    letter-spacing: 0.14em;
    color: #8fa0b2;
    text-align: center;
}

.gx-viseur__coin {
    position: absolute;
    width: 38px;
    height: 38px;
}

.gx-viseur__coin--hg {
    top: 22px;
    left: 22px;
    border-top: 3px solid var(--gx-violet);
    border-left: 3px solid var(--gx-violet);
    border-radius: 8px 0 0 0;
}

.gx-viseur__coin--hd {
    top: 22px;
    right: 22px;
    border-top: 3px solid var(--gx-violet);
    border-right: 3px solid var(--gx-violet);
    border-radius: 0 8px 0 0;
}

.gx-viseur__coin--bg {
    bottom: 22px;
    left: 22px;
    border-bottom: 3px solid var(--gx-violet);
    border-left: 3px solid var(--gx-violet);
    border-radius: 0 0 0 8px;
}

.gx-viseur__coin--bd {
    bottom: 22px;
    right: 22px;
    border-bottom: 3px solid var(--gx-violet);
    border-right: 3px solid var(--gx-violet);
    border-radius: 0 0 8px 0;
}

.gx-viseur__trait {
    position: absolute;
    left: 22px;
    right: 22px;
    top: 50%;
    height: 2px;
    background: var(--gx-violet);
    animation: gx-pulse 1.8s ease-in-out infinite;
}

.gx-ou {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 4px 0;
}

.gx-ou::before,
.gx-ou::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--gx-bord);
}

.gx-ou__mot {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.24em;
    color: var(--gx-faible);
}

.gx-champ {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.gx-champ__nom {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.22em;
    color: var(--gx-faible);
    text-align: center;
}

.gx-saisie {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
}

.gx-saisie__cases {
    display: grid;
    grid-template-columns: repeat(var(--gx-cases, 6), clamp(30px, 7vw, 40px));
    gap: 5px;
}

.gx-saisie__case {
    width: 100%;
    min-width: 0;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 8px;
    padding: 13px 0;
    text-align: center;
    color: var(--gx-texte);
    font: 500 clamp(16px, 3vw, 20px) / 1 var(--gx-mono);
    outline: none;
    text-transform: uppercase;
    transition: border-color 0.18s ease;
}

.gx-saisie__case:focus {
    border-color: var(--gx-violet);
}

.gx-saisie__case--remplie {
    border-color: var(--gx-faible);
}

.gx-viseur__flux {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gx-envoyer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 15px 22px;
    cursor: default;
    background: transparent;
    color: var(--gx-faible);
    font: 500 13px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        background 0.18s ease,
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-envoyer--prêt,
.gx-envoyer--pret {
    cursor: pointer;
    background: var(--gx-violet);
    border-color: var(--gx-violet);
    color: var(--gx-contre);
}

.gx-indice {
    min-height: 18px;
    text-align: center;
    font: 400 12px/1.4 var(--gx-mono);
    letter-spacing: 0.08em;
    color: var(--gx-faible);
}

.gx-indice--refus {
    color: var(--gx-danger);
}

/* -------------------------------------------------------- les classements */

.gx-tableau__tete {
    display: flex;
    gap: 24px;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.2em;
    color: var(--gx-faible);
    padding: 40px 20px 12px;
}

.gx-tableau__rang {
    width: 42px;
}

/* Les lignes portent un visage entre le rang et le nom : l'en-tête lui réserve la même place,
   sinon « JOUEUR » ne surmonte plus la colonne des joueurs. C'est un visage vide, et non une
   largeur recopiée : il porte les mêmes marges que celui des lignes, et suivra ce qu'elles
   deviennent. */
.gx-tableau__face {
    height: 0;
}

.gx-tableau__joueur {
    flex: 1;
}

.gx-classe {
    display: flex;
    gap: 24px;
    align-items: center;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    /* Deux pixels de plus que la maquette : c'est la place où dépasse la couronne d'un visage,
       et la ligne garde la même hauteur qu'il y en ait une ou non. */
    padding: 17px 20px;
    font: 400 17px/1 var(--gx-mono);
    color: var(--gx-texte);
}

.gx-classe__rang {
    width: 42px;
    color: var(--gx-faible);
}

.gx-classe__nom {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
    transition: color 0.18s ease;
}

.gx-classe__nom:hover {
    color: var(--gx-ambre);
}

.gx-classe__score {
    color: var(--gx-faible);
}

/* The reader's own line, set apart under the table in the accent of its ranking. */
.gx-classe--moi {
    border-color: var(--gx-teinte);
    padding: 16px 20px;
    margin-top: 20px;
    color: var(--gx-teinte);
}

.gx-classe--moi .gx-classe__rang,
.gx-classe--moi .gx-classe__score {
    color: inherit;
}

.gx-classe--moi .gx-classe__nom {
    font-family: var(--gx-titre-police);
    font-weight: 700;
    font-size: 19px;
    cursor: default;
}

/* Un refus, posé en haut de l'écran : c'est la seule chose qu'on écrit par-dessus une page. */
.gx-alerte {
    margin-top: 28px;
    border: 1px solid var(--gx-danger);
    border-radius: 10px;
    padding: 14px 18px;
    font: 400 13px/1.5 var(--gx-titre-police);
    color: var(--gx-danger);
}

.gx-vide {
    border: 1px dashed var(--gx-bord);
    border-radius: 10px;
    padding: 20px;
    font: 400 12px/1.7 var(--gx-mono);
    color: var(--gx-faible);
    letter-spacing: 0.04em;
    text-align: center;
}

/* -------------------------------------------------------------- les règles */

.gx-regles {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 44px 0 0;
}

.gx-regle {
    display: grid;
    grid-template-columns: 52px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 12px;
    padding: 22px 24px;
}

.gx-regle__numero {
    font: 400 15px/1.3 var(--gx-mono);
    color: var(--gx-violet);
}

.gx-regle__corps {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.gx-regle__titre {
    font: 700 21px/1.2 var(--gx-titre-police);
}

.gx-regle__texte {
    font: 400 14px/1.6 var(--gx-titre-police);
    color: var(--gx-faible);
    text-wrap: pretty;
}

.gx-regle__texte p + p {
    margin-top: 10px;
}

.gx-regle__texte strong {
    color: var(--gx-texte);
    font-weight: 500;
}

/* ------------------------------------------------------------ le profil */

.gx-profil__actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    padding: 34px 0 0;
}

.gx-action {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 14px 18px;
    cursor: pointer;
    color: var(--gx-texte);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition: border-color 0.18s ease;
}

.gx-action:hover {
    color: var(--gx-texte);
    border-color: var(--gx-vert);
}

.gx-action--sortie {
    background: none;
    color: var(--gx-faible);
    transition:
        color 0.18s ease,
        border-color 0.18s ease;
}

.gx-action--sortie:hover {
    color: var(--gx-danger);
    border-color: var(--gx-danger);
}

.gx-identite {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 24px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 14px;
    padding: 24px;
    margin-top: 22px;
}

.gx-portrait {
    width: 112px;
    height: 112px;
    border-radius: 14px;
    border: 1px dashed var(--gx-bord);
    background: repeating-linear-gradient(
        135deg,
        transparent 0 7px,
        var(--gx-hachure) 7px 14px
    );
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 8px;
    flex: none;
}

/* La photo d'un joueur remplit l'emplacement que la maquette hachure. */
.gx-portrait--photo {
    border-style: solid;
    border-color: var(--gx-bord);
    background: var(--gx-fond);
    object-fit: cover;
    padding: 0;
}

.gx-photo {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.gx-photo .gx-portrait,
.gx-photo .gx-portrait--photo {
    width: 88px;
    height: 88px;
    padding: 7px;
}

.gx-photo .gx-portrait--photo {
    padding: 0;
}

.gx-photo__cote {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
    flex: 1;
    min-width: 160px;
}

/* Un `<input type="file">` nu ne se peint pas : il est caché derrière son étiquette, qui est
   le bouton. Caché, et non `display: none` — un champ retiré de la mise en page n'est plus
   atteint au clavier. */
.gx-photo__champ {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.gx-photo__champ:focus-visible + * {
    outline: 2px solid var(--gx-vert);
    outline-offset: 2px;
}

.gx-photo__retirer {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font: 400 12px/1.3 var(--gx-mono);
    color: var(--gx-faible);
}

.gx-photo__note {
    font: 400 11px/1.4 var(--gx-mono);
    color: var(--gx-faible);
    overflow-wrap: anywhere;
}

.gx-portrait__mot {
    font: 400 9px/1.3 var(--gx-mono);
    color: var(--gx-faible);
    text-align: center;
}

.gx-identite__corps {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
    flex: 1;
}

.gx-identite__nom {
    font: 700 clamp(30px, 5vw, 44px) / 1 var(--gx-titre-police);
    letter-spacing: -0.015em;
}

.gx-identite__etat {
    display: flex;
    align-items: center;
    gap: 9px;
    font: 400 12px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    color: var(--gx-vert);
}

.gx-identite__etat::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gx-vert);
}

.gx-identite__ligne {
    font: 400 13px/1.4 var(--gx-mono);
    letter-spacing: 0.06em;
    color: var(--gx-texte);
    padding-top: 4px;
}

.gx-section {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.24em;
    color: var(--gx-faible);
    padding: 36px 4px 12px;
}

/* Les statistiques : un seul bloc montré, le switch au-dessus. Les deux blocs sont rendus, et
   celui qu'on ne lit pas porte `hidden` — d'où la règle qui le range, `display: flex` du bloc
   l'emportant sinon sur celui du navigateur. */
.gx-stats {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.gx-stats .gx-stat[hidden] {
    display: none;
}

.gx-stats__bascule {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

/* Un onglet porte le nom de son échelle et le rang qu'on y tient : c'est ce qui se lit avant
   d'ouvrir le bloc. Pris, il se peint de la teinte de sa colonne — le vert du solo, l'ambre de
   l'arène. */
.gx-stats__onglet {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 9px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 11px;
    padding: 13px 10px;
    cursor: pointer;
    color: var(--gx-faible);
    transition:
        background 0.18s ease,
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-stats__onglet:not([aria-pressed='true']):hover {
    border-color: var(--gx-teinte);
    color: var(--gx-texte);
}

.gx-stats__onglet[aria-pressed='true'] {
    background: var(--gx-teinte);
    border-color: var(--gx-teinte);
    color: var(--gx-contre);
}

.gx-stats__nom {
    font: 500 11px/1.2 var(--gx-mono);
    letter-spacing: 0.18em;
}

.gx-stats__rang {
    font: 400 14px/1.2 var(--gx-mono);
    letter-spacing: 0.06em;
    color: var(--gx-teinte);
}

.gx-stats__onglet[aria-pressed='true'] .gx-stats__rang {
    color: var(--gx-contre);
}

.gx-stat {
    display: flex;
    flex-direction: column;
    gap: 16px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 11px;
    padding: 20px;
}

.gx-stat__tete {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.gx-stat__nom {
    font: 400 10px/1.3 var(--gx-mono);
    letter-spacing: 0.18em;
    color: var(--gx-faible);
}

/* Le niveau, à côté du titre de la colonne arène : la même ligne, en accent, parce qu'il
   qualifie la note affichée juste dessous et non la colonne. */
.gx-stat__niveau {
    color: var(--gx-ambre);
}

.gx-stat__valeur {
    font: 700 32px/1 var(--gx-titre-police);
    color: var(--gx-teinte);
}

.gx-stat__lignes {
    display: flex;
    flex-direction: column;
    gap: 1px;
    border-top: 1px solid var(--gx-bord);
    padding-top: 4px;
}

.gx-stat__ligne {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 7px 0;
}

.gx-stat__etiquette {
    flex: 1;
    font: 400 11px/1.3 var(--gx-mono);
    letter-spacing: 0.12em;
    color: var(--gx-faible);
}

.gx-stat__nombre {
    font: 400 14px/1.3 var(--gx-mono);
    color: var(--gx-texte);
}

.gx-stat__part {
    width: 40px;
    text-align: right;
    margin-left: -8px;
    font: 400 12px/1.3 var(--gx-mono);
    color: var(--gx-faible);
}

.gx-meta {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.gx-meta__ligne {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: baseline;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 16px 20px;
}

.gx-meta__nom {
    flex: 1;
    min-width: 140px;
    font: 400 12px/1.4 var(--gx-mono);
    letter-spacing: 0.12em;
    color: var(--gx-faible);
}

.gx-meta__valeur {
    font: 400 15px/1.3 var(--gx-mono);
    color: var(--gx-texte);
}

/* --------------------------------------------- l'écran d'une partie */

/* La partie prend la fenêtre entière sous la bande, et elle seule parmi les écrans du module :
   la vue au centre, le rail des vues à droite. Rien n'y défile en bloc — c'est le contenu d'une
   vue qui défile, et le plateau se dimensionne sur la hauteur qu'on lui laisse. */
.gx-colonne--partie {
    max-width: none;
    height: 100dvh;
    padding: 67px 0 0;
    /* Une colonne, et non un bloc : un refus posé par la coquille au-dessus de l'écran prend sa
       place, et c'est la partie qui se resserre dessous au lieu de déborder. */
    display: flex;
    flex-direction: column;
}

.gx-colonne--partie > .gx-alerte {
    flex: none;
    margin: 0 16px 10px;
}

.gx-page:has(.gx-colonne--partie) {
    overflow: hidden;
}

.gx-partie {
    flex: 1;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    min-height: 0;
    background: var(--gx-fond);
}

/* En plein écran c'est `<html>` qui y passe, et non la partie : un lien du rail mène à une autre
   vue, et la visite Turbo qui la charge remplace le corps du document — un élément du corps en
   plein écran s'en irait avec lui. La bande n'a alors plus lieu d'être, ni la place qu'on lui
   réserve ; ailleurs qu'ici elle reste, pour que la navigation ne disparaisse jamais. */
html:fullscreen:has(.gx-colonne--partie) .gx-bande {
    display: none;
}

html:fullscreen .gx-colonne--partie {
    padding-top: 0;
}

.gx-partie__corps {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.gx-partie__vue {
    position: relative;
    flex: 1;
    min-height: 0;
}

/* ---- Les deux camps, et le temps de jeu ---- */

.gx-duel {
    flex: none;
    display: flex;
    align-items: stretch;
    gap: 12px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--gx-bord);
}

.gx-camp {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 12px;
    padding: 12px 16px;
}

/* Le liseré de la maquette : il dit lequel des deux camps est celui du lecteur. */
.gx-camp--moi {
    border-color: var(--gx-vert);
}

/* Le camp B se lit en miroir, comme dans la maquette : son avatar au bord de l'écran, son nom
   aligné à droite, et sa pastille après son état. */
.gx-camp--b {
    flex-direction: row-reverse;
}

.gx-camp--b .gx-camp__corps {
    align-items: flex-end;
}

.gx-camp--b .gx-camp__etat {
    flex-direction: row-reverse;
}

.gx-camp__corps {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.gx-camp__nom {
    font: 500 15px/1 var(--gx-titre-police);
    color: var(--gx-texte);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.gx-camp__etat {
    display: flex;
    align-items: center;
    gap: 7px;
    font: 500 10px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    color: var(--gx-faible);
}

.gx-camp__point {
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gx-bord);
}

.gx-camp--trait .gx-camp__etat {
    color: var(--gx-vert);
}

.gx-camp--trait .gx-camp__point {
    background: var(--gx-vert);
}

/* Le compte de pions. La maquette ne le montre pas ; une partie d'Ataxx **est** ce compte, et la
   carte d'un camp est le seul endroit où le poser sans ajouter un bloc. */
.gx-camp__score {
    flex: none;
    font: 500 22px/1 var(--gx-mono);
    font-variant-numeric: tabular-nums;
    color: var(--gx-texte);
}

.gx-chrono {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 20px;
}

.gx-chrono__nom {
    font: 400 9px/1 var(--gx-mono);
    letter-spacing: 0.22em;
    color: var(--gx-faible);
}

.gx-chrono__valeur {
    font: 500 30px/1 var(--gx-mono);
    font-variant-numeric: tabular-nums;
    color: var(--gx-texte);
}

/* ---- Le plateau : posé sur le fond, carré, sans cadre ---- */

.gx-aire {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    container-type: size;
}

.gx-aire--plein {
    position: absolute;
    inset: 0;
}

.gx-aire--souple {
    flex: 1;
    min-width: 0;
    min-height: 0;
}

/* Le carré tient dans la plus petite des deux dimensions de son aire, mesurées sur l'aire
   elle-même (`container-type: size`) : le plateau reste carré sans jamais déborder. */
.gx-aire__carre {
    position: relative;
    width: min(100cqw, 100cqh);
    aspect-ratio: 1 / 1;
}

.gx-aire__carre glatax-plateau {
    display: block;
    width: 100%;
    height: 100%;
}

/* Le témoin de la lecture se pose sur l'aire, et non sur le plateau : la maquette le met dans un
   coin de son emplacement, qui est vide, et un vrai plateau y a une case. */
.gx-aire__temoin {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    padding: 7px 12px;
    font: 500 10px/1 var(--gx-mono);
    letter-spacing: 0.18em;
    color: var(--gx-faible);
}

.gx-aire__point {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--gx-faible);
}

.gx-aire__temoin--lit .gx-aire__point {
    background: var(--gx-vert);
}

/* Un coup refusé par l'arbitre. La maquette ne lui garde pas de place : il se pose au pied du
   plateau, et s'en va dès que le suivant est accepté. */
.gx-refus {
    position: absolute;
    right: 20px;
    bottom: 14px;
    left: 20px;
    margin: 0;
    background: var(--gx-surface);
    border: 1px solid var(--gx-danger);
    border-radius: 10px;
    padding: 12px 14px;
    font: 400 12px/1.5 var(--gx-mono);
    color: var(--gx-danger);
    text-align: center;
}

/* ---- Le tchat ---- */

.gx-tchat {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
}

.gx-tchat__fil {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 20px 24px;
}

.gx-bulle__rang {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    justify-content: flex-start;
}

/* Mes messages se lisent à droite, et mon avatar avec eux. */
.gx-bulle__rang--moi {
    flex-direction: row-reverse;
    justify-content: flex-end;
}

.gx-bulle {
    max-width: 62%;
    display: flex;
    flex-direction: column;
    gap: 7px;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 12px;
    padding: 12px 15px;
}

.gx-bulle--moi {
    background: var(--gx-surface);
}

.gx-bulle__tete {
    display: flex;
    align-items: baseline;
    gap: 12px;
}

.gx-bulle__qui {
    flex: 1;
    font: 500 10px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    color: var(--gx-ambre);
}

.gx-bulle--moi .gx-bulle__qui {
    color: var(--gx-vert);
}

.gx-bulle__heure {
    font: 400 10px/1 var(--gx-mono);
    color: var(--gx-faible);
}

.gx-bulle__texte {
    font: 400 14px/1.5 var(--gx-titre-police);
    color: var(--gx-texte);
    text-wrap: pretty;
}

.gx-tchat__envoi {
    flex: none;
    display: flex;
    gap: 8px;
    padding: 14px 24px 20px;
    border-top: 1px solid var(--gx-bord);
}

.gx-tchat__champ {
    flex: 1;
    min-width: 0;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 14px 16px;
    color: var(--gx-texte);
    font: 400 14px/1 var(--gx-titre-police);
    outline: none;
    transition: border-color 0.18s ease;
}

.gx-tchat__champ:focus {
    border-color: var(--gx-vert);
}

.gx-tchat__envoyer {
    flex: none;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 0 20px;
    min-height: 46px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        color 0.18s ease,
        border-color 0.18s ease;
}

.gx-tchat__envoyer:hover {
    color: var(--gx-texte);
    border-color: var(--gx-texte);
}

/* ---- L'historique, et son lecteur ---- */

.gx-lecteur {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: row;
    align-items: stretch;
}

/* Le plateau et sa barre font **une colonne** : c'est ce qui permet à la barre de se centrer
   sous le plateau, et non sous l'écran entier — la liste des coups est à côté d'eux, jamais
   au-dessus. Une partie qui ne se rejoue pas n'a ni l'un ni l'autre, et la colonne s'efface. */
.gx-lecteur__scene {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.gx-lecteur:not(:has(.gx-aire)) .gx-lecteur__scene {
    display: none;
}

/* La liste des coups est toujours rendue — le lecteur y lit le libellé de chaque pas —, et c'est
   le bouton de la barre qui la montre. Elle part cachée, comme dans la maquette. */
.gx-coups {
    display: none;
    flex: none;
    width: 320px;
    border-left: 1px solid var(--gx-bord);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 18px 18px 22px;
}

.gx-lecteur--liste .gx-coups {
    display: block;
}

/* Une partie qui ne se rejoue pas n'a pas de plateau à côté de sa liste : la liste prend la
   place. */
.gx-lecteur:not(:has(.gx-aire)) .gx-coups {
    flex: 1;
    width: auto;
    max-width: 620px;
    border-left: 0;
}

.gx-coups__tete,
.gx-coups__rang {
    display: grid;
    grid-template-columns: 34px 1fr 1fr;
    align-items: baseline;
}

.gx-coups__tete {
    gap: 10px 12px;
    padding-bottom: 4px;
    font: 400 9px/1 var(--gx-mono);
    letter-spacing: 0.18em;
    color: var(--gx-faible);
}

.gx-coups__tete .gx-coups__a,
.gx-coups__tete .gx-coups__b {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gx-coups__tete .gx-coups__a {
    color: var(--gx-camp-a);
}

.gx-coups__tete .gx-coups__b {
    color: var(--gx-camp-b);
}

.gx-coups__corps {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.gx-coups__rang {
    gap: 12px;
    margin: 0 -8px;
    background: none;
    border: 0;
    border-top: 1px solid var(--gx-bord);
    border-radius: 7px;
    padding: 10px 8px;
    cursor: pointer;
    text-align: left;
    transition:
        background 0.18s ease,
        opacity 0.18s ease;
}

.gx-coups__rang--courant {
    background: var(--gx-survol);
}

.gx-coups__rang--avenir {
    opacity: 0.32;
}

.gx-coups__num {
    font: 400 11px/1 var(--gx-mono);
    color: var(--gx-faible);
}

.gx-coups__rang--courant .gx-coups__num {
    color: var(--gx-vert);
}

.gx-coups__rang .gx-coups__a,
.gx-coups__rang .gx-coups__b {
    font: 400 12px/1 var(--gx-mono);
    color: var(--gx-texte);
}

.gx-coups__creux {
    color: var(--gx-faible) !important;
}

.gx-coups__note {
    margin: 16px 0 0;
    font: 400 11px/1.7 var(--gx-mono);
    color: var(--gx-faible);
}

/* ---- La barre du lecteur : une pastille, pas un bandeau ----

   Elle ne tient pas la largeur de l'écran : elle tient ses boutons, et se centre sous le
   plateau. Tout ce qui s'étirait — la jauge, le chronomètre, le geste du coup — en est sorti :
   la position se lit d'un nombre, et le reste se lit dans la liste des coups, que le dernier
   bouton ouvre. */

.gx-barre {
    flex: none;
    align-self: center;
    max-width: calc(100% - 32px);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin: 0 0 22px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    padding: 8px 16px;
}

.gx-transport {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    cursor: pointer;
    color: var(--gx-faible);
    transition:
        background 0.18s ease,
        color 0.18s ease,
        border-color 0.18s ease;
}

.gx-transport:hover {
    color: var(--gx-texte);
    border-color: var(--gx-texte);
    background: var(--gx-survol);
}

.gx-transport span {
    display: flex;
}

.gx-transport svg {
    stroke-width: 2.2;
}

/* La liste des coups est ouverte ou fermée : le bouton se remplit quand elle est là. */
.gx-transport--actif,
.gx-transport--actif:hover {
    background: var(--gx-texte);
    border-color: var(--gx-texte);
    color: var(--gx-fond);
}

/* La lecture est la seule réponse pleine de la barre : c'est le geste qu'on vient faire. Elle
   est d'un cran plus grande que ses deux voisines, et le vert est posé deux fois — le disque et
   le halo. */
.gx-transport--lire {
    width: 46px;
    height: 46px;
    background: var(--gx-vert);
    border-color: var(--gx-vert);
    color: var(--gx-contre);
    box-shadow: 0 4px 14px -6px var(--gx-vert);
    transition:
        filter 0.18s ease,
        box-shadow 0.18s ease;
}

.gx-transport--lire svg {
    stroke-width: 2;
}

.gx-transport--lire:hover {
    border-color: var(--gx-vert);
    background: var(--gx-vert);
    color: var(--gx-contre);
    filter: brightness(1.08);
    box-shadow: 0 6px 18px -6px var(--gx-vert);
}

/* Un triangle penche à gauche de son cadre : on le repousse d'un cheveu pour qu'il se lise au
   centre du disque. */
.gx-transport__joue {
    transform: translateX(1px);
}

/* La vitesse se choisit dans une liste déroulante, la même que celle des formulaires, mise à
   la taille des boutons qui l'entourent et arrondie comme eux. */
/* La largeur est posée : un `select` se réserve de lui-même la place d'une flèche qu'il ne
   dessine plus, et laisserait un trou entre la vitesse et le chevron. */
.gx-liste-deroulante--menue select {
    width: 78px;
    height: 40px;
    border-radius: 999px;
    padding: 0 28px 0 13px;
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.1em;
    color: var(--gx-texte);
}

.gx-liste-deroulante--menue .gx-liste-deroulante__chevron {
    right: 12px;
    margin-top: -6px;
}

/* ---- Les spectateurs ---- */

.gx-public,
.gx-danger {
    position: absolute;
    inset: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 20px 24px 24px;
}

.gx-public > *,
.gx-danger > * {
    width: 100%;
    max-width: 620px;
}

.gx-public__tete,
.gx-danger__tete {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 6px;
}

.gx-public__note {
    margin-left: auto;
    font: 400 10px/1 var(--gx-mono);
    letter-spacing: 0.14em;
    color: var(--gx-faible);
}

.gx-public__rang {
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 12px;
    padding: 17px 18px;
}

.gx-public__corps {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.gx-public__nom {
    font: 500 15px/1 var(--gx-titre-police);
    color: var(--gx-texte);
}

.gx-public__lieu {
    font: 400 11px/1 var(--gx-mono);
    letter-spacing: 0.08em;
    color: var(--gx-faible);
}

/* ---- La zone de danger ---- */

.gx-danger__bloc {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 12px;
    padding: 20px;
}

.gx-danger__texte {
    flex: 1;
    min-width: 220px;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.gx-danger__titre {
    font: 500 16px/1 var(--gx-titre-police);
    color: var(--gx-texte);
}

.gx-danger__note {
    font: 400 13px/1.5 var(--gx-titre-police);
    color: var(--gx-faible);
    text-wrap: pretty;
}

.gx-danger__oui,
.gx-danger__non {
    flex: none;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 9px;
    padding: 14px 18px;
    min-height: 46px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        background 0.18s ease,
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-danger__oui {
    border-color: var(--gx-rouge);
    color: var(--gx-danger);
}

.gx-danger__oui:hover {
    background: var(--gx-rouge);
    color: var(--gx-sur-rouge);
}

.gx-danger__non:hover {
    border-color: var(--gx-danger);
    color: var(--gx-danger);
}

.gx-danger__pied {
    margin: 0;
    padding: 6px 2px;
    font: 400 11px/1.6 var(--gx-mono);
    letter-spacing: 0.1em;
    color: var(--gx-faible);
}

/* Un motif de signalement : la donnée que la maquette n'a pas, posée dans sa boîte de
   confirmation. */
.gx-motifs {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.gx-motif {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 13px 15px;
    cursor: pointer;
    font: 400 13px/1.3 var(--gx-titre-police);
    color: var(--gx-texte);
    transition: border-color 0.18s ease;
}

.gx-motif:has(input:checked) {
    border-color: var(--gx-vert);
}

.gx-motif input {
    accent-color: var(--gx-vert);
}

.gx-motifs__detail {
    line-height: 1.5;
    resize: vertical;
}

/* ---- La fin d'une partie ---- */

/* La maquette ne dessine pas ce dialogue : il prend la fiche des autres surcouches, pour ne pas
   faire tache au milieu de l'écran de jeu. */
.gx-fin {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 6px 0 2px;
}

.gx-fin__verdict {
    font: 700 clamp(22px, 4vw, 28px) / 1 var(--gx-titre-police);
    letter-spacing: 0.18em;
    color: var(--gx-vert);
}

.gx-fin__verdict--nul {
    color: var(--gx-faible);
}

.gx-fin__verdict--perdu {
    color: var(--gx-danger);
}

.gx-fin__score {
    font: 500 30px/1 var(--gx-mono);
    font-variant-numeric: tabular-nums;
    color: var(--gx-texte);
}

.gx-fin__contre {
    font: 400 11px/1.5 var(--gx-mono);
    letter-spacing: 0.08em;
    color: var(--gx-faible);
    text-align: center;
}

.gx-fin__compte {
    display: flex;
    flex-direction: column;
    gap: 1px;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 4px 16px;
}

.gx-fin__ligne {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 11px 0;
    font: 400 13px/1.3 var(--gx-titre-police);
    color: var(--gx-faible);
}

.gx-fin__ligne + .gx-fin__ligne {
    border-top: 1px solid var(--gx-bord);
}

.gx-fin__ligne b {
    font: 500 13px/1.3 var(--gx-mono);
    color: var(--gx-texte);
}

.gx-fin__ligne--total,
.gx-fin__ligne--total b {
    color: var(--gx-vert);
}

/* Deux réponses sont deux colonnes ; la troisième, rejouer contre la Team Glatax, prend sa
   propre ligne au-dessus d'elles. Un pied de 372 px ne tient pas trois boutons côte à côte
   — « CLASSEMENT » déborde seul de son tiers — et rejouer n'est de toute façon pas « ou bien »
   des deux autres : c'est l'action qu'on vient chercher, donc celle qui a la largeur. */
.gx-fin__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.gx-fin__actions > * {
    flex: 1;
    text-align: center;
}

.gx-fin__actions > .gx-fin__rejouer {
    flex: 1 1 100%;
}

.gx-fin__rejouer .gx-invite__oui {
    width: 100%;
}

a.gx-invite__non,
a.gx-invite__oui {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ---- Le rail des vues, et ses bulles ---- */

.gx-rail {
    flex: none;
    width: 72px;
    border-left: 1px solid var(--gx-bord);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 14px 0;
}

.gx-rail__ancre {
    justify-content: center;
}

.gx-rail__espace {
    flex: 1;
}

.gx-rail__ancre--pied {
    padding-top: 8px;
    border-top: 1px solid var(--gx-bord);
}

.gx-onglet {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 11px;
    cursor: pointer;
    color: var(--gx-faible);
    transition:
        background 0.18s ease,
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-onglet:not([aria-current='page']):hover {
    border-color: var(--gx-texte);
    color: var(--gx-texte);
}

.gx-onglet[aria-current='page'] {
    background: var(--gx-texte);
    border-color: var(--gx-texte);
    color: var(--gx-fond);
}

.gx-onglet--danger {
    color: var(--gx-danger);
}

.gx-onglet--danger:not([aria-current='page']):hover {
    border-color: var(--gx-danger);
    color: var(--gx-danger);
}

.gx-onglet--danger[aria-current='page'] {
    background: var(--gx-rouge);
    border-color: var(--gx-rouge);
    color: var(--gx-sur-rouge);
}

.gx-onglet__badge {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 17px;
    height: 17px;
    border-radius: 999px;
    background: var(--gx-ambre);
    color: var(--gx-contre);
    font: 500 9px/17px var(--gx-mono);
    text-align: center;
    padding: 0 4px;
}

/* La bulle d'un bouton du rail ou de la barre : la même boîte, deux ancrages. */
.gx-tip__ancre {
    position: relative;
    display: flex;
}

.gx-tip {
    position: absolute;
    z-index: 20;
    opacity: 0;
    pointer-events: none;
    white-space: nowrap;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 8px;
    padding: 9px 12px;
    font: 500 10px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    color: var(--gx-texte);
    box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 0.8);
    transition: opacity 0.16s ease;
}

.gx-tip--cote {
    top: 50%;
    right: 62px;
    transform: translateY(-50%);
}

.gx-tip--danger {
    border-color: var(--gx-rouge);
    color: var(--gx-danger);
}

/* Au survol, et à la tabulation — mais pas après un clic : un bouton cliqué garde le focus, et
   sa bulle resterait ouverte sur l'écran. */
.gx-tip__ancre:hover .gx-tip,
.gx-tip__ancre:has(:focus-visible) .gx-tip {
    opacity: 1;
}

/* L'écran étroit : la maquette ne dessine pas la partie sur un téléphone. Le temps de jeu passe
   au-dessus des deux camps, la liste des coups sous le plateau, et le rail se resserre. */
@media (max-width: 760px) {
    .gx-duel {
        flex-wrap: wrap;
        gap: 10px;
        padding: 12px 14px;
    }

    .gx-chrono {
        order: -1;
        width: 100%;
        flex-direction: row;
        justify-content: center;
        gap: 12px;
        padding: 0;
    }

    .gx-chrono__valeur {
        font-size: 22px;
    }

    .gx-camp {
        gap: 10px;
        padding: 10px 12px;
    }

    .gx-camp__score {
        font-size: 18px;
    }

    .gx-camp__etat {
        font-size: 9px;
        letter-spacing: 0.1em;
    }

    /* Le lecteur s'empile : le plateau et sa barre gardent leur part de la hauteur, et c'est la
       liste des coups qui défile sous eux. */
    .gx-lecteur {
        flex-direction: column;
    }

    /* La pastille prend la largeur du plateau et répartit : sur un téléphone, ses six commandes
       ne tiendraient pas côte à côte autour d'un centre. */
    .gx-barre {
        width: calc(100% - 16px);
        max-width: none;
        justify-content: space-evenly;
        gap: 4px;
        margin-bottom: 14px;
        padding: 7px 8px;
    }

    .gx-transport {
        width: 36px;
        height: 36px;
    }

    .gx-transport--lire {
        width: 42px;
        height: 42px;
    }

    .gx-liste-deroulante--menue select {
        width: 68px;
        height: 36px;
        padding: 0 24px 0 10px;
    }

    .gx-liste-deroulante--menue .gx-liste-deroulante__chevron {
        right: 9px;
    }

    /* Le plateau empilé est trop étroit pour qu'un témoin se pose à côté : l'icône du bouton de
       lecture dit déjà si la partie se déroule. */
    .gx-aire__temoin {
        display: none;
    }

    .gx-coups {
        flex: 1;
        width: auto;
        min-height: 0;
        border-top: 1px solid var(--gx-bord);
        border-left: 0;
    }

    .gx-lecteur--liste .gx-lecteur__scene {
        flex: none;
        height: 52%;
    }

    .gx-aire {
        padding: 12px;
    }

    .gx-tchat__fil,
    .gx-public,
    .gx-danger {
        padding: 16px;
    }

    .gx-bulle {
        max-width: 84%;
    }

    .gx-rail {
        width: 58px;
    }
}

/* --------------------------------------------------------- les surcouches */

/* A `<dialog>` and not a div: Escape, the focus trap and the inert page behind come from the
   browser, and the maquette's backdrop is exactly what `::backdrop` is for. */
.gx-voile {
    position: fixed;
    inset: 0;
    z-index: 300;
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    margin: 0;
    padding: 84px 24px 24px;
    border: 0;
    background: transparent;
    color: var(--gx-texte);
    /* La fiche tient dans la hauteur ; c'est son corps qui défile, pas le voile. */
    overflow: hidden;
}

.gx-voile:not([open]) {
    display: none;
}

.gx-voile[open] {
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

.gx-voile--centre[open] {
    align-items: center;
    padding: 24px;
}

.gx-voile::backdrop {
    background: var(--gx-voile);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

/* Une fiche ne dépasse jamais la fenêtre : sa tête et son pied restent en vue, et c'est son
   corps qui défile. Une cloche pleine d'invitations se lit donc sans perdre son titre. */
.gx-fiche {
    width: 100%;
    max-width: 420px;
    max-height: 100%;
    background: var(--gx-surface);
    border: 1px solid var(--gx-bord);
    border-radius: 16px;
    padding: 24px;
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.gx-fiche__tete,
.gx-fiche__pied {
    flex: none;
}

.gx-fiche__corps {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: 22px;
    /* Les deux pixels qu'un anneau de focus déborde, et que le défilement couperait. */
    margin: -2px;
    padding: 2px;
}

.gx-fiche--reglages .gx-fiche__corps {
    gap: 26px;
}

.gx-fiche--courte .gx-fiche__corps {
    gap: 20px;
}

.gx-fiche--reglages {
    gap: 26px;
}

.gx-fiche--edition {
    max-width: 460px;
}

.gx-fiche--carte {
    max-width: 560px;
}

.gx-fiche--courte {
    max-width: 400px;
    padding: 28px 26px 22px;
    gap: 20px;
}

.gx-fiche__tete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.gx-fiche__titre {
    font: 700 17px/1 var(--gx-titre-police);
    letter-spacing: 0.14em;
}

.gx-fermer {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    cursor: pointer;
    color: var(--gx-faible);
    flex: none;
}

.gx-fermer:hover {
    color: var(--gx-texte);
}

.gx-bloc {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.gx-bloc--reglage {
    gap: 10px;
}

.gx-etiquette {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.22em;
    color: var(--gx-faible);
}

.gx-etiquette--espace {
    padding-top: 16px;
}

.gx-entree-texte {
    width: 100%;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 14px 15px;
    color: var(--gx-texte);
    font: 400 15px/1 var(--gx-mono);
    letter-spacing: 0.06em;
    outline: none;
    transition: border-color 0.18s ease;
}

.gx-entree-texte:focus {
    border-color: var(--gx-vert);
}

.gx-liste-deroulante {
    position: relative;
    display: flex;
}

.gx-liste-deroulante select {
    appearance: none;
    -webkit-appearance: none;
    padding: 14px 40px 14px 15px;
    cursor: pointer;
}

.gx-liste-deroulante__chevron {
    position: absolute;
    right: 14px;
    top: 50%;
    margin-top: -7px;
    color: var(--gx-faible);
    pointer-events: none;
}

.gx-choix {
    display: flex;
    gap: 8px;
}

.gx-choix__option {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 14px 6px;
    cursor: pointer;
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.12em;
    background: transparent;
    color: var(--gx-faible);
}

.gx-choix__option--large {
    padding: 14px;
    font-size: 13px;
    letter-spacing: 0.14em;
}

/* Deux réponses prises, deux couleurs : la maquette peint le genre retenu en vert — c'est une
   réponse de la fiche —, et la langue ou le thème en couleur du texte, parce que ce sont des
   réglages et non des réponses. */
.gx-choix__option[aria-pressed='true'] {
    background: var(--gx-vert);
    color: var(--gx-contre);
}

.gx-choix__option--large[aria-pressed='true'] {
    background: var(--gx-texte);
    color: var(--gx-fond);
}

.gx-fiche__pied {
    display: flex;
    gap: 8px;
    padding-top: 2px;
}

.gx-valider {
    flex: 1;
    background: var(--gx-vert);
    border: 1px solid var(--gx-vert);
    border-radius: 10px;
    padding: 14px;
    cursor: pointer;
    color: var(--gx-contre);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition: filter 0.18s ease;
}

.gx-valider:hover {
    color: var(--gx-contre);
    filter: brightness(1.08);
}

.gx-annuler {
    flex: 1;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 10px;
    padding: 14px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-annuler:hover {
    border-color: var(--gx-texte);
    color: var(--gx-texte);
}

/* --------------------------------------------------- la cloche, et ses défis */

.gx-fiche .gx-liste {
    gap: 8px;
}

.gx-defi {
    display: flex;
    flex-direction: column;
    gap: 14px;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 11px;
    padding: 16px 16px 14px;
}

.gx-defi__ligne {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.gx-defi__texte {
    flex: 1;
    min-width: 0;
    font: 500 15px/1.3 var(--gx-titre-police);
    color: var(--gx-texte);
    text-wrap: pretty;
}

.gx-defi__nom {
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color 0.18s ease;
}

.gx-defi__nom:hover {
    color: var(--gx-ambre);
}

.gx-defi__quand {
    flex: none;
    font: 400 11px/1 var(--gx-mono);
    color: var(--gx-faible);
}

.gx-defi__actions {
    display: flex;
    gap: 8px;
}

/* Accepter et refuser sont deux écritures, donc deux formulaires : chacun porte la moitié. */
.gx-defi__actions form {
    flex: 1;
    display: flex;
}

.gx-defi__oui {
    flex: 1;
    background: var(--gx-ambre);
    border: 1px solid var(--gx-ambre);
    border-radius: 9px;
    padding: 12px;
    cursor: pointer;
    color: var(--gx-contre);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition: filter 0.18s ease;
}

.gx-defi__oui:hover {
    color: var(--gx-contre);
    filter: brightness(1.08);
}

.gx-defi__non {
    flex: 1;
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 9px;
    padding: 12px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-defi__non:hover {
    border-color: var(--gx-danger);
    color: var(--gx-danger);
}

/* The player card read in a dialog: the same blocks as the profile screen, one notch smaller and
   laid on the page colour rather than the surface, because the dialog is the surface. */
.gx-carte__identite {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 20px;
    background: var(--gx-fond);
    border: 1px solid var(--gx-bord);
    border-radius: 14px;
    padding: 20px;
}

.gx-carte__identite .gx-portrait {
    width: 88px;
    height: 88px;
    padding: 7px;
}

.gx-carte__identite .gx-identite__nom {
    font-size: clamp(24px, 4vw, 34px);
    overflow: hidden;
    text-overflow: ellipsis;
}

.gx-stats--carte {
    margin-top: -10px;
}

.gx-stats--carte .gx-stat,
.gx-stats--carte .gx-stats__onglet,
.gx-carte__meta .gx-meta__ligne {
    background: var(--gx-fond);
}

.gx-stats--carte .gx-stats__onglet[aria-pressed='true'] {
    background: var(--gx-teinte);
}

.gx-stats--carte .gx-stat {
    padding: 18px;
}

.gx-stats--carte .gx-stat__valeur {
    font-size: 28px;
}

.gx-stats--carte .gx-stat__ligne {
    padding: 6px 0;
}

.gx-carte__meta {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: -10px;
}

.gx-carte__meta .gx-meta__ligne {
    padding: 14px 18px;
}

.gx-carte__section {
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.24em;
    color: var(--gx-faible);
}

/* L'invitation : une question, deux réponses. */
.gx-invite__tete {
    display: flex;
    align-items: center;
    gap: 12px;
}

.gx-invite__question {
    font: 500 clamp(19px, 3vw, 24px) / 1.3 var(--gx-titre-police);
    color: var(--gx-texte);
    text-wrap: pretty;
}

.gx-invite__actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    flex-wrap: wrap;
}

.gx-invite__non {
    background: none;
    border: 1px solid var(--gx-bord);
    border-radius: 9px;
    padding: 14px 18px;
    cursor: pointer;
    color: var(--gx-faible);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition:
        border-color 0.18s ease,
        color 0.18s ease;
}

.gx-invite__non:hover {
    border-color: var(--gx-texte);
    color: var(--gx-texte);
}

.gx-invite__oui {
    background: var(--gx-ambre);
    border: 1px solid var(--gx-ambre);
    border-radius: 9px;
    padding: 14px 20px;
    cursor: pointer;
    color: var(--gx-contre);
    font: 500 12px/1 var(--gx-mono);
    letter-spacing: 0.16em;
    transition: filter 0.18s ease;
}

.gx-invite__oui:hover {
    color: var(--gx-contre);
    filter: brightness(1.08);
}

/* La même boîte, pour une réponse définitive : abandonner, signaler. */
.gx-invite__oui--sang,
.gx-invite__oui--sang:hover {
    background: var(--gx-rouge);
    border-color: var(--gx-rouge);
    color: var(--gx-sur-rouge);
}

/* ------------------------------------------------------------- le téléphone */

@media (max-width: 620px) {
    .gx-bande__rang {
        padding: 12px 16px;
        gap: 10px;
    }

    /* Le logo porte la marque à lui seul : sur un téléphone, `RETOUR`, le mot GLATAX et le
       bouton de connexion ne tiennent pas côte à côte, et c'est le mot qui part — comme le
       pseudo du lecteur juste à côté. */
    .gx-marque__nom {
        display: none;
    }

    .gx-moi__nom {
        display: none;
    }

    .gx-moi {
        padding: 7px 8px;
    }

    .gx-colonne {
        padding: 64px 16px 48px;
    }

    .gx-noel {
        padding: 26px 20px 22px;
    }

    .gx-entree {
        gap: 16px;
        padding: 24px 20px;
    }

    .gx-rang {
        gap: 12px;
        padding: 18px 16px;
    }

    .gx-rang--solo {
        gap: 10px;
        padding: 14px 8px 12px;
    }

    .gx-ligne,
    .gx-classe {
        gap: 12px;
        padding: 15px 14px;
    }

    .gx-tableau__tete {
        gap: 12px;
        padding: 36px 14px 12px;
    }

    .gx-panneau,
    .gx-panneau--large {
        padding: 28px 18px 24px;
    }

    .gx-voile {
        padding: 72px 14px 14px;
    }

    .gx-regle {
        grid-template-columns: 36px minmax(0, 1fr);
        gap: 12px;
        padding: 20px 18px;
    }

    .gx-profil__actions {
        flex-wrap: wrap;
    }
}

/* ------------------------------------------------------------------------
   Les écrans que la maquette ne couvre pas — une battle, la partie découverte,
   la connexion, la page 404 — gardent leurs règles telles quelles. Elles ne
   lisent que des jetons `--g-*`, désormais des alias des nouveaux : elles
   changent donc de peau, et suivent le thème clair, sans être réécrites.
   ------------------------------------------------------------------------ */

/* Every icon of the module is an open path: the stroke is the rule, the fill the exception, and
   each component only restates its size. */
/* `hidden` has to win over a component's own `display`: several blocks of the page are grids or
   columns that a controller hides and shows again. */
[hidden] {
    display: none !important;
}

svg {
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ---- Shell ---- */

.g-app {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.g-bandeau {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    height: 46px;
    padding: 0 12px;
    background: var(--g-bandeau);
    border-bottom: 1px solid var(--g-creux);
}

.g-bandeau__marque {
    flex: none;
    display: inline-flex;
    align-items: center;
    height: 36px;
    padding: 0 6px;
    border: none;
    background: none;
    color: #fff;
    font-family: 'Bungee', 'Roboto', sans-serif;
    font-size: 15px;
    letter-spacing: 0.06em;
    cursor: pointer;
}

.g-bandeau__marque:hover {
    color: #bfe0f5;
    text-decoration: none;
}

.g-bandeau__nav {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

.g-bandeau__droite {
    display: flex;
    align-items: center;
    gap: 8px;
}

.g-bandeau__separateur {
    flex: none;
    width: 1px;
    height: 22px;
    margin: 0 2px;
    background: rgb(255 255 255 / 28%);
}

.g-rond {
    position: relative;
    display: inline-flex;
    flex: none;
}

.g-carre {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--g-accent-clair);
    border-radius: var(--g-rayon);
    background: var(--g-bandeau-creux);
    color: #fff;
    cursor: pointer;
}

.g-carre:hover {
    background: var(--g-bandeau-survol);
    color: #fff;
    text-decoration: none;
}

.g-carre[aria-current='page'] {
    background: var(--g-bandeau-survol);
}

.g-carre svg {
    display: block;
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-carre--menu svg {
    width: 18px;
    height: 18px;
}

.g-carre__point {
    position: absolute;
    top: -4px;
    right: -4px;
    width: 11px;
    height: 11px;
    border: 2px solid var(--g-bandeau);
    border-radius: 50%;
    background: var(--g-vert);
    animation: g-pulse 1.8s infinite;
}

.g-avatar-lien {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 32px;
    height: 32px;
    border: 2px solid var(--g-accent-clair);
    border-radius: 50%;
    background: var(--g-bandeau-creux);
    color: #fff;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 0.02em;
}

.g-avatar-lien:hover,
.g-avatar-lien[aria-current='page'] {
    background: var(--g-bandeau-survol);
    color: #fff;
    text-decoration: none;
}

.g-cloche {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 36px;
    height: 36px;
    padding: 0;
    border: none;
    border-radius: var(--g-rayon);
    background: none;
    color: #fff;
    cursor: pointer;
}

.g-cloche:hover {
    color: #bfe0f5;
}

.g-cloche svg {
    display: block;
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-cloche__badge {
    position: absolute;
    top: 2px;
    right: 1px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    border: 1px solid var(--g-bandeau);
    border-radius: 8px;
    background: var(--g-alerte);
    color: #fff;
    font-size: 10px;
    font-weight: bold;
    line-height: 14px;
    text-align: center;
}

.g-badge-invite {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 7px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-creux);
    color: var(--g-second);
    font-size: 11px;
    font-weight: bold;
}

/* The header's tooltip and the one on a battle's rail: same box, two anchorings. */
.g-tip {
    position: absolute;
    z-index: 9;
    top: calc(100% + 6px);
    left: 50%;
    padding: 7px 11px;
    transform: translateX(-50%);
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-creux);
    color: #fff;
    font-size: 13px;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    box-shadow: 0 5px 14px rgb(7 17 25 / 55%);
    transition: opacity 0.12s linear;
}

.g-rond:hover .g-tip,
.g-rond:focus-within .g-tip {
    opacity: 1;
}

.g-tip--gauche {
    left: 0;
    transform: none;
}

.g-tip--droite {
    right: 0;
    left: auto;
    transform: none;
}

.g-tip--cote {
    top: 50%;
    right: calc(100% + 8px);
    left: auto;
    transform: translateY(-50%);
}

.g-defile {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
    padding: 12px;
    overflow: auto;
}

.g-nav-bas {
    display: flex;
    flex: none;
    align-items: stretch;
    height: 58px;
    background: var(--g-bandeau);
    border-top: 1px solid var(--g-creux);
}

.g-nav-bas__item {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: 44px;
    border: none;
    background: var(--g-bandeau);
    color: #fff;
    cursor: pointer;
}

.g-nav-bas__item:hover,
.g-nav-bas__item[aria-current='page'] {
    background: var(--g-bandeau-survol);
    color: #fff;
    text-decoration: none;
}

.g-nav-bas__item--menu {
    border-right: 1px solid var(--g-creux);
    border-left: 1px solid var(--g-creux);
    background: var(--g-creux);
}

.g-nav-bas__item--menu:hover {
    background: var(--g-creux);
}

.g-nav-bas__item svg {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-nav-bas__item span {
    max-width: 100%;
    overflow: hidden;
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.g-nav-bas__item--arene span,
.g-nav-bas__item--menu span {
    text-transform: uppercase;
}

/* The header carries the wide navigation, the bottom bar the narrow one: never both. */
@media (width >= 560px) {
    .g-etroit {
        display: none !important;
    }
}

@media (width < 560px) {
    .g-large {
        display: none !important;
    }
}

/* ---- Panels ---- */

.g-panneau {
    overflow: hidden;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
}

.g-panneau__tete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 7px 10px 7px 12px;
    background: var(--g-creux);
    color: #fff;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.g-panneau__tete > :last-child:not(:only-child) {
    margin-left: auto;
}

.g-panneau__note {
    font-family: var(--g-mono);
    font-size: 11px;
    font-weight: normal;
    letter-spacing: 0;
    text-transform: none;
    color: var(--g-second);
}

.g-panneau__compteur {
    min-width: 20px;
    padding: 1px 5px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-bandeau);
    color: #fff;
    font-size: 11px;
    font-weight: bold;
    text-align: center;
}

.g-panneau__corps {
    padding: 12px;
}

.g-panneau__pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 7px 12px;
    border-top: 1px solid var(--g-bord);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--g-second);
}

.g-vide {
    padding: 22px 16px;
    font-size: 12px;
    text-align: center;
    color: var(--g-second);
}

/* ---- List rows ---- */

.g-ligne {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--g-bord);
}

.g-ligne:hover {
    background: var(--g-survol);
}

.g-ligne--clic {
    cursor: pointer;
}

.g-ligne__corps {
    flex: 1;
    min-width: 0;
}

.g-ligne__nom {
    display: block;
    overflow: hidden;
    font-size: 13px;
    color: var(--g-texte);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.g-ligne__nom a,
.g-nom-clic {
    padding: 0;
    border: none;
    background: none;
    color: var(--g-texte);
    font: inherit;
    cursor: pointer;
}

.g-ligne__nom a:hover,
.g-nom-clic:hover {
    color: var(--g-titre);
    text-decoration: none;
}

.g-ligne__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 2px;
    font-size: 11px;
    color: var(--g-second);
}

.g-ligne__detail {
    display: block;
    overflow: hidden;
    font-size: 11px;
    color: var(--g-second);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.g-meta {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--g-second);
}

.g-meta svg {
    flex: none;
    width: 12px;
    height: 12px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-mode {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 2px;
    font-size: 11px;
}

.g-mode::before {
    content: '';
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentcolor;
}

.g-mode--auto {
    color: var(--g-vert);
}

.g-mode--invitation {
    color: var(--g-or);
}

.g-chiffre {
    font-family: var(--g-mono);
    font-size: 12px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 32px;
    height: 32px;
    border: 2px solid var(--g-bord);
    border-radius: 50%;
    background: var(--g-avatar);
    font-size: 12px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-avatar--vedette {
    border-color: var(--g-accent);
}

.g-avatar--grand {
    width: 34px;
    height: 34px;
}

.g-avatar--petit {
    width: 30px;
    height: 30px;
    font-size: 11px;
}

/* A fight's badge: two sets of initials split on the diagonal, like a poster. */
.g-affiche {
    position: relative;
    flex: none;
    width: 36px;
    height: 36px;
    overflow: hidden;
    border: 2px solid var(--g-bord-vif);
    border-radius: 50%;
    background: var(--g-avatar);
}

.g-affiche__haut,
.g-affiche__bas {
    position: absolute;
    inset: 0;
}

.g-affiche__haut {
    background: var(--g-bleu-sourd);
    clip-path: polygon(0 0, 100% 0, 0 100%);
}

.g-affiche__bas {
    background: #0d2131;
    clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.g-affiche__trait {
    position: absolute;
    top: 50%;
    left: -20%;
    width: 140%;
    height: 2px;
    background: var(--g-surface);
    transform: rotate(-45deg);
}

.g-affiche__a,
.g-affiche__b {
    position: absolute;
    font-size: 9px;
    font-weight: bold;
}

.g-affiche__a {
    top: 5px;
    left: 7px;
    color: var(--g-titre);
}

.g-affiche__b {
    right: 7px;
    bottom: 5px;
    color: var(--g-texte);
}

.g-etiquette {
    flex: none;
    padding: 2px 7px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-3);
    color: var(--g-second);
    font-size: 11px;
    font-weight: bold;
}

.g-etiquette--actif {
    border-color: var(--g-bord-fort);
    background: var(--g-bandeau);
    color: #fff;
}

/* ---- Buttons ---- */

.g-bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 36px;
    padding: 8px 12px;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    color: var(--g-texte);
    cursor: pointer;
    white-space: nowrap;
}

.g-bouton:hover {
    background: var(--g-survol);
    color: var(--g-texte);
    text-decoration: none;
}

.g-bouton svg {
    flex: none;
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-bouton[disabled],
.g-bouton[aria-disabled='true'] {
    cursor: not-allowed;
    opacity: 0.5;
}

.g-bouton--principal {
    border-color: var(--g-bord-fort);
    background: var(--g-bandeau);
    color: #fff;
    font-weight: bold;
}

.g-bouton--principal:hover {
    background: var(--g-bandeau-survol);
    color: #fff;
}

.g-bouton--secondaire {
    border-color: var(--g-bord-vif);
    background: var(--g-surface);
}

.g-bouton--discret {
    background: var(--g-surface-3);
    color: var(--g-second);
}

.g-bouton--discret:hover {
    color: var(--g-texte);
}

.g-bouton--danger {
    border-color: var(--g-rouge);
    background: var(--g-danger-plein);
    color: #fff;
    font-weight: bold;
}

.g-bouton--danger:hover {
    background: #a83a3a;
}

.g-bouton--danger-doux {
    border-color: var(--g-rouge);
    background: var(--g-danger-fond-2);
    color: var(--g-danger-texte);
    font-weight: bold;
}

.g-bouton--danger-doux:hover {
    background: #5a2626;
}

.g-bouton--petit {
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.g-bouton--large {
    width: 100%;
    min-height: 44px;
}

.g-bouton--haut {
    min-height: 40px;
    padding: 10px 18px;
}

.g-bouton--jouer {
    align-self: flex-start;
    min-height: 44px;
    padding: 10px 24px;
    border-color: var(--g-accent);
    background: var(--g-bandeau);
    color: #fff;
    font-family: 'Bungee', sans-serif;
    font-size: 15px;
    letter-spacing: 0.08em;
    gap: 10px;
}

.g-bouton--jouer:hover {
    background: var(--g-bandeau-survol);
    color: #fff;
}

.g-bouton--jouer svg {
    width: 18px;
    height: 18px;
    fill: currentcolor;
    stroke: none;
}

.g-bouton-nu {
    display: flex;
    padding: 4px;
    border: none;
    background: none;
    color: var(--g-second);
    cursor: pointer;
}

.g-bouton-nu:hover {
    color: #fff;
}

.g-bouton-nu svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-tourniquet {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgb(255 255 255 / 35%);
    border-top-color: #fff;
    border-radius: 50%;
    animation: g-tourne 0.7s linear infinite;
}

/* ---- Fields ---- */

.g-champ {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.g-champ > span {
    font-size: 12px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-saisie {
    width: 100%;
    min-height: 40px;
    padding: 9px 10px;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    color: var(--g-texte);
    font-size: 13px;
}

.g-saisie::placeholder {
    color: var(--g-faible);
}

textarea.g-saisie {
    min-height: 80px;
    resize: vertical;
    background: var(--g-surface-2);
}

select.g-saisie {
    appearance: none;
    cursor: pointer;
    background-image: linear-gradient(45deg, transparent 50%, var(--g-second) 50%),
        linear-gradient(135deg, var(--g-second) 50%, transparent 50%);
    background-position: calc(100% - 14px) calc(50% + 1px), calc(100% - 9px) calc(50% + 1px);
    background-size: 5px 5px;
    background-repeat: no-repeat;
    padding-right: 26px;
}

.g-saisie--compacte {
    min-height: 36px;
    padding: 7px 9px;
    font-size: 12px;
}

.g-note {
    font-size: 11px;
    color: var(--g-second);
    text-wrap: pretty;
}

.g-note--faible {
    color: var(--g-faible);
}

/* ---- Arena ---- */

.g-heros {
    overflow: hidden;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: linear-gradient(155deg, #23405a 0%, #1a2b3c 55%, #16222e 100%);
}

.g-heros__corps {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px 16px 16px;
}

.g-heros__salut {
    font-size: 13px;
    color: var(--g-second);
}

.g-heros__titre {
    font-family: 'Bungee', sans-serif;
    font-size: 21px;
    line-height: 1.15;
    letter-spacing: 0.02em;
    color: var(--g-texte);
    text-wrap: pretty;
}

.g-accroches {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.g-accroche {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-3);
    font-size: 11px;
    color: var(--g-texte);
}

.g-accroche::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--g-puce, var(--g-accent));
}

.g-attente {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--g-bord-vif);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
}

.g-attente__tete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.g-attente__vivant {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--g-vert);
    animation: g-pulse 1.8s infinite;
}

.g-attente__titre {
    font-size: 13px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-attente__partage {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--g-bord);
}

.g-qr {
    flex: none;
    width: 112px;
    height: 112px;
    padding: 8px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: #fff;
}

.g-qr svg {
    display: block;
    width: 100%;
    height: 100%;
}

.g-attente__code {
    display: flex;
    flex: 1 1 170px;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.g-code-texte {
    font-family: var(--g-mono);
    font-size: 20px;
    font-weight: bold;
    letter-spacing: 0.16em;
    color: var(--g-texte);
}

.g-bandeau-info {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 12px;
    border: 1px solid var(--g-bord-vif);
    border-radius: var(--g-rayon);
    background: var(--g-bleu-sourd);
    font-size: 12px;
    color: var(--g-texte);
}

.g-bandeau-info svg {
    flex: none;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: var(--g-titre);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-bandeau-info > span {
    flex: 1;
    min-width: 0;
}

.g-bandeau-info--erreur {
    border-color: var(--g-rouge);
    background: var(--g-danger-fond-2);
    color: var(--g-danger-texte);
}

.g-bandeau-info--erreur svg {
    stroke: var(--g-danger-texte);
}

/* ---- Battle ---- */

/* The battle screen takes the whole scroll area rather than its content's height: that is what
   gives the board a height to fit into. A view with more to show than there is room — a long
   thread — grows past it and scrolls, as before. */
.g-battle {
    display: flex;
    flex: 1;
    align-items: stretch;
    gap: 10px;
    min-height: 0;
}

.g-battle__vue {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}

.g-camps {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    padding: 12px;
}

.g-camp {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 10px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-2);
}

.g-camp--trait {
    border-color: var(--g-accent);
}

.g-camp__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 44px;
    height: 44px;
    overflow: hidden;
    border: 1px solid var(--g-bord);
    border-radius: 50%;
    background: repeating-linear-gradient(135deg, #223243 0 6px, #1b2836 6px 12px);
    font-size: 12px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-camp__corps {
    flex: 1;
    min-width: 0;
}

.g-camp__nom {
    overflow: hidden;
    font-size: 13px;
    font-weight: bold;
    color: var(--g-texte);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.g-camp__etat {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--g-second);
}

.g-camp__etat::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentcolor;
}

.g-camp__etat--present {
    color: var(--g-vert);
}

.g-camp__score {
    flex: none;
    font-family: var(--g-mono);
    font-size: 24px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-battle__rythme {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 7px 12px;
    border-top: 1px solid var(--g-bord);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--g-second);
}

.g-battle__rythme .g-meta {
    font-family: var(--g-mono);
    letter-spacing: 0;
    text-transform: none;
    color: var(--g-texte);
}

/* The board's panel takes whatever height is left, and the board fits inside it. A laptop window
   is wider than it is tall: a board sized on the width alone went under the fold, and the panel,
   which clips, cut it off rather than scrolling. */
.g-panneau--plateau {
    display: flex;
    flex: 1;
    flex-direction: column;
    /* A floor, under which the board stops shrinking and the screen scrolls instead: a phone
       held sideways has barely more than 300 px of height, and a thumbnail is not a game. */
    min-height: 320px;
}

/* The board is square: on a wide screen, letting it take the whole column would give cells the
   size of a hand. The mock-up shows it 480 px a side. `container-type` is what lets the width be
   read off the height as well — the board is the largest square that fits both ways. */
.g-plateau {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    min-height: 0;
    padding: 10px;
    container-type: size;
}

glatax-plateau {
    width: min(520px, 100cqw, 100cqh);
}

.g-panneau__outils {
    display: flex;
    align-items: center;
    gap: 6px;
}

.g-panneau__outils .g-bouton-nu svg {
    width: 15px;
    height: 15px;
}

/* In fullscreen the panel is the whole screen, and the board takes all of it: no 520 px cap, and
   the screen's own background, since a fullscreen element is painted on black by default. */
.g-panneau--plateau:fullscreen {
    justify-content: center;
    border: none;
    border-radius: 0;
    background: var(--g-fond);
}

.g-panneau--plateau:fullscreen glatax-plateau {
    width: min(100cqw, 100cqh);
}

.g-menu-battle {
    display: flex;
    flex: none;
    flex-direction: column;
    gap: 6px;
    align-self: flex-start;
    padding: 8px;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
}

.g-menu-battle__item {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-2);
    color: var(--g-second);
    cursor: pointer;
}

.g-menu-battle__item:hover {
    background: var(--g-survol);
    color: var(--g-titre);
    text-decoration: none;
}

.g-menu-battle__item[aria-current='page'] {
    border-color: var(--g-accent-clair);
    background: var(--g-bandeau);
    color: #fff;
}

.g-menu-battle__item svg {
    display: block;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-menu-battle__item--danger {
    margin-top: 10px;
    border-color: var(--g-danger-bord);
    color: var(--g-danger-sourd);
}

.g-menu-battle__item--danger:hover {
    background: var(--g-danger-fond-2);
    color: var(--g-danger-texte);
}

.g-menu-battle__item--danger[aria-current='page'] {
    border-color: var(--g-rouge);
    background: var(--g-danger-plein);
    color: #fff;
}

.g-menu-battle__badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    border: 1px solid var(--g-surface);
    border-radius: 8px;
    background: var(--g-alerte);
    color: #fff;
    font-size: 10px;
    font-weight: bold;
    line-height: 14px;
    text-align: center;
}

.g-coup {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-top: 1px solid var(--g-bord);
}

.g-coup__num {
    flex: none;
    width: 26px;
    font-family: var(--g-mono);
    font-size: 11px;
    color: var(--g-second);
}

.g-coup__puce {
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
}

.g-coup__puce--a {
    background: var(--g-accent);
}

.g-coup__puce--b {
    background: var(--g-ambre);
}

.g-coup__texte {
    flex: 1;
    min-width: 0;
    font-size: 13px;
}

.g-coup__heure {
    flex: none;
    font-family: var(--g-mono);
    font-size: 11px;
    color: var(--g-second);
}

.g-tchat__fil {
    display: flex;
    flex-direction: column;
    gap: 7px;
    max-height: 190px;
    padding: 10px 12px;
    overflow: auto;
}

.g-bulle {
    max-width: 78%;
    align-self: flex-start;
    padding: 7px 9px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-2);
}

.g-bulle--moi {
    align-self: flex-end;
    border-color: var(--g-bord-vif);
    background: var(--g-surface-3);
}

.g-bulle__heure {
    margin-top: 3px;
    font-family: var(--g-mono);
    font-size: 10px;
    color: var(--g-second);
}

.g-tchat__envoi {
    display: flex;
    gap: 8px;
    padding: 8px 10px;
    border-top: 1px solid var(--g-bord);
}

.g-danger {
    border-color: var(--g-danger-bord);
}

.g-danger .g-panneau__tete {
    background: var(--g-danger-fond);
    color: var(--g-danger-texte);
}

.g-danger__bloc {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 14px;
}

.g-danger__bloc + .g-danger__bloc {
    border-top: 1px solid var(--g-danger-bord);
}

.g-danger__texte {
    flex: 1 1 200px;
    min-width: 0;
}

.g-danger__titre {
    font-size: 13px;
    font-weight: bold;
    color: var(--g-texte);
}

/* ---- Player card ---- */

.g-carte {
    overflow: hidden;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: linear-gradient(155deg, #23405a 0%, #1a2b3c 55%, #16222e 100%);
}

.g-carte__corps {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 14px;
    padding: 14px;
}

.g-carte__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 84px;
    height: 84px;
    border: 3px solid var(--g-accent);
    border-radius: 50%;
    background: var(--g-avatar);
    font-family: 'Bungee', sans-serif;
    font-size: 24px;
    color: var(--g-titre);
}

.g-carte__identite {
    display: flex;
    flex: 1 1 180px;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
    padding-right: 96px;
}

.g-carte__nom {
    font-size: 20px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-carte__slogan {
    font-size: 13px;
    font-style: italic;
    color: var(--g-texte);
}

.g-carte__lieu {
    font-size: 11px;
    color: var(--g-second);
}

.g-carte__niveau {
    align-self: flex-start;
    margin-top: 4px;
    padding: 3px 7px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-3);
    font-size: 11px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-carte__modifier {
    position: absolute;
    top: 12px;
    right: 12px;
}

.g-carte__modifier svg {
    stroke: var(--g-accent);
}

.g-rangee-bouton {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 52px;
    padding: 10px 12px;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    color: var(--g-texte);
    text-align: left;
    cursor: pointer;
}

.g-rangee-bouton:hover {
    background: var(--g-surface-3);
    color: var(--g-texte);
    text-decoration: none;
}

.g-rangee-bouton__libelle {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: bold;
}

.g-rangee-bouton__fleche {
    flex: none;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: var(--g-second);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-positions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding: 12px;
}

.g-positions__groupe {
    display: flex;
    flex: 1 1 220px;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
    padding: 10px;
    border-radius: var(--g-rayon);
    background: var(--g-surface-4);
}

.g-positions__titre {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--g-second);
}

.g-positions__titre svg {
    flex: none;
    width: 14px;
    height: 14px;
    fill: none;
    stroke: var(--g-accent);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-positions__rangee {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: space-between;
}

.g-position {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    min-width: 0;
    padding: 8px 10px;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: #243545;
    text-align: center;
}

.g-position__rang {
    font-family: var(--g-mono);
    font-size: 16px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-position__lieu {
    font-family: var(--g-mono);
    font-size: 12px;
    color: var(--g-texte);
}

.g-position--or {
    border-color: #f2c75c;
    background: linear-gradient(155deg, #f2c75c 0%, #b8862b 100%);
}

.g-position--or .g-position__rang {
    color: #3a2a07;
}

.g-position--or .g-position__lieu {
    color: #51380a;
}

.g-position--argent {
    border-color: #dfe7ee;
    background: linear-gradient(155deg, #dfe7ee 0%, #93a4b4 100%);
}

.g-position--argent .g-position__rang {
    color: #22303d;
}

.g-position--argent .g-position__lieu {
    color: #2f3f4e;
}

.g-position--bronze {
    border-color: #d9955c;
    background: linear-gradient(155deg, #d9955c 0%, #93562a 100%);
}

.g-position--bronze .g-position__rang {
    color: #3a1f0a;
}

.g-position--bronze .g-position__lieu {
    color: #4a2a10;
}

.g-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
}

.g-stat {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    padding: 10px 12px;
    border-right: 1px solid var(--g-bord);
    border-bottom: 1px solid var(--g-bord);
    text-align: center;
}

.g-stat__label {
    font-size: 11px;
    color: var(--g-second);
}

.g-stat__valeur {
    font-family: var(--g-mono);
    font-size: 17px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-stat__note {
    font-family: var(--g-mono);
    font-size: 10px;
    color: var(--g-faible);
}

.g-badges {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 14px 8px;
    padding: 14px 12px;
}

.g-badge {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    min-width: 0;
    text-align: center;
}

.g-badge__rond {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 56px;
    height: 56px;
    border: 2px solid var(--g-bord);
    border-radius: 50%;
    background: var(--g-surface-2);
}

.g-badge__rond svg {
    width: 26px;
    height: 26px;
    fill: none;
    stroke: #5c6f81;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-badge__titre {
    font-size: 11px;
    line-height: 1.25;
    color: #6d8094;
    text-wrap: pretty;
}

.g-badge--obtenu .g-badge__titre {
    color: var(--g-texte);
}

.g-histo {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    padding: 14px 12px 10px;
}

.g-histo__legende {
    display: flex;
    gap: 10px;
    margin-left: auto;
    font-size: 11px;
    font-weight: normal;
    letter-spacing: 0;
    text-transform: none;
    color: var(--g-second);
}

.g-histo__legende span {
    display: flex;
    align-items: center;
    gap: 5px;
}

.g-puce-carree {
    width: 9px;
    height: 9px;
    border-radius: 2px;
}

.g-puce-carree--g {
    background: var(--g-accent);
}

.g-puce-carree--n {
    background: #c9d7e4;
}

.g-puce-carree--p {
    background: #44607a;
}

.g-mois {
    position: relative;
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    min-width: 0;
}

.g-mois__total {
    min-height: 12px;
    font-family: var(--g-mono);
    font-size: 10px;
    color: var(--g-faible);
}

.g-mois__barre {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    width: 100%;
    max-width: 26px;
    height: 118px;
    overflow: hidden;
    border-radius: 2px;
    background: var(--g-surface-4);
}

.g-mois__p,
.g-mois__n,
.g-mois__g {
    flex: none;
}

.g-mois__p {
    background: #44607a;
}

.g-mois__n {
    background: #c9d7e4;
}

.g-mois__g {
    background: var(--g-accent);
}

.g-mois__bulle {
    position: absolute;
    bottom: 132px;
    left: 50%;
    z-index: 5;
    display: none;
    width: 168px;
    padding: 8px 10px;
    transform: translateX(-50%);
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-creux);
    text-align: left;
    pointer-events: none;
    box-shadow: var(--g-ombre-flottante);
}

.g-mois:hover .g-mois__bulle,
.g-mois:focus-within .g-mois__bulle {
    display: block;
}

.g-mois:first-child .g-mois__bulle,
.g-mois:nth-child(2) .g-mois__bulle {
    left: 0;
    transform: none;
}

.g-mois:last-child .g-mois__bulle,
.g-mois:nth-last-child(2) .g-mois__bulle {
    right: 0;
    left: auto;
    transform: none;
}

.g-mois__bulle-titre {
    font-size: 11px;
    font-weight: bold;
    color: var(--g-texte);
    text-transform: capitalize;
}

.g-mois__bulle-lignes {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-top: 6px;
}

.g-mois__bulle-ligne {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--g-second);
}

.g-mois__bulle-ligne span:nth-child(2) {
    flex: 1;
}

.g-mois__bulle-ligne b {
    font-family: var(--g-mono);
    font-weight: normal;
    color: var(--g-texte);
}

.g-mois__bulle-pied {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--g-bord);
    font-size: 11px;
    color: var(--g-second);
}

.g-mois__bulle-pied b {
    font-family: var(--g-mono);
    font-weight: normal;
    color: var(--g-titre);
}

.g-histo__pied {
    display: flex;
    gap: 6px;
    padding: 7px 12px 10px;
}

.g-histo__etiquette {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
    text-align: center;
}

.g-histo__etiquette span:first-child {
    font-size: 10px;
    color: var(--g-second);
}

.g-histo__etiquette span:last-child {
    font-family: var(--g-mono);
    font-size: 9px;
    color: var(--g-tres-faible);
}

.g-inscription {
    padding: 10px 12px;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    font-size: 11px;
    color: var(--g-second);
}

/* ---- Rankings ---- */

.g-onglets {
    display: flex;
    gap: 6px;
}

.g-onglet {
    flex: 1;
    min-height: 40px;
    padding: 10px 12px;
    border: 1px solid var(--g-bord-vif);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    color: var(--g-texte);
    font-size: 12px;
    font-weight: bold;
    text-align: center;
    cursor: pointer;
}

.g-onglet:hover {
    text-decoration: none;
}

.g-onglet[aria-current='page'] {
    border-color: var(--g-bord-fort);
    background: var(--g-bandeau);
    color: #fff;
}

.g-filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--g-bord);
    background: var(--g-surface-3);
}

.g-filtres__lieu {
    position: relative;
    flex: 0 1 136px;
    min-width: 104px;
}

.g-filtres__dates {
    display: flex;
    gap: 6px;
    margin-left: auto;
}

.g-rang {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--g-bord);
}

.g-rang--moi {
    background: var(--g-surface-3);
}

.g-rang__place {
    flex: none;
    width: 28px;
    font-family: var(--g-mono);
    font-size: 13px;
    font-weight: bold;
    color: var(--g-second);
}

.g-rang--podium .g-rang__place {
    color: var(--g-titre);
}

.g-rang__points {
    flex: none;
    padding: 5px 8px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: transparent;
    font-family: var(--g-mono);
    font-size: 13px;
    font-weight: bold;
    color: var(--g-titre);
    cursor: pointer;
}

.g-rang__points:hover {
    background: var(--g-surface-3);
}

/* ---- Sign-in ---- */

.g-connexion {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    padding: 10px;
}

.g-connexion__boite {
    width: 100%;
    max-width: 340px;
    overflow: hidden;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
}

.g-connexion__tete {
    padding: 11px 16px;
    background: var(--g-creux);
    color: #fff;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.g-connexion__corps {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
}

.g-cases {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 7px;
}

.g-case {
    width: 100%;
    height: 48px;
    padding: 0;
    border: 1px solid var(--g-bord-fort);
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    color: var(--g-texte);
    font-family: var(--g-mono);
    font-size: 20px;
    text-align: center;
}

.g-case:focus {
    border-color: var(--g-accent);
    outline: none;
}

.g-case--remplie {
    border-color: var(--g-bord-vif);
}

.g-case--code {
    height: 46px;
    font-size: 19px;
    font-weight: bold;
    text-transform: uppercase;
}

.g-chrono {
    font-family: var(--g-mono);
    font-size: 13px;
    color: var(--g-second);
}

.g-chrono--court {
    color: var(--g-alerte);
}

/* ---- Dialogs ---- */

.g-dialogue {
    width: 100%;
    max-width: 340px;
    max-height: calc(100% - 32px);
    padding: 0;
    overflow: hidden;
    border: none;
    border-radius: var(--g-rayon);
    background: var(--g-surface);
    color: var(--g-texte);
    box-shadow: var(--g-ombre-dialogue);
}

.g-dialogue[open] {
    display: flex;
    flex-direction: column;
}

.g-dialogue::backdrop {
    background: rgb(0 0 51 / 35%);
    backdrop-filter: blur(5px);
}

.g-dialogue--large {
    max-width: 660px;
}

.g-dialogue--moyen {
    max-width: 380px;
}

/* La fin d'une partie porte deux réponses dont les libellés sont longs : on lui donne la place
   de les mettre côte à côte sur une ligne chacune. */
.g-dialogue--fin {
    max-width: 460px;
}

.g-dialogue__tete {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 16px;
    background: var(--g-creux);
    color: #fff;
}

.g-dialogue__titre {
    margin: 0;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.g-dialogue__titre--marque {
    font-family: 'Bungee', sans-serif;
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: none;
}

.g-dialogue__tete .g-bouton-nu {
    color: #fff;
}

.g-dialogue__tete--danger {
    background: var(--g-danger-fond);
    color: var(--g-danger-texte);
}

.g-dialogue__tete--danger .g-bouton-nu {
    color: var(--g-danger-texte);
}

/* A dialog whose body and footer sit in one form: the column has to run through the `<form>`,
   or the body no longer knows where to scroll. */
.g-dialogue__forme {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
}

.g-dialogue__corps {
    flex: 1;
    min-height: 0;
    overflow: auto;
    overscroll-behavior: contain;
}

.g-dialogue__corps--pile {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
}

.g-dialogue__texte {
    padding: 16px;
    font-size: 13px;
    text-wrap: pretty;
}

.g-dialogue__pied {
    display: flex;
    flex: none;
    gap: 8px;
    justify-content: flex-end;
    align-items: stretch;
    padding: 11px 16px;
    border-top: 1px solid var(--g-bord);
    background: var(--g-surface-3);
}

/* Deux réponses sont deux colonnes, jamais deux lignes : un pied qui se replie fait lire
   « ou bien » là où il n'y a qu'un choix. Les boutons se partagent donc la place et leur
   libellé s'enroule plutôt que de pousser le voisin dessous. */
.g-dialogue__pied .g-bouton {
    flex: 1 1 0;
    min-width: 0;
    white-space: normal;
}

.g-dialogue__pied--reparti {
    justify-content: space-between;
}

.g-menu-entree {
    display: block;
    width: 100%;
    min-height: 44px;
    padding: 12px 16px;
    border: none;
    border-bottom: 1px solid var(--g-bord);
    background: var(--g-surface);
    color: var(--g-texte);
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.g-menu-entree:hover {
    background: var(--g-survol);
    color: var(--g-texte);
    text-decoration: none;
}

/* ---- The « Jouer » dialog ---- */

.g-jouer {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    align-content: start;
}

.g-jouer__colonne {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.g-jouer__colonne + .g-jouer__colonne {
    border-left: 1px solid var(--g-bord);
}

.g-jouer__intitule {
    padding: 6px 16px;
    border-top: 1px solid var(--g-bord);
    border-bottom: 1px solid var(--g-bord);
    background: var(--g-surface-3);
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--g-second);
}

.g-jouer__intitule:first-child {
    border-top: none;
}

.g-jouer__bloc {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
}

.g-reglages {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: #1b2a39;
}

.g-reglage {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
}

.g-reglage + .g-reglage {
    border-top: 1px solid var(--g-bord);
}

.g-reglage__texte {
    flex: 1;
    min-width: 0;
}

.g-reglage__titre {
    display: block;
    font-size: 13px;
    font-weight: bold;
    color: var(--g-texte);
}

.g-reglage__note {
    display: block;
    font-size: 11px;
    color: var(--g-second);
}

.g-bascule {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex: none;
    width: 48px;
    height: 28px;
    padding: 3px;
    border: 1px solid var(--g-bord);
    border-radius: 14px;
    background: var(--g-survol);
    cursor: pointer;
}

.g-bascule::after {
    content: '';
    display: block;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #fff;
}

.g-bascule[aria-checked='true'] {
    justify-content: flex-end;
    border-color: var(--g-accent);
    background: var(--g-bandeau);
}

.g-grosse-ligne {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 48px;
    padding: 10px 14px;
    border: 1px solid var(--g-bord-vif);
    border-radius: var(--g-rayon);
    background: #1b2a39;
    color: var(--g-texte);
    text-align: left;
    cursor: pointer;
}

.g-grosse-ligne:hover {
    border-color: var(--g-accent);
    background: var(--g-survol);
    color: var(--g-texte);
    text-decoration: none;
}

.g-grosse-ligne svg {
    flex: none;
    width: 18px;
    height: 18px;
    fill: none;
    stroke: var(--g-accent);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.g-grosse-ligne__corps {
    flex: 1;
    min-width: 0;
}

.g-grosse-ligne__titre {
    display: block;
    font-size: 14px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-grosse-ligne__note {
    display: block;
    font-size: 11px;
    color: var(--g-second);
}

.g-pastille-ia {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px;
    height: 30px;
    border: 2px solid var(--g-bord);
    border-radius: 50%;
    background: var(--g-avatar);
    font-family: var(--g-mono);
    font-size: 11px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-pastille-ia--fort {
    border-color: var(--g-accent);
}

/* ---- Notifications ---- */

.g-notif {
    padding: 10px 14px;
    border-bottom: 1px solid var(--g-bord);
    background: var(--g-surface);
}

.g-notif:hover {
    background: var(--g-survol);
}

.g-notif--neuve {
    background: var(--g-surface-2);
}

.g-notif--invitation {
    background: var(--g-bleu-sourd);
}

.g-notif__lien {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.g-notif__lien:hover {
    color: inherit;
    text-decoration: none;
}

.g-notif__puce {
    flex: none;
    width: 8px;
    height: 8px;
    margin-top: 5px;
    border-radius: 50%;
    background: #3a4a59;
}

.g-notif--neuve .g-notif__puce {
    background: var(--g-accent);
}

.g-notif--invitation .g-notif__puce {
    background: var(--g-vert);
}

.g-notif__corps {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.g-notif__titre {
    font-size: 13px;
    color: var(--g-texte);
}

.g-notif--neuve .g-notif__titre,
.g-notif--invitation .g-notif__titre {
    font-weight: bold;
}

.g-notif__detail {
    font-size: 11px;
    color: var(--g-second);
}

.g-notif__quand {
    flex: none;
    font-family: var(--g-mono);
    font-size: 10px;
    color: var(--g-second);
}

.g-notif__actions {
    display: flex;
    gap: 8px;
    margin-top: 9px;
    padding-left: 18px;
}

/* ---- Face-off and end of game ---- */

.g-confront {
    overflow: hidden;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
}

.g-confront__ligne {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr);
    border-bottom: 1px solid var(--g-bord);
}

.g-confront__ligne--tete {
    background: var(--g-surface-3);
}

.g-confront__ligne > span {
    padding: 8px 9px;
    font-size: 12px;
    color: var(--g-second);
}

.g-confront__ligne > span + span {
    border-left: 1px solid var(--g-bord);
    font-family: var(--g-mono);
    color: var(--g-texte);
}

.g-confront__ligne--tete > span {
    padding: 7px 9px;
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.g-confront__ligne--tete > span + span {
    font-family: inherit;
    color: var(--g-titre);
}

.g-fin {
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: center;
    padding: 16px;
    text-align: center;
}

.g-fin__verdict {
    font-family: 'Bungee', sans-serif;
    font-size: 22px;
    letter-spacing: 0.04em;
    color: var(--g-vert);
}

.g-fin__verdict--perdu {
    color: var(--g-rouge);
}

.g-fin__verdict--nul {
    color: var(--g-second);
}

.g-fin__score {
    font-family: var(--g-mono);
    font-size: 26px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-fin__contre {
    font-size: 12px;
    color: var(--g-second);
}

.g-compte {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-2);
}

.g-compte__ligne {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 12px;
    color: var(--g-second);
}

.g-compte__ligne b {
    font-family: var(--g-mono);
    font-weight: normal;
    color: var(--g-texte);
}

.g-compte__ligne--total {
    padding-top: 6px;
    border-top: 1px solid var(--g-bord);
    font-size: 13px;
    font-weight: bold;
    color: var(--g-titre);
}

.g-compte__ligne--total b {
    color: var(--g-titre);
}

.g-compte__ligne--refus b {
    color: var(--g-alerte);
}

.g-evolution {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 2px;
    border-bottom: 1px solid var(--g-bord);
    font-size: 12px;
    color: var(--g-second);
}

.g-evolution b {
    font-family: var(--g-mono);
    font-weight: normal;
    color: var(--g-vert);
}

/* ---- Scanning ---- */

.g-viseur {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 150px;
    padding: 12px;
    overflow: hidden;
    border: 2px dashed var(--g-bord-fort);
    border-radius: var(--g-rayon);
    text-align: center;
}

.g-viseur video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.g-viseur__mot {
    font-family: var(--g-mono);
    font-size: 11px;
    color: var(--g-second);
}

.g-viseur__note {
    max-width: 26ch;
    font-size: 11px;
    color: var(--g-second);
}

.g-ou {
    display: flex;
    align-items: center;
    gap: 10px;
}

.g-ou::before,
.g-ou::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--g-bord);
}

.g-ou span {
    flex: none;
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--g-second);
}

/* ---- Reporting ---- */

.g-motif {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 12px;
    border: 1px solid var(--g-bord);
    border-radius: var(--g-rayon);
    background: var(--g-surface-2);
    color: var(--g-texte);
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.g-motif:hover {
    background: var(--g-survol);
}

.g-motif::before {
    content: '';
    flex: none;
    width: 14px;
    height: 14px;
    border: 1px solid var(--g-bord);
    border-radius: 50%;
}

.g-motif:has(input:checked) {
    border-color: var(--g-bord-vif);
    background: var(--g-surface-3);
}

.g-motif:has(input:checked)::before {
    border-color: var(--g-accent);
    background: var(--g-accent);
}

.g-motif input {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

/* ---- Odds and ends ---- */

.g-pile {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.g-rangee {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.g-rangee--pousse > :last-child {
    margin-left: auto;
}

.g-invisible {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ---- 404 ---- */

.g-404 {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    min-height: 100%;
    padding: 24px;
    text-align: center;
}

.g-404__code {
    font-family: 'Bungee', sans-serif;
    font-size: 44px;
    letter-spacing: 0.06em;
    color: var(--g-titre);
}

/* ------------------------------------------ la partie découverte, allégée

   Depuis que la maquette couvre l'écran d'une battle, c'est la partie d'un invité — et elle
   seule — qui porte encore l'ancien balisage : un bloc par bandeau, un cadre autour du plateau,
   un cadre autour de chaque camp. La nouvelle peau ne supporte pas cet empilement, et on en
   retire donc tout ce qui n'est pas une information — le plateau se pose **sur le fond**, comme
   un vrai plateau sur une table, et les deux camps sont une ligne et non deux boîtes. Elle est
   la prochaine à reprendre sur la maquette, et ces règles partiront avec elle. */

.g-battle {
    /* La bande du haut est au-dessus : on lui laisse de l'air, comme aux autres écrans. */
    padding-top: 28px;
}

.g-battle__vue > .g-panneau {
    border: none;
    border-radius: 0;
    background: none;
}

.g-battle__vue > .g-panneau > .g-panneau__tete {
    padding: 0 2px 12px;
    background: none;
    color: var(--gx-faible);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.24em;
}

/* Les deux camps : une seule ligne, deux noms, deux scores, et le trait sous celui qui joue. */
.g-camps {
    gap: 0;
    padding: 0;
    border: 1px solid var(--gx-bord);
    border-radius: 11px;
    overflow: hidden;
    background: var(--gx-surface);
}

.g-camp {
    padding: 14px 16px;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    background: none;
}

.g-camp + .g-camp {
    border-left: 1px solid var(--gx-bord);
}

.g-camp--trait {
    border-bottom-color: var(--gx-vert);
}

.g-camp__avatar {
    display: none;
}

.g-battle__rythme {
    border-top: none;
    padding: 12px 0 0;
    font-family: var(--gx-mono);
    letter-spacing: 0.14em;
}

/* Le plateau n'a plus de cadre : il est posé sur le fond. */
.g-panneau--plateau {
    margin-top: 12px;
}

.g-panneau--plateau > .g-panneau__tete {
    padding: 0 2px 8px;
    background: none;
    color: var(--gx-faible);
    font: 500 11px/1 var(--gx-mono);
    letter-spacing: 0.24em;
}

.g-plateau {
    padding: 0;
}

/* La consigne et le score passent sous le plateau, sans trait : il n'y a plus de bloc à clore. */
.g-panneau--plateau > .g-panneau__pied {
    border-top: none;
    background: none;
    padding: 14px 2px 0;
    font-family: var(--gx-mono);
    letter-spacing: 0.14em;
}

/* Le rail des vues : des ronds posés sur le fond, comme ceux de la bande, et non un bloc. */
.g-menu-battle {
    border: none;
    background: none;
    padding: 0;
}

.g-menu-battle__item {
    border: 1px solid var(--gx-bord);
    border-radius: 999px;
    background: none;
}

.g-menu-battle__item[aria-current='page'] {
    border-color: var(--gx-vert);
}
