/**
 * Jeux RKUL — Chrome de la charte « arcade neon CRT »   (ticket #134)
 *
 * Depend de css/retro-tokens.css, a charger AVANT celui-ci.
 *
 * ─── Les trois invariants, a respecter sans exception ────────────────────
 *
 * 1. Tout le vocabulaire introduit ici est prefixe .rk- . Cette feuille ne
 *    redefinit JAMAIS un nom existant du depot (.btn, .stat, .game-header,
 *    .screen, .container, .gr-*), qui restent la propriete de chaque jeu.
 *
 * 2. Aucun selecteur d'element nu : pas de `body {}`, pas de `h1 {}`.
 *    Seule entorse, section 0 : `:root`, qui est une PSEUDO-CLASSE et non un
 *    element nu — l'invariant tient a la lettre. Elle est necessaire parce
 *    qu'un comportement de viewport ne peut pas etre porte par une classe.
 *
 * 3. Consequence des deux premiers, et c'est tout l'interet : une regle
 *    `.rk-page` pese (0,1,0) la ou le `body {}` des blocs <style> inline des
 *    jeux solo pese (0,0,1). On gagne par la SPECIFICITE, pas par l'ordre.
 *    Le <link> peut donc etre place AVANT le <style> inline, ce qui laisse
 *    le CSS local de chaque jeu garder le dernier mot sur son layout.
 *    C'est le fusible qui evite de casser un jeu en le repeignant.
 */

/* ═══════════════════════════════════════════════════════════════════════
   0. GESTES DU NAVIGATEUR   (ticket #137)

   Le « tirer pour rafraichir » des navigateurs mobiles rechargeait la page
   des qu'on glissait le doigt vers le bas en haut de course — c'est-a-dire
   le geste meme qui fait descendre une piece a Tetris ou dirige un serpent.
   On perdait sa partie en jouant normalement.

   Ces trois regles sont le point CENTRAL du correctif : toute page de la
   plateforme charge cette feuille, donc tout futur jeu en herite sans que
   personne n'ait a y penser. Quatre decisions, toutes contre-intuitives :

   - `:root` ET `.rk-page`. `:root` atteint le viewport DIRECTEMENT. S'en
     remettre au seul `.rk-page` (donc au <body>) marcherait aujourd'hui,
     mais par chance : la propagation body -> viewport n'a lieu que si la
     racine vaut `auto`, ce qu'une feuille locale peut casser en silence.
     `.rk-page` reste a cote : meme poids, il dit l'intention et couvrirait
     un <body> devenu conteneur de defilement.

   - `-y` seulement. Le geste est vertical. Bloquer aussi X supprimerait la
     navigation arriere par sur-defilement de Chrome Android sur l'accueil
     et /regles.html, pour rien : les gestes horizontaux des jeux se font
     tous sur des canvas en touch-action:none, jamais pris pour un
     defilement.

   - `none` et pas `contain`. `contain` ne coupe que le chainage vers le
     parent ; sa portee sur le rafraichissement du viewport n'est pas
     interoperable. On n'y perd que le rebond elastique de fin de course.

   - `pan-x pan-y` sur .rk-jeu, JAMAIS `none` sur le <body> : la modale de
     regles (.gr-panel, overflow-y:auto) ne defilerait plus au doigt. Voir
     l'avertissement de solo/50.html. `pan-x pan-y` garde le defilement et
     ne retire que le pincement et le double-tap — d'ou son absence sur
     l'accueil, les regles et les deux salons, ou agrandir un texte est un
     vrai besoin.

   Deux limites a connaitre : `overflow:hidden` sur la racine N'EMPECHE PAS
   le rafraichissement (Chrome Android le declenche sur le conteneur racine
   meme quand il n'a rien a faire defiler), et iOS Safari < 16 ignore
   overscroll-behavior — d'ou le filet conditionnel de
   games/tetris/js/game.js, seul endroit du depot a en poser un.
   ═══════════════════════════════════════════════════════════════════════ */
:root,
.rk-page { overscroll-behavior-y: none; }

/* Sur le <body> des pages de JEU uniquement. */
.rk-jeu { touch-action: pan-x pan-y; }

/* La charte impose deja d'entourer le canvas d'un .rk-bezel : un canvas
   encadre EST un terrain de jeu, il ne doit jamais faire defiler la page.
   Les apercus (piece suivante, grille de l'adversaire) sont hors bezel et
   gardent leur comportement normal. Un jeu qui se passe du bezel se prive
   de cette protection et doit poser son touch-action lui-meme — c'est le
   cas de games/trix. */
.rk-bezel canvas { touch-action: none; }

/* ═══════════════════════════════════════════════════════════════════════
   1. LA PAGE : fond de salle, vignette de tube, scanlines
   ═══════════════════════════════════════════════════════════════════════ */
.rk-page {
    background:
        radial-gradient(120% 90% at 50% -10%, var(--rk-void-2) 0%, var(--rk-void) 62%),
        var(--rk-void);
    background-attachment: fixed;
    color: var(--rk-ink);
    font-family: var(--rk-font-body);
}

/* Vignette + scanlines en pseudo-elements du <body>.
   Verifie : aucun body::before / body::after dans tout le perimetre.

   pointer-events: none EST OBLIGATOIRE. Sans lui, une surcouche en
   z-index 9999 avale tous les clics et les 12 jeux deviennent injouables.
   C'est le piege n.1 de ce ticket. */
.rk-page::before,
.rk-page::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
}

.rk-page::before {              /* creusement du tube */
    z-index: 9998;
    background: radial-gradient(120% 100% at 50% 50%,
                transparent 52%, rgba(0, 0, 0, var(--rk-vignette-alpha)) 100%);
}

.rk-page::after {               /* lignes de balayage */
    z-index: 9999;
    background: repeating-linear-gradient(
        to bottom,
        rgba(0, 0, 0, var(--rk-scanline-alpha)) 0px,
        rgba(0, 0, 0, var(--rk-scanline-alpha)) 1px,
        transparent 1px,
        transparent 3px);
}

/* Echappatoire : une page qui ne supporte pas la surcouche (rendu 3D,
   plein ecran tactile) peut l'eteindre sans perdre le reste de la charte. */
.rk-page.rk-no-crt::before,
.rk-page.rk-no-crt::after { display: none; }

/* ═══════════════════════════════════════════════════════════════════════
   2. LE CADRE DE BORNE

   100 % CSS, a dessein. Les canvas du depot font 288x380, 300x600, 400x500,
   150x300... et ceux de trix et solo/arena sont dimensionnes en JS a
   l'execution : un bezel raster serait etire dans des proportions
   arbitraires. border-image 9-slice ne sauve pas la mise non plus — il ne
   peut pas mordre vers l'interieur (donc pas d'effet « ecran encastre »),
   il ignore border-radius, et il est monochrome donc indeclinable en clair.
   ═══════════════════════════════════════════════════════════════════════ */
.rk-bezel {
    position: relative;
    display: inline-block;
    padding: var(--rk-bezel-w);
    border: 2px solid transparent;
    border-radius: var(--rk-radius-lg);
    /* Deux calques : le meuble en padding-box, le lisere neon en border-box.
       C'est ce qui donne une bordure en degrade sans pseudo-element. */
    background:
        linear-gradient(160deg, var(--rk-surface-2), var(--rk-surface)) padding-box,
        linear-gradient(140deg, rgba(var(--rk-accent-rgb), .9),
                                rgba(var(--rk-accent-2-rgb), .9)) border-box;
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, .6),                        /* lisere de separation */
        0 0 18px rgba(var(--rk-accent-rgb), .30),           /* halo externe */
        inset 0 0 26px rgba(0, 0, 0, .85);                  /* creux de l'ecran */
}

/* Le cadre ne doit jamais pousser la page en debordement horizontal : les
   canvas ont des largeurs FIXES (400px pour serpent et cassebrik, 300 pour
   tetris) qui depassent un ecran de 360. */
.rk-bezel { max-width: 100%; }

/* display:block indispensable : un canvas en inline pose sur la ligne de
   base laisse un lisere de ~4px sous lui, dans le cadre. */
.rk-bezel > * {
    display: block;
    max-width: 100%;
    height: auto;          /* conserve le ratio du canvas quand il retrecit */
    border-radius: calc(var(--rk-radius-lg) - var(--rk-bezel-w));
}

/* Le cadre est inline-block par defaut (il epouse son canvas). Quand le
   canvas est fluide — `width:100%; height:auto`, cas de bubbles et de
   cassebrik — le cadre doit s'etirer avec lui. */
.rk-bezel--fill { display: block; width: 100%; }

/* Variante compacte, pour les canvas secondaires (apercu adversaire,
   piece suivante) ou un cadre plein ferait plus de bruit que d'effet. */
.rk-bezel--thin {
    padding: 4px;
    border-radius: var(--rk-radius);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .5),
                0 0 10px rgba(var(--rk-accent-rgb), .18);
}
.rk-bezel--thin > * { border-radius: calc(var(--rk-radius) - 4px); }

/* Le fond d'ecran allume, quand un jeu n'a pas de canvas a mettre dedans. */
.rk-screen {
    background: var(--rk-screen);
    color: var(--rk-ink);
}

/* ═══════════════════════════════════════════════════════════════════════
   3. TITRES NEON

   Press Start 2P est monospace, ~1,7x plus large que Segoe UI a taille
   egale, et ses glyphes touchent le haut de l'em-box. D'ou : taille
   declaree plus petite, line-height genereux, letter-spacing negatif.
   ═══════════════════════════════════════════════════════════════════════ */
.rk-title {
    font-family: var(--rk-font-display);
    font-size: clamp(0.85rem, 3.6vw, 1.45rem);
    line-height: 1.75;
    letter-spacing: -0.02em;
    text-transform: uppercase;
    color: var(--rk-accent);
    /* Couleur pleine + text-shadow, JAMAIS background-clip:text : avec un
       texte transparent, le glow serait rendu SOUS le texte et apparaitrait
       en bloc plein. */
    text-shadow: var(--rk-glow);
    /* Filet anti-debordement : « L'IMPOSTEUR » en pixel sur un ecran de
       320 px depasse sinon. */
    overflow-wrap: anywhere;
    hyphens: none;
}

.rk-title--sm { font-size: clamp(0.7rem, 2.8vw, 1rem); line-height: 1.6; }
.rk-title--lg { font-size: clamp(1rem, 5.2vw, 2rem); }

/* Le titre prend la couleur du jeu quand la page en declare une. */
.rk-title[style*="--rk-tile-accent"] { color: var(--rk-tile-accent); }

.rk-sub {
    color: var(--rk-ink-dim);
    font-size: 0.88rem;
    line-height: 1.45;
}

/* Chiffres de score : la police pixel est monospace, donc un score qui
   passe de 999 a 1000 ne fait plus sauter la mise en page. */
.rk-num {
    font-family: var(--rk-font-display);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.03em;
}

/* ═══════════════════════════════════════════════════════════════════════
   4. BOUTONS
   ═══════════════════════════════════════════════════════════════════════ */
.rk-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 20px;
    border: 1px solid var(--rk-line);
    border-radius: var(--rk-radius);
    background: var(--rk-surface-2);
    color: var(--rk-ink);
    font-family: var(--rk-font-body);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: transform .15s ease, box-shadow .2s ease, background .2s ease;
}

.rk-btn:hover:not(:disabled) {
    transform: translateY(-2px);
    border-color: rgba(var(--rk-accent-rgb), .55);
    box-shadow: var(--rk-glow-soft);
}

.rk-btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

.rk-btn--primary {
    background: linear-gradient(135deg,
                rgba(var(--rk-accent-rgb), .22), rgba(var(--rk-accent-2-rgb), .22));
    border-color: rgba(var(--rk-accent-rgb), .6);
    color: var(--rk-accent);
}

.rk-btn--ghost { background: transparent; }

.rk-btn--danger {
    border-color: rgba(var(--rk-danger-rgb), .55);
    color: var(--rk-danger);
}

.rk-btn--block { display: flex; width: 100%; }
.rk-btn--sm { padding: 7px 13px; font-size: .84rem; }

/* ═══════════════════════════════════════════════════════════════════════
   5. LA RANGEE DU COIN HAUT-DROIT

   Les trois boutons flottants de la plateforme — retour, « ? » des regles
   (js/game-rules.js) et bascule de theme (js/theme-toggle.js) — vivent
   ensemble en HAUT A DROITE, sur une meme rangee horizontale. Un seul
   endroit ou chercher, un seul endroit a eviter en dessinant un jeu.

   Chacun est rond et pas un bandeau : le CLAUDE.md documente une regression
   deja vecue ou le badge de solo-score.js, en position fixed, recouvrait les
   commandes tactiles de Tetris.

   --rk-slot dit combien de boutons occupent DEJA les places a sa droite. Le
   retour prend toujours le coin (slot 0) ; les deux autres se calent a sa
   gauche et posent leur slot en JS, parce qu'aucune feuille de style ne peut
   savoir lesquels sont presents sur la page.

   COLONNE et non rangee horizontale : trois boutons cote a cote font 162 px
   de large et passaient par-dessus les en-tetes des jeux, qui ne reservent
   que la largeur d'un bouton (~46 px). Empiles, le groupe n'en occupe pas
   plus qu'avant.
   ═══════════════════════════════════════════════════════════════════════ */
.rk-home {
    position: fixed;
    box-sizing: border-box;   /* la bordure de 1px NE s'ajoute PAS a la
                                 largeur : sinon ce bouton fait 2px de plus
                                 que le « ? » et la colonne se desaligne. */
    top: calc(12px + var(--rk-slot, 0) * 54px);
    right: 12px;
    left: auto;
    bottom: auto;
    /* Au-dessus des empilements internes des jeux (flip7 monte jusqu'a 100
       pour ses panneaux), mais SOUS .theme-toggle (1000) et l'overlay des
       regles (9001), qui doivent rester accessibles. */
    z-index: 500;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--rk-surface-2);
    border: 1px solid var(--rk-line);
    box-shadow: var(--rk-glow-soft);
    color: var(--rk-accent);
    font-size: .95rem;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: transform .15s ease;
}
.rk-home:hover { transform: scale(1.08); }

/* Ancienne variante haut-gauche, du temps ou le retour vivait en bas a
   gauche. Le bouton est desormais en haut a droite pour tout le monde :
   la classe ne fait plus rien, et reste pour ne pas casser les pages qui
   la portent encore. */
.rk-home--top { top: 12px; bottom: auto; }

@media (max-width: 480px) {
    .rk-home {
        top: calc(10px + var(--rk-slot, 0) * 48px);
        right: 10px;
        width: 38px;
        height: 38px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════
   6. TUILES DE CATALOGUE

   Une seule regle, coloree par --rk-tile-accent pose en attribut style.
   Cela remplace les ~80 lignes de .btn-{game} de css/style.css : ajouter
   un jeu ne demande plus aucune ligne de CSS.
   ═══════════════════════════════════════════════════════════════════════ */
.rk-tiles {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.rk-tile {
    --rk-tile-accent: var(--rk-accent);
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 12px;
    text-align: left;
    background: var(--rk-surface);
    border: 1px solid var(--rk-line);
    border-left: 3px solid var(--rk-tile-accent);
    border-radius: var(--rk-radius);
    color: var(--rk-ink);
    font-family: inherit;
    font-size: 1rem;
    text-decoration: none;
    cursor: pointer;
    transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}

.rk-tile:hover:not(:disabled) {
    transform: translateY(-3px);
    background: var(--rk-surface-2);
    box-shadow: 0 0 20px rgba(0, 0, 0, .35), 0 0 0 1px var(--rk-tile-accent);
}

.rk-tile:disabled { opacity: .55; cursor: progress; transform: none; }

.rk-tile__thumb {
    width: 96px;
    height: 60px;
    flex-shrink: 0;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--rk-line);
    background: var(--rk-screen);
}

/* Repli quand aucune vignette n'est declaree : l'emoji du registre. */
.rk-tile__icon {
    width: 96px;
    height: 60px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    border-radius: 6px;
    background: var(--rk-screen);
    border: 1px solid var(--rk-line);
}

.rk-tile__body {
    display: flex;
    flex-direction: column;
    gap: 5px;
    flex: 1;
    min-width: 0;
}

.rk-tile__title {
    font-family: var(--rk-font-display);
    font-size: .78rem;
    line-height: 1.5;
    letter-spacing: -.02em;
    color: var(--rk-tile-accent);
    overflow-wrap: anywhere;
}

.rk-tile__desc {
    color: var(--rk-ink-dim);
    font-size: .82rem;
    line-height: 1.4;
}

.rk-tile__tags { display: flex; flex-wrap: wrap; gap: 6px; }

.rk-chip {
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--rk-surface-2);
    border: 1px solid var(--rk-line);
    color: var(--rk-ink-dim);
    font-size: .7rem;
}

/* ═══════════════════════════════════════════════════════════════════════
   7. DIVERS PARTAGE
   ═══════════════════════════════════════════════════════════════════════ */

/* Panneau generique (HUD de jeu, encart de resultat). */
.rk-panel {
    background: var(--rk-surface);
    border: 1px solid var(--rk-line);
    border-radius: var(--rk-radius);
    padding: 14px 16px;
}

/* Bascule de theme — rapatriee depuis css/style.css pour etre disponible
   sur les 15 pages, et non plus seulement sur l'accueil et le lobby. */
.theme-toggle {
    position: fixed;
    box-sizing: border-box;   /* meme raison que .rk-home : la colonne doit
                                 aligner trois boutons de largeur identique. */
    /* Meme colonne que .rk-home et .gr-btn — voir la section 5. Le slot est
       pose par js/theme-toggle.js, seul a savoir ce qu'il y a au-dessus. */
    top: calc(12px + var(--rk-slot, 0) * 54px);
    right: 12px;
    z-index: 1000;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid var(--rk-line);
    background: var(--rk-surface-2);
    color: var(--rk-ink);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform .15s ease, background .2s ease;
}
.theme-toggle:hover { transform: scale(1.08); }

@media (max-width: 480px) {
    .theme-toggle {
        top: calc(10px + var(--rk-slot, 0) * 48px);
        right: 10px;
        width: 38px;
        height: 38px;
    }
}

/* Respect des preferences systeme : on eteint les animations, pas la
   charte. Les scanlines sont statiques, elles peuvent rester. */
@media (prefers-reduced-motion: reduce) {
    .rk-btn, .rk-tile, .rk-home, .theme-toggle { transition: none; }
    .rk-btn:hover, .rk-tile:hover, .rk-home:hover, .theme-toggle:hover {
        transform: none;
    }
}
