:root {
    /* Cadrage des vignettes de jeu, partagé par la grille et les rails. */
    --card-ratio: 16 / 9;
    color-scheme: dark;
    --bg: #060811;
    --bg-deep: #03050a;
    --surface: #0c111d;
    --surface-raised: #111827;
    --surface-soft: #0a0f1a;
    --line: rgba(151, 174, 211, 0.16);
    --line-strong: rgba(151, 174, 211, 0.28);
    --text: #f5f7fb;
    --text-soft: #ccd5e5;
    --muted: #8f9bb0;
    --brand: #865DFF;
    --brand-bright: #A98BFF;
    --brand-deep: #5B34D6;
    --magenta: #f04bbd;
    --violet: #865DFF;  /* valeur du kit de marque */
    --success: #5ce3a1;
    --warning: #ffc96b;
    --danger: #ff7b8e;
    --shadow: 0 28px 90px rgba(0, 0, 0, 0.42);
    --radius-sm: 10px;
    --radius: 18px;
    --radius-lg: 28px;
    --container: 1180px;
}

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

html {
    scroll-behavior: smooth;
    scroll-padding-top: 100px;
}

body {
    margin: 0;
    min-width: 320px;
    background:
        radial-gradient(circle at 82% 5%, rgba(143, 108, 255, 0.09), transparent 30rem),
        radial-gradient(circle at 10% 18%, rgba(134, 93, 255, 0.06), transparent 28rem),
        var(--bg);
    color: var(--text);
    font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 16px;
    line-height: 1.65;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
}

body::before {
    position: fixed;
    z-index: -1;
    inset: 0;
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.018) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.018) 1px, transparent 1px);
    background-size: 48px 48px;
    mask-image: linear-gradient(to bottom, black, transparent 85%);
    pointer-events: none;
    content: "";
}

/* `hidden` doit CACHER, meme quand une regle d'auteur donne un `display` a l'element.
   L'attribut n'est qu'un `display: none` de la feuille du navigateur, que la moindre regle
   bat : `img { display: block }` ci-dessous suffisait a rendre visible une image marquee
   `hidden`. Ca m'a coute trois bugs de suite (l'image et le cadre d'une modale, puis la
   modale elle-meme) avant que je le prenne a la racine. */
[hidden] {
    display: none !important;
}

img {
    display: block;
    max-width: 100%;
}

a {
    color: inherit;
}

button,
input,
textarea {
    color: inherit;
    font: inherit;
}

button {
    border: 0;
}

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

h1,
h2,
h3 {
    letter-spacing: -0.035em;
    line-height: 1.08;
    text-wrap: balance;
}

h1 {
    font-size: clamp(3rem, 7vw, 6.6rem);
}

h2 {
    font-size: clamp(2.1rem, 4vw, 4rem);
}

h3 {
    font-size: 1.25rem;
}

p {
    color: var(--text-soft);
}

::selection {
    background: var(--brand);
    color: #021014;
}

:focus-visible {
    outline: 3px solid var(--brand-bright);
    outline-offset: 4px;
}

.site-shell {
    overflow: clip;
}

.container {
    width: min(calc(100% - 40px), var(--container));
    margin-inline: auto;
}

.container.narrow {
    width: min(calc(100% - 40px), 900px);
    margin-inline: auto;
}

.sr-only,
.honeypot {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.skip-link {
    position: fixed;
    z-index: 999;
    top: 12px;
    left: 12px;
    padding: 10px 16px;
    border-radius: 8px;
    background: var(--brand);
    color: #031015;
    font-weight: 800;
    transform: translateY(-160%);
}

.skip-link:focus {
    transform: translateY(0);
}

.eyebrow {
    margin-bottom: 15px;
    color: var(--brand);
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.button {
    display: inline-flex;
    min-height: 52px;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 13px 22px;
    border: 1px solid transparent;
    border-radius: 12px;
    font-size: 0.94rem;
    font-weight: 800;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    transition: transform 180ms ease, box-shadow 180ms ease, background-color 180ms ease, border-color 180ms ease;
}

.button:hover {
    transform: translateY(-2px);
}

.button-primary {
    background: linear-gradient(135deg, var(--brand-bright), var(--brand));
    box-shadow: 0 12px 35px rgba(134, 93, 255, 0.2);
    color: #031116;
}

.button-primary:hover {
    box-shadow: 0 16px 46px rgba(134, 93, 255, 0.32);
}

/* Le survol d'un bouton violet : un reflet balaie le bouton de gauche a droite, et son
   icone, s'il en a une, bondit vers la droite (courbe qui depasse puis revient). Le reflet
   vit dans un pseudo-element sous le texte : le bouton isole son empilement pour que le
   z-index negatif reste chez lui. Le retour se fait sans transition, pour que le reflet ne
   repasse pas a l'envers quand la souris s'en va. Un <input> n'a pas de pseudo-element :
   il garde simplement son elevation. */
.button-primary {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

.button-primary::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .5) 50%, transparent 62%);
    transform: translateX(-120%);
}

.button-primary:hover::after,
.button-primary:focus-visible::after {
    transform: translateX(120%);
    transition: transform 650ms ease-out;
}

.button-icon {
    flex: none;
    transition: transform 280ms cubic-bezier(.34, 1.56, .64, 1);
}

.button-primary:hover .button-icon,
.button-primary:focus-visible .button-icon {
    transform: translateX(4px) scale(1.25);
}

/* Une roue dentee tourne, elle ne part pas vers la droite. */
.button-icon-gear {
    transition: transform 420ms cubic-bezier(.34, 1.4, .64, 1);
}

.button-primary:hover .button-icon-gear,
.button-primary:focus-visible .button-icon-gear {
    transform: rotate(120deg) scale(1.15);
}

.button-ghost {
    border-color: var(--line-strong);
    background: rgba(255, 255, 255, 0.025);
    color: var(--text);
}

.button-ghost:hover {
    border-color: rgba(134, 93, 255, 0.52);
    background: rgba(134, 93, 255, 0.06);
}

.button-small {
    min-height: 42px;
    padding: 10px 16px;
    border-radius: 10px;
    font-size: 0.82rem;
}

.button-wide {
    width: 100%;
}

.button[aria-busy="true"] {
    cursor: wait;
    opacity: 0.68;
}

.text-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--brand-bright);
    font-weight: 800;
    text-decoration: none;
}

.text-link span {
    transition: transform 180ms ease;
}

.text-link:hover span {
    transform: translateX(5px);
}

/* Header */
.site-header {
    position: sticky;
    z-index: 100;
    top: 0;
    border-bottom: 1px solid transparent;
    background: rgba(6, 8, 17, 0.74);
    backdrop-filter: blur(18px);
    transition: border-color 180ms ease, background-color 180ms ease;
}

.site-header.is-scrolled {
    border-color: var(--line);
    background: rgba(6, 8, 17, 0.92);
}

.header-inner {
    display: flex;
    min-height: 78px;
    align-items: center;
    gap: 30px;
}

.brand {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 11px;
    text-decoration: none;
}

/* La marque est évidée : un box-shadow projetterait depuis la boîte
   rectangulaire de l'image et dessinerait un cadre derrière un cercle. Le
   drop-shadow suit la forme réelle, et il reprend le violet de NelfePlay -
   le halo était cyan, couleur de NelfeTech. Plus de border-radius non plus :
   il n'avait de sens que pour l'ancien PNG carré. */
.brand img {
    filter: drop-shadow(0 0 14px rgba(134, 93, 255, 0.45));
}

/* Graisse et interlettrage repris de la charte, sans interpretation : 700 et
   -0.02em. Le site montait a 850 et -0.04em, ce qui epaississait le nom et le
   resserrait par rapport a la reference. */
.brand-name {
    color: var(--text);
    font-size: 1.18rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

/* « Play » porte le violet de NelfePlay, pas le cyan de NelfeTech. */
.brand-name span {
    color: var(--violet);
}

.primary-nav {
    display: flex;
    align-items: center;
    gap: 3px;
    margin-left: auto;
}

.mobile-language-link,
.mobile-launch-link,
.mobile-account-link {
    display: none;
}

/* Le sélecteur de langue du menu repliable porte AUSSI la classe générique du
   sélecteur, déclarée plus bas : à spécificité égale, c'est la dernière qui
   gagne, et le sélecteur réapparaissait donc en double sur grand écran. On
   cible ici les deux classes ensemble pour que le masquage l'emporte. */
.language-group.mobile-language-link {
    display: none;
}

.primary-nav > a,
.nav-group > button {
    min-height: 42px;
    padding: 10px 12px;
    /* « Comment ca marche » se cassait au milieu : deux lignes dans une barre
       d'une ligne se lisent comme un defaut d'affichage. */
    white-space: nowrap;
    border-radius: 9px;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    font-size: 0.86rem;
    font-weight: 700;
    text-decoration: none;
    transition: color 160ms ease, background-color 160ms ease;
}

.primary-nav > a:hover,
.primary-nav > a.is-active,
.nav-group > button:hover,
.nav-group > button.is-active,
.nav-group > button[aria-expanded="true"] {
    background: rgba(255, 255, 255, 0.04);
    color: var(--text);
}

.nav-group {
    position: relative;
}

.nav-group > button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.nav-popover {
    position: absolute;
    top: calc(100% + 10px);
    left: 50%;
    display: none;
    min-width: 190px;
    padding: 8px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: rgba(12, 17, 29, 0.98);
    box-shadow: var(--shadow);
    transform: translateX(-50%);
}

.nav-popover.is-open {
    display: grid;
}

.nav-popover a {
    padding: 10px 12px;
    border-radius: 8px;
    color: var(--text-soft);
    font-size: 0.86rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}

.nav-popover a:hover,
.nav-popover a.is-active {
    background: rgba(134, 93, 255, 0.08);
    color: var(--brand-bright);
}

/* Le separateur avant le vote du vendredi : une action, a part des pages a parcourir. */
.nav-popover .nav-sep {
    width: auto;
    height: 1px;
    margin: 6px 4px;
    border: 0;
    background: var(--line);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    /* « SE CONNECTER » se coupait en deux quand la rangee devenait etroite. */
    white-space: nowrap;
}

.language-link {
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-decoration: none;
    text-transform: uppercase;
}

.language-link:hover {
    color: var(--brand-bright);
}

/* Sélecteur de langue. La paire côte à côte tenait à deux langues ; à six elle
   poussait la navigation sur deux lignes. Le repli garde la langue courante
   lisible sans rien ouvrir - c'est ce que la paire apportait - et range les
   cinq autres. */
.language-group {
    flex: 0 0 auto;
}

.language-trigger {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 8px 5px 10px;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    color: var(--text);
    font-family: inherit;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    background: transparent;
}

.language-trigger:hover,
.language-trigger[aria-expanded="true"] {
    color: var(--brand-bright);
    border-color: var(--brand-bright);
}

.language-trigger .nav-caret {
    font-size: 0.62rem;
    transition: transform 0.15s ease;
}

.language-trigger[aria-expanded="true"] .nav-caret {
    transform: rotate(180deg);
}

/* Ancré à droite : le sélecteur vit au bord de l'en-tête, un popover centré
   déborderait de la fenêtre. */
.language-popover {
    left: auto;
    right: 0;
    min-width: 150px;
    transform: none;
}

.language-choice {
    padding: 9px 12px;
    border-radius: 8px;
    color: var(--text-soft);
    font-size: 0.86rem;
    font-weight: 700;
    text-decoration: none;
}

.language-choice.is-current {
    color: var(--text);
    background: rgba(134, 93, 255, 0.16);
    cursor: default;
}

.language-choice:not(.is-current):hover,
.language-choice:not(.is-current):focus-visible {
    color: var(--brand-bright);
    background: rgba(134, 93, 255, 0.08);
}

.nav-toggle {
    display: none;
    width: 44px;
    height: 44px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: transparent;
    cursor: pointer;
}

.nav-toggle span:not(.sr-only) {
    position: absolute;
    width: 18px;
    height: 2px;
    border-radius: 2px;
    background: var(--text);
    transition: transform 180ms ease;
}

.nav-toggle span:nth-child(2) {
    transform: translateY(-4px);
}

.nav-toggle span:nth-child(3) {
    transform: translateY(4px);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
    transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(3) {
    transform: rotate(-45deg);
}

/* Feedback */
.flash {
    position: relative;
    z-index: 80;
    border-bottom: 1px solid var(--line);
    background: #101725;
}

.flash .container {
    display: flex;
    min-height: 56px;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    font-weight: 700;
}

.flash-success {
    border-color: rgba(92, 227, 161, 0.3);
    background: rgba(18, 64, 49, 0.96);
}

.flash-error {
    border-color: rgba(255, 123, 142, 0.35);
    background: rgba(73, 28, 39, 0.97);
}

.flash button {
    padding: 8px;
    background: transparent;
    cursor: pointer;
    font-size: 1.5rem;
}

/* Un message peut proposer un geste (la bienvenue mene au choix du nom) :
   le lien suit la phrase et passe dessous quand la place manque. */
.flash-message {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px 16px;
}

.flash-action {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    white-space: nowrap;
}

/* Home hero */
.hero {
    position: relative;
    min-height: 720px;
    padding: clamp(76px, 10vw, 145px) 0 110px;
}

.section-glow::after {
    position: absolute;
    z-index: -1;
    right: -15%;
    bottom: -10%;
    width: 650px;
    height: 650px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(134, 93, 255, 0.08), transparent 68%);
    content: "";
}

.hero-grid {
    display: grid;
    align-items: center;
    grid-template-columns: minmax(0, 1.02fr) minmax(410px, 0.98fr);
    gap: clamp(45px, 7vw, 100px);
}

.status-pill {
    display: inline-flex;
    min-height: 34px;
    align-items: center;
    gap: 9px;
    padding: 7px 12px;
    border: 1px solid rgba(134, 93, 255, 0.2);
    border-radius: 999px;
    background: rgba(134, 93, 255, 0.055);
    color: var(--brand-bright);
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.09em;
    line-height: 1.2;
    text-transform: uppercase;
}

.status-pill > span {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brand);
    box-shadow: 0 0 14px var(--brand);
}

.hero h1 {
    max-width: 760px;
    margin: 25px 0 24px;
}

.hero h1 span,
.hero h1 strong {
    display: block;
}

.hero h1 span {
    color: var(--text);
    font-weight: 780;
}

.hero h1 strong {
    background: linear-gradient(100deg, var(--brand-bright) 5%, var(--brand) 38%, var(--violet) 68%, var(--magenta));
    background-clip: text;
    color: transparent;
    font-weight: 850;
}

.brand-signature {
    margin: -12px 0 22px;
    color: var(--muted);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.hero-lead {
    max-width: 690px;
    margin-bottom: 18px;
    color: var(--text-soft);
    font-size: clamp(1.08rem, 1.8vw, 1.32rem);
    line-height: 1.55;
}

.hero-proof {
    max-width: 650px;
    margin-bottom: 30px;
    color: var(--text);
    font-weight: 750;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.transparency-note {
    display: flex;
    max-width: 670px;
    align-items: flex-start;
    gap: 10px;
    margin: 24px 0 0;
    color: var(--muted);
    font-size: 0.84rem;
    line-height: 1.55;
}

.transparency-note > span {
    display: inline-grid;
    width: 19px;
    height: 19px;
    flex: 0 0 auto;
    place-items: center;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    color: var(--brand);
    font-size: 0.7rem;
    font-style: normal;
    font-weight: 900;
}

.hero-visual {
    position: relative;
    min-height: 540px;
    display: grid;
    place-items: center;
    isolation: isolate;
}

.orb {
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    filter: blur(10px);
}

.orb-cyan {
    top: 5%;
    right: 5%;
    width: 300px;
    height: 300px;
    background: radial-gradient(circle, rgba(134, 93, 255, 0.2), transparent 68%);
}

.orb-magenta {
    bottom: 0;
    left: -5%;
    width: 330px;
    height: 330px;
    background: radial-gradient(circle, rgba(240, 75, 189, 0.13), transparent 67%);
}

.signal-card {
    position: relative;
    width: min(100%, 475px);
    padding: 20px;
    border: 1px solid rgba(124, 150, 192, 0.28);
    border-radius: 24px;
    background:
        linear-gradient(145deg, rgba(17, 24, 39, 0.97), rgba(7, 11, 20, 0.98)),
        var(--surface);
    box-shadow:
        0 40px 100px rgba(0, 0, 0, 0.54),
        inset 0 1px rgba(255, 255, 255, 0.05);
    transform: perspective(1200px) rotateY(-4deg) rotateX(2deg);
}

.signal-card::before {
    position: absolute;
    inset: -1px;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(125deg, rgba(134, 93, 255, 0.45), transparent 35%, transparent 70%, rgba(240, 75, 189, 0.28));
    content: "";
    filter: blur(12px);
    opacity: 0.4;
}

.signal-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    margin-bottom: 18px;
}

.signal-brand {
    display: flex;
    align-items: center;
    gap: 12px;
}

.signal-brand img {
    /* Pas de cadre autour de la marque : elle porte sa propre forme. */
}

.signal-brand div {
    display: grid;
    gap: 2px;
}

.signal-brand span {
    color: var(--muted);
    font-size: 0.65rem;
    font-weight: 750;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.signal-brand strong {
    font-size: 0.95rem;
}

.live-dot {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--brand);
    font-size: 0.6rem;
    font-weight: 850;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.live-dot i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 10px currentColor;
}

.signal-screen {
    position: relative;
    display: grid;
    min-height: 205px;
    place-content: center;
    overflow: hidden;
    border: 1px solid rgba(134, 93, 255, 0.18);
    border-radius: 14px;
    background:
        linear-gradient(rgba(134, 93, 255, 0.025) 1px, transparent 1px),
        linear-gradient(90deg, rgba(134, 93, 255, 0.025) 1px, transparent 1px),
        radial-gradient(circle at 50% 45%, rgba(134, 93, 255, 0.12), transparent 44%),
        #050913;
    background-size: 16px 16px, 16px 16px, auto, auto;
    text-align: center;
}

.signal-screen::after {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, transparent 50%, rgba(0, 0, 0, 0.18) 50%);
    background-size: 100% 4px;
    pointer-events: none;
    content: "";
    opacity: 0.3;
}

.signal-screen p {
    margin: 11px 0 2px;
    color: var(--text);
    font-size: 1.35rem;
    font-weight: 900;
    letter-spacing: 0.12em;
}

.signal-screen p strong {
    color: var(--brand);
}

.signal-screen small {
    color: var(--muted);
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.24em;
}

.cartridge-mark {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 4px;
    height: 34px;
}

.cartridge-mark span {
    width: 7px;
    background: linear-gradient(to top, var(--brand), var(--magenta));
    box-shadow: 0 0 13px rgba(134, 93, 255, 0.38);
}

.cartridge-mark span:nth-child(1) {
    height: 16px;
}

.cartridge-mark span:nth-child(2) {
    height: 30px;
}

.cartridge-mark span:nth-child(3) {
    height: 22px;
}

.pixel-corner {
    position: absolute;
    width: 18px;
    height: 18px;
    border-color: var(--brand);
    opacity: 0.6;
}

.pixel-corner-a {
    top: 12px;
    left: 12px;
    border-top: 2px solid;
    border-left: 2px solid;
}

.pixel-corner-b {
    right: 12px;
    bottom: 12px;
    border-right: 2px solid;
    border-bottom: 2px solid;
}

.signal-rows {
    display: grid;
    gap: 1px;
    margin-top: 12px;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--line);
}

.signal-rows > div {
    display: flex;
    min-height: 43px;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    padding: 9px 12px;
    background: rgba(8, 12, 21, 0.98);
}

.signal-rows > div > span {
    color: var(--muted);
    font-size: 0.72rem;
}

.signal-rows strong {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 0.72rem;
}

.signal-status {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--success);
    box-shadow: 0 0 8px rgba(92, 227, 161, 0.45);
}

.signal-status-3 {
    background: var(--violet);
}

.signal-status-4 {
    background: var(--magenta);
}

.floating-chip {
    position: absolute;
    padding: 8px 11px;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: rgba(9, 14, 24, 0.92);
    box-shadow: 0 16px 35px rgba(0, 0, 0, 0.35);
    color: var(--muted);
    font-family: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
    font-size: 0.56rem;
    font-weight: 800;
    letter-spacing: 0.08em;
}

.floating-chip-a {
    top: 10%;
    left: -3%;
}

.floating-chip-b {
    right: -2%;
    bottom: 12%;
}

/* Shared sections */
.section {
    position: relative;
    padding: clamp(56px, 6.5vw, 104px) 0;
}

.section-muted {
    border-block: 1px solid var(--line);
    background: rgba(12, 17, 29, 0.55);
}

.section-heading {
    max-width: 810px;
    margin-bottom: 55px;
}

.section-heading h2 {
    margin-bottom: 20px;
}

.section-heading > p:last-child {
    max-width: 720px;
    margin-bottom: 0;
    font-size: 1.07rem;
}

.section-heading-row {
    display: flex;
    max-width: none;
    align-items: end;
    justify-content: space-between;
    gap: 30px;
}

.section-heading-row > div {
    max-width: 760px;
}

/* Families */
.section-families {
    border-top: 1px solid var(--line);
    background: linear-gradient(to bottom, rgba(14, 20, 34, 0.55), transparent);
}

.family-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
}

.family-card {
    position: relative;
    min-height: 390px;
    overflow: hidden;
    padding: 28px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: linear-gradient(155deg, rgba(17, 24, 39, 0.98), rgba(8, 12, 20, 0.98));
    transition: transform 200ms ease, border-color 200ms ease;
}

.family-card:hover {
    border-color: rgba(134, 93, 255, 0.34);
    transform: translateY(-5px);
}

.family-card::after {
    position: absolute;
    right: -30%;
    bottom: -25%;
    width: 280px;
    height: 280px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(134, 93, 255, 0.1), transparent 66%);
    content: "";
}

.family-card-2::after {
    background: radial-gradient(circle, rgba(143, 108, 255, 0.12), transparent 66%);
}

.family-card-3::after {
    background: radial-gradient(circle, rgba(240, 75, 189, 0.1), transparent 66%);
}

.family-number {
    color: var(--muted);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.7rem;
    font-weight: 800;
}

.family-art {
    position: relative;
    display: grid;
    width: 100%;
    height: 150px;
    place-items: center;
    margin: 10px 0 24px;
}

.family-art span {
    position: absolute;
    width: 58px;
    height: 58px;
    border: 8px solid rgba(134, 93, 255, 0.52);
    border-radius: 8px;
    transform: rotate(45deg);
}

.family-art span:nth-child(2) {
    width: 32px;
    height: 32px;
    border-color: rgba(240, 75, 189, 0.48);
    transform: translate(50px, -30px) rotate(15deg);
}

.family-art span:nth-child(3) {
    width: 18px;
    height: 18px;
    border: 0;
    border-radius: 2px;
    background: var(--brand);
    box-shadow: 0 0 20px rgba(134, 93, 255, 0.5);
    transform: translate(-53px, 38px);
}

.family-art span:nth-child(4) {
    width: 80px;
    height: 2px;
    border: 0;
    border-radius: 0;
    background: linear-gradient(90deg, transparent, var(--brand), transparent);
    transform: translateY(68px);
}

.family-card-2 .family-art span:first-child {
    border-color: rgba(143, 108, 255, 0.64);
}

.family-card-3 .family-art span:first-child {
    border-color: rgba(240, 75, 189, 0.55);
}

.family-card h3 {
    position: relative;
    z-index: 1;
    margin-bottom: 12px;
    font-size: 1.35rem;
}

.family-card p {
    position: relative;
    z-index: 1;
    margin-bottom: 0;
    color: var(--muted);
}

.catalogue-link {
    display: flex;
    justify-content: flex-end;
    margin-top: 30px;
}

/* Trust */
.section-trust {
    background:
        radial-gradient(circle at 10% 50%, rgba(134, 93, 255, 0.055), transparent 30rem),
        var(--bg-deep);
}

.trust-layout {
    display: grid;
    grid-template-columns: 0.78fr 1.22fr;
    gap: clamp(55px, 9vw, 120px);
}

.trust-intro {
    position: sticky;
    top: 130px;
    align-self: start;
}

.trust-intro h2 {
    margin-bottom: 22px;
}

.trust-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
}

.trust-grid article {
    min-height: 245px;
    padding: 26px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(13, 19, 31, 0.82);
}

.trust-icon {
    display: inline-grid;
    width: 42px;
    height: 42px;
    place-items: center;
    margin-bottom: 37px;
    border: 1px solid rgba(134, 93, 255, 0.28);
    border-radius: 10px;
    background: rgba(134, 93, 255, 0.06);
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.68rem;
    font-weight: 850;
}

.trust-grid h3 {
    margin-bottom: 10px;
}

.trust-grid p {
    margin-bottom: 0;
    color: var(--muted);
    font-size: 0.94rem;
}

/* Passport */
.section-passport {
    overflow: hidden;
    border-block: 1px solid var(--line);
    background:
        radial-gradient(circle at 75% 50%, rgba(143, 108, 255, 0.09), transparent 35rem),
        rgba(10, 14, 25, 0.78);
}

.passport-layout {
    display: grid;
    align-items: center;
    grid-template-columns: 0.92fr 1.08fr;
    gap: clamp(55px, 9vw, 115px);
}

.passport-copy h2 {
    margin-bottom: 24px;
}

.passport-copy > p:not(.eyebrow) {
    max-width: 540px;
    font-size: 1.08rem;
}

.evidence-legend {
    display: flex;
    max-width: 600px;
    flex-wrap: wrap;
    gap: 10px 16px;
    margin-top: 30px;
}

.evidence-legend > span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--muted);
    font-size: 0.72rem;
}

.dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.dot-creator {
    background: var(--violet);
}

.dot-nelfe {
    background: var(--brand);
}

.dot-partner {
    background: var(--success);
}

.dot-unknown {
    background: #566176;
}

.passport-card {
    position: relative;
    padding: 28px;
    border: 1px solid rgba(134, 93, 255, 0.27);
    border-radius: 24px;
    background:
        linear-gradient(135deg, rgba(134, 93, 255, 0.045), transparent 38%),
        rgba(6, 10, 18, 0.98);
    box-shadow: 0 32px 90px rgba(0, 0, 0, 0.45);
}

.passport-card::before {
    position: absolute;
    top: 0;
    left: 28px;
    width: 80px;
    height: 3px;
    background: linear-gradient(90deg, var(--brand), var(--magenta));
    content: "";
}

.passport-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding-bottom: 22px;
    border-bottom: 1px solid var(--line);
}

.passport-header div {
    display: grid;
    gap: 4px;
}

.passport-header span {
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.64rem;
    font-weight: 800;
    letter-spacing: 0.12em;
}

.passport-header strong {
    font-size: 0.9rem;
    letter-spacing: 0.04em;
}

.passport-header img {
    /* Pas de cadre autour de la marque. */
}

.passport-card dl {
    margin: 0;
}

.passport-card dl > div {
    display: grid;
    padding: 15px 0;
    border-bottom: 1px solid var(--line);
    grid-template-columns: 0.85fr 1.15fr;
    gap: 20px;
}

.passport-card dt {
    color: var(--muted);
    font-size: 0.78rem;
}

.passport-card dd {
    margin: 0;
    color: var(--text);
    font-size: 0.82rem;
    font-weight: 750;
}

.verified-mark {
    display: inline-grid;
    width: 18px;
    height: 18px;
    place-items: center;
    margin-right: 7px;
    border-radius: 50%;
    background: rgba(92, 227, 161, 0.12);
    color: var(--success);
    font-size: 0.67rem;
}

.passport-card > p {
    margin: 18px 0 0;
    color: var(--muted);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.67rem;
}

/* Journey */
.journey-list {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
    /* Trois etapes, trois colonnes. La grille en comptait cinq, heritee du
       parcours d'avant : les deux colonnes vides laissaient le bloc bancal. */
    grid-template-columns: repeat(3, 1fr);
}

.journey-list li {
    position: relative;
    min-height: 220px;
    padding: 0 22px;
    border-left: 1px solid var(--line);
}

.journey-list li:last-child {
    border-right: 1px solid var(--line);
}

.journey-list li > span {
    display: inline-grid;
    width: 34px;
    height: 34px;
    place-items: center;
    margin-bottom: 40px;
    border-radius: 50%;
    background: rgba(134, 93, 255, 0.08);
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 850;
}

.journey-list h3 {
    margin-bottom: 10px;
}

.journey-list p {
    margin: 0;
    color: var(--muted);
    font-size: 0.88rem;
}

.boundary-note {
    display: flex;
    align-items: flex-start;
    gap: 15px;
    margin-top: 50px;
    padding: 20px 22px;
    border: 1px solid rgba(255, 201, 107, 0.2);
    border-radius: 14px;
    background: rgba(255, 201, 107, 0.035);
}

.boundary-note > span {
    display: grid;
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    place-items: center;
    border: 1px solid rgba(255, 201, 107, 0.4);
    border-radius: 50%;
    color: var(--warning);
    font-size: 0.7rem;
    font-weight: 900;
}

.boundary-note p {
    margin: 0;
    color: #c9c0aa;
    font-size: 0.87rem;
}

/* Partner cards */
.section-partners {
    border-top: 1px solid var(--line);
    background: linear-gradient(180deg, rgba(13, 18, 31, 0.62), transparent);
}

.partner-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
}

.partner-card {
    min-height: 340px;
    padding: 30px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(10, 15, 25, 0.82);
}

.partner-kicker {
    display: inline-block;
    margin-bottom: 72px;
    color: var(--muted);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.64rem;
    font-weight: 800;
    letter-spacing: 0.1em;
}

.partner-creator {
    border-top-color: rgba(134, 93, 255, 0.58);
}

.partner-rights {
    border-top-color: rgba(143, 108, 255, 0.58);
}

.partner-pro {
    border-top-color: rgba(240, 75, 189, 0.48);
}

.partner-card h3 {
    margin-bottom: 13px;
    font-size: 1.5rem;
}

.partner-card p {
    min-height: 112px;
    margin-bottom: 24px;
    color: var(--muted);
}

.mission-banner {
    position: relative;
    padding: clamp(85px, 10vw, 135px) 0;
    overflow: hidden;
    border-block: 1px solid rgba(134, 93, 255, 0.16);
    background:
        linear-gradient(115deg, rgba(134, 93, 255, 0.085), rgba(143, 108, 255, 0.07) 55%, rgba(240, 75, 189, 0.06)),
        #080c16;
}

.mission-banner-inner {
    display: grid;
    align-items: center;
    grid-template-columns: 0.55fr 1.45fr;
    gap: clamp(45px, 8vw, 110px);
}

.mission-banner h2 {
    max-width: 900px;
    margin-bottom: 22px;
}

.mission-banner p:not(.eyebrow) {
    max-width: 760px;
}

.mission-pixel {
    position: relative;
    display: grid;
    width: 230px;
    height: 230px;
    place-items: center;
    margin-inline: auto;
}

.mission-pixel span {
    position: absolute;
    width: 104px;
    height: 104px;
    border: 16px solid var(--brand);
    box-shadow: 0 0 45px rgba(134, 93, 255, 0.18);
    transform: rotate(45deg);
}

.mission-pixel span:nth-child(2) {
    width: 48px;
    height: 48px;
    border-color: var(--magenta);
    transform: translate(64px, -52px);
}

.mission-pixel span:nth-child(3) {
    width: 24px;
    height: 24px;
    border: 0;
    background: var(--violet);
    transform: translate(-76px, 70px);
}

.mission-pixel span:nth-child(4) {
    width: 150px;
    height: 2px;
    border: 0;
    background: linear-gradient(90deg, transparent, var(--brand), transparent);
    transform: translateY(108px);
}

/* Game catalogue */
.page-hero {
    position: relative;
    padding: clamp(90px, 11vw, 160px) 0 clamp(70px, 9vw, 120px);
    border-bottom: 1px solid var(--line);
    background:
        radial-gradient(circle at 80% 30%, rgba(134, 93, 255, 0.08), transparent 30rem),
        linear-gradient(to bottom, rgba(14, 20, 34, 0.55), transparent);
}

/* « Compact » ne compactait RIEN : la classe se contentait de centrer le texte, et ces pages
   heritaient du hero de vitrine, jusqu'a 160px dessus et 120px dessous, puis d'une section a
   145px. Entre l'identite et la premiere carte utile, ca faisait un demi-ecran vide.

   Or ce sont les pages d'APPLICATION qui la portent : compte, administration, bibliotheque,
   createurs. On y vient pour AGIR, pas pour etre accueilli, et la premiere chose utile doit
   tenir a l'ecran. Les pages vitrine, elles, gardent le hero genereux : elles n'ont pas la
   meme fonction. */
.compact-hero {
    text-align: center;
    padding: clamp(2.2rem, 4.5vw, 3.4rem) 0 clamp(1.4rem, 3vw, 2.2rem);
}

/* Le hero du site pousse ses titres a 6rem. Sur une page d'application, le titre est un
   pseudo ou un nom de vue, pas une accroche : il n'a pas besoin de cette taille-la, et sa
   taille commande ses marges. */
.compact-hero h1 {
    margin-bottom: 12px;
    font-size: clamp(1.9rem, 3.6vw, 2.9rem);
}

.compact-hero + .section {
    padding: clamp(1.6rem, 3vw, 2.4rem) 0 clamp(2.4rem, 5vw, 3.6rem);
}

.page-hero h1 {
    margin-bottom: 25px;
    font-size: clamp(3rem, 6.2vw, 6rem);
}

.page-lead {
    max-width: 820px;
    margin-bottom: 0;
    color: var(--text-soft);
    font-size: clamp(1.08rem, 2vw, 1.35rem);
    line-height: 1.55;
}

.compact-hero .page-lead {
    margin-inline: auto;
}

.catalogue-section {
    min-height: 600px;
}

.empty-catalogue {
    display: grid;
    align-items: center;
    padding: clamp(35px, 6vw, 75px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, rgba(17, 24, 39, 0.94), rgba(7, 11, 18, 0.96));
    grid-template-columns: 0.8fr 1.2fr;
    gap: clamp(45px, 8vw, 100px);
}

.empty-catalogue h2 {
    margin: 25px 0 18px;
    font-size: clamp(2rem, 4vw, 3.5rem);
}

.empty-catalogue p {
    max-width: 610px;
    margin-bottom: 27px;
    font-size: 1.03rem;
}

.empty-visual {
    position: relative;
    display: grid;
    min-height: 300px;
    place-items: center;
    border: 1px solid var(--line);
    border-radius: 20px;
    background:
        radial-gradient(circle, rgba(134, 93, 255, 0.1), transparent 55%),
        #070b14;
}

.empty-visual img {
    position: relative;
    z-index: 2;
}

.empty-shelf {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.empty-shelf span {
    position: absolute;
    bottom: 34px;
    width: 46px;
    border: 1px solid var(--line-strong);
    border-radius: 4px 4px 0 0;
    background: rgba(255, 255, 255, 0.025);
}

.empty-shelf span:nth-child(1) {
    left: 12%;
    height: 120px;
}

.empty-shelf span:nth-child(2) {
    left: 27%;
    height: 155px;
}

.empty-shelf span:nth-child(3) {
    right: 24%;
    height: 138px;
}

.empty-shelf span:nth-child(4) {
    right: 9%;
    height: 96px;
}

.catalogue-note {
    max-width: 820px;
    margin: 38px auto 0;
    color: var(--muted);
    font-size: 0.83rem;
    text-align: center;
}

.game-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
}

.game-card {
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    transition: border-color 160ms ease, transform 160ms ease;
}

.game-card:hover,
.game-card:focus-within {
    border-color: rgba(134, 93, 255, 0.42);
    transform: translateY(-3px);
}

.game-card-link {
    display: block;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

.game-card-link:focus-visible {
    outline: 3px solid rgba(134, 93, 255, 0.5);
    outline-offset: -3px;
}

.game-cover {
    display: grid;
    /* Cadrage UNIQUE pour toutes les vignettes : capture, jaquette ou
       monogramme. Sans cela, une carte illustrée est plus basse que sa voisine
       et la grille se déséquilibre. `object-fit: cover` remplit le cadre sans
       jamais déformer l'image. */
    aspect-ratio: var(--card-ratio);
    place-items: center;
    overflow: hidden;
    background:
        radial-gradient(circle, rgba(134, 93, 255, 0.12), transparent 55%),
        #050913;
}

.game-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.game-cover > span {
    color: rgba(134, 93, 255, 0.3);
    font-size: 4rem;
    font-weight: 900;
}

.game-card-body {
    padding: 24px;
}

.game-meta {
    display: flex;
    justify-content: space-between;
    gap: 15px;
    margin-bottom: 15px;
    color: var(--brand);
    font-size: 0.65rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.game-card h2,
.game-card h3 {
    margin-bottom: 10px;
}

.game-card p {
    margin-bottom: 0;
    color: var(--muted);
}

.game-card .creator-name {
    color: var(--brand);
    font-size: 0.8rem;
}

/* Game detail */
.game-detail-hero-grid {
    display: grid;
    align-items: center;
    grid-template-columns: 1.05fr 0.95fr;
    gap: clamp(50px, 8vw, 110px);
}

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 34px;
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 750;
    text-decoration: none;
}

.back-link:hover {
    color: var(--brand);
}

.game-detail-meta {
    justify-content: flex-start;
    flex-wrap: wrap;
    margin-bottom: 18px;
}

.game-detail-meta span:not(:last-child)::after {
    margin-left: 15px;
    color: var(--muted);
    content: "·";
}

.game-detail-creator {
    margin: -10px 0 20px;
    color: var(--brand);
    font-size: 0.9rem;
    font-weight: 750;
}

.game-detail-hero .page-lead {
    margin-bottom: 28px;
}

.game-detail-cover {
    display: grid;
    aspect-ratio: 4 / 3;
    place-items: center;
    overflow: hidden;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-lg);
    background:
        radial-gradient(circle, rgba(134, 93, 255, 0.13), transparent 55%),
        #050913;
    box-shadow: var(--shadow);
}

.game-detail-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.game-detail-cover img[width] {
    width: 150px;
    height: 150px;
    object-fit: contain;
    opacity: 0.66;
}

.game-detail-layout {
    display: grid;
    align-items: start;
    grid-template-columns: 1.15fr 0.85fr;
    gap: clamp(45px, 8vw, 105px);
}

.game-description > p:last-child {
    max-width: 760px;
    margin-bottom: 0;
    color: var(--text-soft);
    font-size: 1.06rem;
}

.rights-card {
    padding: 28px;
    border: 1px solid rgba(92, 227, 161, 0.24);
    border-radius: var(--radius);
    background:
        linear-gradient(145deg, rgba(92, 227, 161, 0.05), transparent 48%),
        var(--surface);
}

.rights-card-heading {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 18px;
}

.rights-card-heading .verified-mark {
    flex: 0 0 auto;
    margin-top: 2px;
    margin-right: 0;
}

.rights-card h2 {
    margin-bottom: 0;
    font-size: 1.45rem;
}

.rights-card > p {
    color: var(--muted);
    font-size: 0.9rem;
}

.rights-card dl {
    margin: 24px 0 0;
}

.rights-card dl > div {
    display: grid;
    padding: 14px 0;
    border-top: 1px solid var(--line);
    grid-template-columns: 0.8fr 1.2fr;
    gap: 16px;
}

.rights-card dt {
    color: var(--muted);
    font-size: 0.77rem;
}

.rights-card dd {
    margin: 0;
    color: var(--text);
    font-size: 0.8rem;
    font-weight: 720;
}

.rights-card .rights-territory-note {
    margin: 18px 0 0;
    padding-top: 16px;
    border-top: 1px solid var(--line);
    font-size: 0.76rem;
}

.game-passport-card {
    max-width: none;
}

.passport-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}

.passport-tags span {
    padding: 4px 8px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.025);
    font-size: 0.72rem;
}

.passport-pending,
.compatibility-empty {
    padding: 28px;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius);
    background: rgba(255, 255, 255, 0.018);
}

.passport-pending h3,
.passport-pending p,
.compatibility-empty {
    margin-bottom: 0;
}

.compatibility-heading {
    max-width: 750px;
    margin: 58px 0 26px;
}

.compatibility-heading h3 {
    margin-bottom: 8px;
    font-size: 1.65rem;
}

.compatibility-heading p {
    margin-bottom: 0;
    color: var(--muted);
}

.compatibility-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.compatibility-card {
    padding: 24px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.compatibility-card-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
}

.compatibility-card h4 {
    margin: 12px 0 8px;
    font-size: 1.12rem;
}

.compatibility-card p {
    margin-bottom: 8px;
    color: var(--muted);
    font-size: 0.83rem;
}

.compatibility-result {
    flex: 0 0 auto;
    padding: 5px 9px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    color: var(--text-soft);
    font-size: 0.64rem;
    font-weight: 800;
}

.compatibility-result.result-compatible {
    border-color: rgba(92, 227, 161, 0.32);
    color: var(--success);
}

.compatibility-result.result-compatible_with_limitations {
    border-color: rgba(255, 201, 107, 0.32);
    color: var(--warning);
}

.compatibility-result.result-incompatible {
    border-color: rgba(255, 123, 142, 0.32);
    color: var(--danger);
}

.compatibility-card .compatibility-evidence {
    color: var(--brand);
}

.compatibility-card .compatibility-notes {
    margin-top: 15px;
    padding-top: 15px;
    border-top: 1px solid var(--line);
    color: var(--text-soft);
}

.game-prelaunch {
    text-align: center;
}

.game-prelaunch p:not(.eyebrow) {
    max-width: 690px;
    margin: 0 auto 28px;
}

/* Creator and partner pages */
.page-hero-grid {
    display: grid;
    align-items: center;
    grid-template-columns: 1.1fr 0.9fr;
    gap: clamp(55px, 9vw, 120px);
}

.page-hero-grid h1 {
    max-width: 850px;
}

.page-hero-grid .page-lead {
    margin-bottom: 30px;
}

.creator-hero {
    background:
        radial-gradient(circle at 75% 40%, rgba(240, 75, 189, 0.1), transparent 30rem),
        linear-gradient(to bottom, rgba(14, 20, 34, 0.65), transparent);
}

.creator-console {
    width: min(100%, 440px);
    margin-inline: auto;
    padding: 26px 24px 30px;
    border: 1px solid rgba(134, 93, 255, 0.28);
    border-radius: 28px 28px 48px 28px;
    background: linear-gradient(145deg, #182337, #0a0f19);
    box-shadow: var(--shadow);
    transform: rotate(3deg);
}

.console-screen {
    position: relative;
    display: grid;
    min-height: 265px;
    place-content: center;
    overflow: hidden;
    border: 10px solid #05070d;
    border-radius: 15px;
    background:
        linear-gradient(rgba(134, 93, 255, 0.035) 1px, transparent 1px),
        linear-gradient(90deg, rgba(134, 93, 255, 0.035) 1px, transparent 1px),
        radial-gradient(circle, rgba(134, 93, 255, 0.11), transparent 55%),
        #061018;
    background-size: 14px 14px, 14px 14px, auto, auto;
    text-align: center;
}

.console-screen > span {
    color: var(--muted);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.7rem;
    font-weight: 900;
    letter-spacing: 0.15em;
}

.console-screen strong {
    margin-top: 6px;
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 1.2rem;
}

.console-sprite {
    width: 28px;
    height: 28px;
    margin: 28px auto 0;
    background: var(--magenta);
    box-shadow:
        28px 0 var(--brand),
        -28px 0 var(--violet),
        0 28px var(--brand),
        0 -28px var(--violet);
    transform: rotate(45deg);
}

.console-controls {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 26px 14px 0;
}

.console-controls i {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--magenta);
    box-shadow: inset 0 -4px rgba(0, 0, 0, 0.3);
}

.console-controls i:nth-child(2) {
    background: var(--brand);
}

.console-controls span {
    width: 48px;
    height: 10px;
    margin-left: auto;
    border-radius: 5px;
    background: #05070c;
}

.console-controls span:last-child {
    width: 10px;
    margin-left: 0;
}

.value-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
}

.value-grid article {
    min-height: 285px;
    padding: 28px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(13, 18, 30, 0.76);
}

.value-grid article > span {
    display: block;
    margin-bottom: 70px;
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.68rem;
    font-weight: 850;
}

.value-grid h3 {
    margin-bottom: 12px;
}

.value-grid p {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.split-section {
    display: grid;
    align-items: start;
    grid-template-columns: 0.85fr 1.15fr;
    gap: clamp(60px, 10vw, 140px);
}

.split-section h2 {
    max-width: 500px;
}

.check-list {
    display: grid;
    gap: 1px;
    margin: 0;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--line);
    list-style: none;
}

.check-list li {
    display: flex;
    min-height: 58px;
    align-items: center;
    gap: 13px;
    padding: 13px 18px;
    background: rgba(8, 12, 21, 0.98);
    color: var(--text-soft);
    font-weight: 650;
}

.check-list span {
    color: var(--success);
}

.process-grid {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
    grid-template-columns: repeat(4, 1fr);
}

.process-grid li {
    position: relative;
    min-height: 275px;
    padding: 28px;
    border-block: 1px solid var(--line);
    border-left: 1px solid var(--line);
}

.process-grid li:last-child {
    border-right: 1px solid var(--line);
}

.process-grid li > span {
    display: block;
    margin-bottom: 70px;
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 850;
}

.process-grid h3 {
    margin-bottom: 12px;
}

.process-grid p {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.partner-page-hero {
    min-height: 650px;
}

.rights-hero {
    background:
        radial-gradient(circle at 78% 38%, rgba(143, 108, 255, 0.12), transparent 31rem),
        linear-gradient(to bottom, rgba(14, 20, 34, 0.65), transparent);
}

.pro-hero {
    background:
        radial-gradient(circle at 78% 38%, rgba(240, 75, 189, 0.1), transparent 31rem),
        linear-gradient(to bottom, rgba(14, 20, 34, 0.65), transparent);
}

.partner-hero-visual {
    position: relative;
    display: grid;
    min-height: 430px;
    place-items: center;
}

.partner-hero-visual > img {
    position: relative;
    z-index: 3;
    border-radius: 24px;
    box-shadow: 0 0 65px rgba(134, 93, 255, 0.24);
}

.connection-lines {
    position: absolute;
    inset: 12%;
    border: 1px solid rgba(134, 93, 255, 0.15);
    border-radius: 50%;
}

.connection-lines::before,
.connection-lines::after {
    position: absolute;
    inset: 18%;
    border: 1px dashed rgba(143, 108, 255, 0.2);
    border-radius: 50%;
    content: "";
}

.connection-lines::after {
    inset: 36%;
    border-style: solid;
    border-color: rgba(240, 75, 189, 0.18);
}

.node {
    position: absolute;
    z-index: 4;
    display: grid;
    min-width: 58px;
    min-height: 34px;
    place-items: center;
    padding: 6px 9px;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: #0b111d;
    box-shadow: 0 14px 30px rgba(0, 0, 0, 0.3);
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.62rem;
    font-weight: 850;
}

.node-a {
    top: 10%;
    left: 19%;
}

.node-b {
    top: 32%;
    right: 6%;
}

.node-c {
    bottom: 12%;
    left: 15%;
}

/* Forms */
.form-section {
    border-top: 1px solid var(--line);
    background:
        radial-gradient(circle at 18% 45%, rgba(134, 93, 255, 0.07), transparent 30rem),
        #050810;
}

.form-layout {
    display: grid;
    align-items: start;
    grid-template-columns: 0.75fr 1.25fr;
    gap: clamp(55px, 9vw, 120px);
}

.form-intro {
    position: sticky;
    top: 130px;
}

.form-intro h2 {
    margin-bottom: 22px;
}

.form-security {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 28px;
}

.form-security > span {
    display: grid;
    width: 26px;
    height: 26px;
    place-items: center;
    border-radius: 50%;
    background: rgba(92, 227, 161, 0.1);
    color: var(--success);
    font-size: 0.72rem;
    font-weight: 900;
}

.form-security p {
    margin: 0;
    color: var(--muted);
    font-size: 0.78rem;
}

.form-panel {
    padding: clamp(24px, 4vw, 42px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: rgba(13, 18, 30, 0.92);
    box-shadow: var(--shadow);
}

.submission-form {
    display: grid;
    gap: 22px;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
}

.field {
    display: grid;
    gap: 8px;
}

.field label {
    color: var(--text-soft);
    font-size: 0.78rem;
    font-weight: 750;
}

.field label span {
    color: var(--brand);
}

.field input,
.field textarea,
.newsletter-form input[type="email"] {
    width: 100%;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background: rgba(4, 7, 13, 0.82);
    color: var(--text);
    transition: border-color 160ms ease, box-shadow 160ms ease;
}

.field input {
    min-height: 50px;
    padding: 12px 14px;
}

.field textarea {
    min-height: 160px;
    padding: 13px 14px;
    line-height: 1.55;
    resize: vertical;
}

.field input::placeholder,
.field textarea::placeholder,
.newsletter-form input::placeholder {
    color: #7e899e;
}

.field input:focus,
.field textarea:focus,
.newsletter-form input[type="email"]:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 4px rgba(134, 93, 255, 0.08);
    outline: 0;
}

.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
    border-color: var(--danger);
}

.field-error {
    margin: 0;
    color: var(--danger);
    font-size: 0.76rem;
}

.form-error-summary {
    padding: 14px 16px;
    border: 1px solid rgba(255, 123, 142, 0.45);
    border-radius: 10px;
    background: rgba(73, 28, 39, 0.52);
    color: var(--text);
}

.form-error-summary:focus {
    outline: 3px solid rgba(255, 123, 142, 0.32);
    outline-offset: 3px;
}

.form-error-summary p {
    margin: 0;
    font-weight: 750;
}

.declaration-line,
.consent-line {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    color: var(--text-soft);
    cursor: pointer;
    font-size: 0.8rem;
    line-height: 1.5;
}

.declaration-line input,
.consent-line input {
    width: 17px;
    height: 17px;
    flex: 0 0 auto;
    margin-top: 2px;
    accent-color: var(--brand);
}

.declaration-line.has-error {
    color: var(--danger);
}

.legal-note {
    margin: 0;
    color: var(--muted);
    font-size: 0.72rem;
}

.legal-note a {
    color: var(--brand);
}

/* Mission */
.mission-hero {
    padding-bottom: 145px;
    text-align: center;
}

.mission-hero .page-lead {
    margin-inline: auto;
}

.manifesto-statement {
    padding: clamp(90px, 12vw, 170px) 0;
    border-bottom: 1px solid var(--line);
    background:
        linear-gradient(125deg, rgba(134, 93, 255, 0.08), rgba(143, 108, 255, 0.07) 55%, rgba(240, 75, 189, 0.06)),
        #080c15;
    text-align: center;
}

.manifesto-statement .container {
    max-width: 980px;
}

.manifesto-mark {
    display: block;
    height: 65px;
    color: var(--brand);
    font-family: Georgia, serif;
    font-size: 7rem;
    line-height: 1;
    opacity: 0.55;
}

.manifesto-statement h2 {
    margin-bottom: 25px;
}

.manifesto-statement p {
    max-width: 800px;
    margin: 0 auto;
    font-size: 1.15rem;
}

.mission-principles {
    max-width: 960px;
    margin: 0 auto;
    padding: 0;
    border-top: 1px solid var(--line);
    list-style: none;
}

.mission-principles li {
    display: grid;
    padding: 34px 0;
    border-bottom: 1px solid var(--line);
    grid-template-columns: 90px 1fr;
    gap: 20px;
}

.mission-principles li > span {
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 850;
}

.mission-principles h3 {
    margin-bottom: 9px;
    font-size: 1.45rem;
}

.mission-principles p {
    margin: 0;
    color: var(--muted);
}

/* La preservation, sur la page mission : trois blocs de meme hauteur, un seul sur telephone. */
.mission-preservation {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 22px;
}

.mission-preservation article {
    display: flex;
    flex-direction: column;
    padding: 30px 28px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.mission-preservation h3 {
    margin-bottom: 12px;
    font-size: 1.3rem;
    text-wrap: balance;
}

.mission-preservation p {
    margin: 0;
    color: var(--text-soft);
}

.mission-preservation a {
    margin-top: auto;
    padding-top: 20px;
    color: var(--brand-bright);
    font-weight: 700;
}

@media (max-width: 900px) {
    .mission-preservation {
        grid-template-columns: 1fr;
    }
}

.boundary-block {
    display: grid;
    align-items: center;
    grid-template-columns: auto 1fr;
    gap: clamp(35px, 7vw, 80px);
}

.boundary-block img {
    /* Ni cadre ni halo cyan : le halo appartenait a NelfeTech. */
}

.boundary-block h2 {
    margin-bottom: 20px;
}

.boundary-block p:last-child {
    max-width: 820px;
    margin-bottom: 0;
}

/* Legal */
.legal-hero {
    padding-bottom: 65px;
}

.legal-container {
    width: min(calc(100% - 40px), 980px);
}

.legal-hero h1 {
    font-size: clamp(2.8rem, 5vw, 5rem);
}

.legal-section {
    padding-top: 70px;
}

.legal-layout {
    display: grid;
    align-items: start;
    grid-template-columns: 230px 1fr;
    gap: clamp(50px, 8vw, 110px);
}

.legal-nav {
    position: sticky;
    top: 110px;
    display: grid;
    gap: 5px;
}

.legal-nav a {
    padding: 9px 12px;
    border-left: 2px solid transparent;
    color: var(--muted);
    font-size: 0.84rem;
    font-weight: 700;
    text-decoration: none;
}

.legal-nav a:hover,
.legal-nav a.is-active {
    border-left-color: var(--brand);
    background: rgba(134, 93, 255, 0.045);
    color: var(--text);
}

.legal-content {
    max-width: 760px;
}

.legal-content > section {
    margin-bottom: 55px;
}

.legal-content h2 {
    margin-bottom: 18px;
    font-size: 1.65rem;
}

.legal-content p {
    color: var(--text-soft);
}

.legal-contact {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    padding: 22px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
}

.legal-contact a {
    color: var(--brand);
    font-weight: 750;
}

/* Footer */
.site-footer {
    border-top: 1px solid var(--line);
    background: var(--bg-deep);
}

.footer-newsletter {
    display: grid;
    align-items: center;
    padding-block: clamp(70px, 9vw, 115px);
    border-bottom: 1px solid var(--line);
    grid-template-columns: 0.82fr 1.18fr;
    gap: clamp(45px, 8vw, 100px);
}

.footer-newsletter h2 {
    margin-bottom: 15px;
    font-size: clamp(2rem, 3.8vw, 3.5rem);
}

.footer-newsletter p:last-child {
    margin-bottom: 0;
}

.newsletter-form {
    display: grid;
    gap: 14px;
}

.newsletter-privacy {
    margin: 0;
    color: #7e899e;
    font-size: 0.72rem;
}

.newsletter-privacy a {
    color: var(--brand-bright);
}

.newsletter-row {
    display: flex;
    gap: 10px;
}

.newsletter-form input[type="email"] {
    min-height: 54px;
    padding: 12px 15px;
}

.newsletter-form .button {
    flex: 0 0 auto;
}

.footer-grid {
    display: grid;
    padding-block: 65px;
    grid-template-columns: 2fr repeat(3, 1fr);
    gap: 55px;
}

.footer-grid > div:not(.footer-brand) {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
}

.footer-grid h3 {
    margin-bottom: 8px;
    color: var(--text);
    font-size: 0.78rem;
    font-weight: 850;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.footer-grid a:not(.brand) {
    color: var(--muted);
    font-size: 0.82rem;
    text-decoration: none;
    overflow-wrap: anywhere;
}

.footer-grid a:not(.brand):hover {
    color: var(--brand-bright);
}

.footer-brand > p {
    max-width: 320px;
    margin: 20px 0 16px;
    color: var(--muted);
    font-size: 0.9rem;
}

.privacy-signal {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: #718098;
    font-size: 0.68rem;
}

.privacy-signal > span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--success);
}

.footer-bottom {
    display: flex;
    min-height: 70px;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    border-top: 1px solid var(--line);
    color: #78859b;
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.65rem;
    letter-spacing: 0.04em;
}

/* Errors */
.error-page {
    display: grid;
    min-height: 650px;
    place-items: center;
    padding: 100px 0;
    text-align: center;
}

.error-page img {
    margin: 0 auto 25px;
}

.error-code {
    margin-bottom: -20px;
    color: rgba(134, 93, 255, 0.07);
    font-size: clamp(8rem, 25vw, 18rem);
    font-weight: 950;
    letter-spacing: -0.08em;
    line-height: 0.8;
}

.error-page h1 {
    margin-bottom: 15px;
    font-size: clamp(2rem, 5vw, 4rem);
}

.error-page p {
    margin-bottom: 28px;
}

.newsletter-action-hero {
    min-height: min(720px, calc(100vh - 70px));
}

.newsletter-action-form {
    margin-top: 28px;
}

/* Responsive */
@media (max-width: 1280px) {
    .header-inner {
        gap: 18px;
    }

    .primary-nav > a,
    .nav-group > button {
        padding-inline: 8px;
        font-size: 0.8rem;
    }

    .header-actions .button {
        display: none;
    }

    .hero-grid {
        grid-template-columns: 1fr 0.92fr;
        gap: 45px;
    }

    .value-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 1000px) {
    body.nav-open {
        overflow: hidden;
    }

    /* Le backdrop-filter du header crée un bloc conteneur qui casserait le
       position:fixed de l'overlay de nav (il serait clippé dans le header).
       On le neutralise pendant l'ouverture du menu. */
    body.nav-open .site-header {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    .header-inner {
        min-height: 70px;
    }

    .nav-toggle {
        position: relative;
        display: flex;
        margin-left: auto;
    }

    .primary-nav {
        position: fixed;
        top: 70px;
        right: 0;
        bottom: 0;
        left: 0;
        display: none;
        align-items: stretch;
        padding: 24px 20px 40px;
        background: rgba(5, 8, 15, 0.985);
        flex-direction: column;
        overflow-y: auto;
    }

    .primary-nav.is-open {
        display: flex;
    }

    .mobile-language-link,
    .mobile-launch-link,
    .mobile-account-link {
        display: flex;
    }

    .language-group.mobile-language-link {
        display: inline-flex;
        align-self: flex-start;
    }

    .mobile-launch-link {
        justify-content: center;
        margin-top: 12px;
        color: #041018;
    }

    .primary-nav > a,
    .nav-group > button {
        width: 100%;
        min-height: 52px;
        justify-content: space-between;
        padding: 13px 15px;
        font-size: 1rem;
        text-align: left;
    }

    .nav-popover {
        position: static;
        min-width: 0;
        margin: 4px 0 10px;
        border: 0;
        background: rgba(255, 255, 255, 0.025);
        box-shadow: none;
        transform: none;
    }

    .nav-popover a {
        padding: 13px 20px;
        white-space: normal;
    }

    .header-actions {
        display: none;
    }

    .hero {
        padding-top: 85px;
    }

    .hero-grid,
    .page-hero-grid,
    .game-detail-hero-grid,
    .game-detail-layout,
    .passport-layout,
    .trust-layout,
    .form-layout,
    .footer-newsletter,
    .empty-catalogue {
        grid-template-columns: 1fr;
    }

    .hero-copy {
        text-align: center;
    }

    .hero-copy .status-pill,
    .hero-actions {
        justify-content: center;
    }

    .hero-lead,
    .hero-proof,
    .transparency-note {
        margin-inline: auto;
    }

    .hero-visual {
        min-height: 510px;
    }

    .family-grid,
    .partner-grid,
    .game-grid,
    .compatibility-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .game-detail-layout {
        grid-template-columns: 1fr;
    }

    .family-card:last-child,
    .partner-card:last-child {
        grid-column: 1 / -1;
    }

    .trust-intro,
    .form-intro {
        position: static;
    }

    .journey-list {
        grid-template-columns: repeat(2, 1fr);
    }

    .journey-list li,
    .journey-list li:last-child {
        padding: 25px;
        border: 1px solid var(--line);
    }

    .journey-list li:last-child {
        grid-column: 1 / -1;
    }

    .journey-list li > span {
        margin-bottom: 30px;
    }

    .mission-banner-inner {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .mission-banner p,
    .mission-banner .text-link {
        margin-inline: auto;
    }

    .process-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .process-grid li,
    .process-grid li:last-child {
        border: 1px solid var(--line);
    }

    .partner-hero-visual {
        min-height: 360px;
    }

    .legal-layout {
        grid-template-columns: 1fr;
    }

    .legal-nav {
        position: static;
        display: flex;
        flex-wrap: wrap;
    }

    .legal-nav a {
        border-bottom: 2px solid transparent;
        border-left: 0;
    }

    .legal-nav a:hover,
    .legal-nav a.is-active {
        border-bottom-color: var(--brand);
        border-left-color: transparent;
    }

    .footer-grid {
        grid-template-columns: 2fr repeat(2, 1fr);
    }
}

@media (max-width: 640px) {
    .container,
    .container.narrow,
    .legal-container {
        width: min(calc(100% - 28px), var(--container));
    }

    h1 {
        font-size: clamp(2.55rem, 12.8vw, 3.5rem);
    }

    h2 {
        font-size: clamp(2rem, 10vw, 3.1rem);
    }

    .brand img {
        width: 40px;
        height: 40px;
    }

    .brand-name {
        font-size: 1.05rem;
    }

    .hero {
        min-height: auto;
        padding: 65px 0 85px;
    }

    .hero h1 {
        margin-top: 22px;
    }

    .hero-copy {
        min-width: 0;
    }

    .status-pill {
        max-width: 100%;
        align-items: flex-start;
        padding-inline: 10px;
        font-size: 0.59rem;
        letter-spacing: 0.055em;
        text-align: left;
    }

    .hero-actions .button {
        width: 100%;
    }

    .hero-visual {
        min-height: 450px;
    }

    .signal-card {
        padding: 14px;
        transform: none;
    }

    .signal-brand img {
        width: 42px;
        height: 42px;
    }

    .signal-screen {
        min-height: 170px;
    }

    .floating-chip {
        display: none;
    }

    .section {
        padding: 80px 0;
    }

    .section-heading {
        margin-bottom: 38px;
    }

    .section-heading-row {
        align-items: flex-start;
        flex-direction: column;
    }

    .family-grid,
    .trust-grid,
    .partner-grid,
    .game-grid,
    .compatibility-grid,
    .value-grid,
    .form-grid,
    .process-grid {
        grid-template-columns: 1fr;
    }

    .game-detail-hero {
        padding-top: 55px;
    }

    .game-detail-cover {
        border-radius: var(--radius);
    }

    .rights-card {
        padding: 20px;
    }

    .rights-card dl > div {
        grid-template-columns: 1fr;
        gap: 5px;
    }

    .compatibility-card-heading {
        align-items: flex-start;
        flex-direction: column;
        gap: 8px;
    }

    .family-card:last-child,
    .partner-card:last-child {
        grid-column: auto;
    }

    .family-card {
        min-height: 350px;
    }

    .trust-grid article,
    .value-grid article {
        min-height: auto;
    }

    .trust-icon,
    .value-grid article > span,
    .partner-kicker,
    .process-grid li > span {
        margin-bottom: 32px;
    }

    .passport-card {
        padding: 20px;
    }

    .passport-card dl > div {
        grid-template-columns: 1fr;
        gap: 5px;
    }

    .journey-list {
        grid-template-columns: 1fr;
        gap: 10px;
    }

    .journey-list li:last-child {
        grid-column: auto;
    }

    .mission-pixel {
        width: 190px;
        height: 190px;
    }

    .empty-catalogue {
        padding: 22px;
    }

    .empty-visual {
        min-height: 230px;
    }

    .page-hero {
        padding-top: 75px;
    }

    .page-hero-grid {
        text-align: center;
    }

    .page-hero-grid .page-lead {
        margin-inline: auto;
    }

    .creator-console {
        margin-top: 25px;
        transform: none;
    }

    .console-screen {
        min-height: 220px;
    }

    .split-section,
    .boundary-block {
        grid-template-columns: 1fr;
    }

    .boundary-block {
        text-align: center;
    }

    .boundary-block img {
        margin-inline: auto;
    }

    .process-grid {
        gap: 10px;
    }

    .process-grid li {
        min-height: auto;
    }

    .partner-hero-visual {
        min-height: 300px;
    }

    .form-panel {
        padding: 20px;
        border-radius: var(--radius);
    }

    .mission-principles li {
        grid-template-columns: 50px 1fr;
    }

    .newsletter-row {
        flex-direction: column;
    }

    .newsletter-form .button {
        width: 100%;
    }

    .footer-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 40px 30px;
    }

    .footer-brand {
        grid-column: 1 / -1;
    }

    .footer-bottom {
        align-items: flex-start;
        padding-block: 22px;
        flex-direction: column;
        justify-content: center;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        transition-duration: 0.001ms !important;
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
    }
}

/* Library */
.library-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 28px;
    margin-top: 26px;
    color: var(--muted);
    font-size: 0.86rem;
}

.library-stats strong {
    margin-right: 5px;
    color: var(--brand-bright);
    font-size: 1.15rem;
}

.library-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 26px;
}

.library-filters a {
    padding: 9px 15px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.02);
    color: var(--muted);
    font-size: 0.82rem;
    font-weight: 750;
    text-decoration: none;
    transition: border-color 160ms ease, color 160ms ease, background-color 160ms ease;
}

.library-filters a:hover {
    border-color: rgba(134, 93, 255, 0.4);
    color: var(--text);
}

.library-filters a.is-active {
    border-color: rgba(134, 93, 255, 0.55);
    background: rgba(134, 93, 255, 0.08);
    color: var(--brand-bright);
}

.library-card {
    display: flex;
    flex-direction: column;
}

.library-card .game-card-link {
    flex: 1;
}

.library-card-actions {
    display: grid;
    gap: 10px;
    padding: 0 24px 22px;
}

.library-card-actions form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.library-card-actions select {
    flex: 1;
    min-width: 130px;
    min-height: 42px;
    padding: 9px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background: rgba(4, 7, 13, 0.82);
    color: var(--text);
    font-size: 0.85rem;
}

.library-installed,
.library-pending {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: var(--muted);
    font-size: 0.82rem;
}

.library-installed {
    color: var(--success);
}

/* Creator space */
.creator-game-list {
    display: grid;
    gap: 14px;
}

.creator-game-row {
    display: grid;
    align-items: center;
    grid-template-columns: minmax(0, 1fr) minmax(200px, 280px);
    gap: 24px;
    padding: 24px 26px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.creator-game-row h2 {
    margin-bottom: 8px;
    font-size: 1.35rem;
}

.creator-game-row h2 a {
    color: inherit;
    text-decoration: none;
}

.creator-game-row h2 a:hover {
    color: var(--brand-bright);
}

.creator-current,
.creator-blocked {
    margin: 0;
    font-size: 0.87rem;
}

.creator-blocked {
    color: var(--warning);
}

.creator-done {
    color: var(--success);
}

.creator-game-progress {
    display: grid;
    gap: 9px;
    justify-items: start;
}

.creator-game-progress p {
    margin: 0;
    color: var(--muted);
    font-size: 0.78rem;
}

.progress-bar {
    width: 100%;
    height: 7px;
    overflow: hidden;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
}

.progress-bar span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, var(--brand), var(--brand-bright));
}

.review-steps {
    display: grid;
    gap: 12px;
    margin: 30px 0 0;
    padding: 0;
    list-style: none;
    counter-reset: step;
}

.review-step {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr);
    gap: 16px;
    padding: 20px 22px;
    border: 1px solid var(--line);
    border-left: 3px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: rgba(13, 19, 31, 0.72);
}

.review-step-index {
    display: grid;
    width: 30px;
    height: 30px;
    place-items: center;
    border-radius: 50%;
    background: rgba(134, 93, 255, 0.08);
    color: var(--brand);
    font-family: "Cascadia Code", Consolas, monospace;
    font-size: 0.76rem;
    font-weight: 850;
}

.review-step h3 {
    margin-bottom: 5px;
    font-size: 1.05rem;
}

.review-step p {
    margin: 0 0 4px;
    font-size: 0.85rem;
}

.review-step-status {
    color: var(--text);
    font-weight: 750;
}

.review-step-help {
    color: var(--muted);
}

.review-step-note {
    margin-top: 8px !important;
    padding-top: 8px;
    border-top: 1px solid var(--line);
    color: var(--warning);
}

.review-step-approved {
    border-left-color: var(--success);
}

.review-step-approved .review-step-status {
    color: var(--success);
}

.review-step-in_review {
    border-left-color: var(--brand);
}

.review-step-in_review .review-step-status {
    color: var(--brand-bright);
}

.review-step-changes_requested {
    border-left-color: var(--warning);
}

.review-step-changes_requested .review-step-status {
    color: var(--warning);
}

.media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 16px;
}

.media-slot {
    display: grid;
    align-content: start;
    gap: 10px;
    padding: 22px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.media-slot h3 {
    margin: 0;
    font-size: 1rem;
}

.media-hint {
    margin: 0;
    color: var(--muted);
    font-size: 0.78rem;
}

.media-item {
    display: grid;
    gap: 8px;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: rgba(4, 7, 13, 0.6);
}

.media-item img {
    width: 100%;
    border-radius: 6px;
}

.media-status {
    margin: 0;
    color: var(--muted);
    font-size: 0.75rem;
}

.media-item-approved {
    border-color: rgba(92, 227, 161, 0.3);
}

.media-item-rejected {
    border-color: rgba(255, 123, 142, 0.35);
}

.media-upload {
    display: grid;
    gap: 8px;
}

.media-upload input[type="file"] {
    width: 100%;
    padding: 9px;
    border: 1px dashed var(--line-strong);
    border-radius: 8px;
    background: rgba(4, 7, 13, 0.55);
    color: var(--muted);
    font-size: 0.78rem;
}

@media (max-width: 760px) {
    .creator-game-row {
        grid-template-columns: 1fr;
    }
}

/* Recherche du catalogue - même vocabulaire visuel que les autres champs. */
.catalogue-search {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-bottom: 28px;
}

.catalogue-search label {
    flex: 0 0 100%;
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--brand);
}

.catalogue-search input[type="search"] {
    flex: 1 1 260px;
    min-height: 48px;
    padding: 12px 14px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background: rgba(4, 7, 13, 0.82);
    color: var(--text);
    transition: border-color 160ms ease, box-shadow 160ms ease;
}

.catalogue-search input[type="search"]::placeholder {
    color: #7e899e;
}

.catalogue-search input[type="search"]:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 4px rgba(134, 93, 255, 0.08);
    outline: 0;
}

@media (max-width: 620px) {
    .catalogue-search input[type="search"] {
        flex-basis: 100%;
    }
}

/* Identite en en-tete : « Se connecter », puis le pseudo une fois connecte. */
.account-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.account-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--brand);
    color: #041018;
    font-size: 0.78rem;
    font-weight: 700;
}

/* Visuel large + logo : la carte se regarde avant de se lire. */
.game-cover.has-hero,
.game-detail-cover.has-hero {
    position: relative;
    overflow: hidden;
    display: block;
    padding: 0;
    border-radius: 12px;
}

/* La fiche adopte le 4:3 : c'est le format des jeux montrés et celui de leurs
   bandes-annonces, donc une image qui remplit sans bandes ni recadrage. */
.game-detail-cover.has-hero {
    aspect-ratio: 4 / 3;
}

.game-cover.has-hero .game-hero,
.game-detail-cover.has-hero .game-hero {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.game-cover.has-hero .game-logo,
.game-detail-cover.has-hero .game-logo {
    position: absolute;
    left: 50%;
    bottom: 12%;
    /* Le logo est le TITRE du decor sur lequel il est pose, pas une vignette
       posee dessus : sous 90 % il flotte au milieu de l'image sans se lire. */
    width: 90%;
    transform: translateX(-50%);
    filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.6));
}

.game-cover.has-hero::after,
.game-detail-cover.has-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(4, 7, 13, 0.72) 0%, rgba(4, 7, 13, 0) 55%);
    pointer-events: none;
}

.game-detail-cover.has-hero {
    width: 100%;
}

/* ── Vitrine éditoriale : une à la une, puis des rayons horizontaux ──────── */
.spotlight-card {
    display: grid;
    /* Le visuel passe en 4:3 à HAUTEUR CONSTANTE : il devient donc plus
       étroit, et le texte récupère la place. Élargir le visuel l'aurait au
       contraire fait grandir en hauteur, ce qui n'était pas le but. */
    grid-template-columns: minmax(0, 0.45fr) minmax(0, 1fr);
    gap: 28px;
    align-items: center;
    padding: 22px;
    border: 1px solid var(--line-strong);
    border-radius: 16px;
    background: rgba(8, 12, 20, 0.6);
    color: inherit;
    text-decoration: none;
    transition: border-color 180ms ease, transform 180ms ease;
}

.spotlight-card:hover,
.spotlight-card:focus-visible {
    border-color: var(--brand);
    transform: translateY(-2px);
}

.spotlight-visual {
    position: relative;
    overflow: hidden;
    border-radius: 12px;
    aspect-ratio: 5 / 2;
}

.spotlight-visual img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.spotlight-visual.has-hero .game-logo {
    position: absolute;
    left: 50%;
    bottom: 12%;
    width: min(70%, 340px);
    height: auto;
    transform: translateX(-50%);
    filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.6));
}

.spotlight-body h2 {
    margin: 8px 0 10px;
}

.rail-note {
    margin: -6px 0 16px;
    color: #9ba7bb;
    font-size: 0.94rem;
}

.rail-track {
    display: flex;
    gap: 16px;
    margin: 0;
    padding: 4px 4px 14px;
    list-style: none;
    overflow-x: auto;
    scroll-snap-type: x proximity;
}

.rail-track > li {
    flex: 0 0 232px;
    scroll-snap-align: start;
}

.rail-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    color: inherit;
    text-decoration: none;
}

.rail-visual {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: 10px;
    border: 1px solid var(--line-strong);
    aspect-ratio: var(--card-ratio);
    background: rgba(4, 7, 13, 0.7);
    transition: border-color 160ms ease;
}

.rail-visual img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rail-visual.has-hero .game-logo {
    position: absolute;
    left: 50%;
    bottom: 10%;
    width: min(76%, 200px);
    height: auto;
    transform: translateX(-50%);
    filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.65));
}

.rail-card:hover .rail-visual,
.rail-card:focus-visible .rail-visual {
    border-color: var(--brand);
}

.rail-title {
    font-weight: 600;
    line-height: 1.3;
}

.rail-system {
    color: #7e899e;
    font-size: 0.84rem;
}

@media (max-width: 780px) {
    .spotlight-card {
        grid-template-columns: 1fr;
    }

    .rail-track > li {
        flex-basis: 190px;
    }
}

/* La vidéo prend la place du visuel, exactement au même cadrage.
   Un agrandissement léger mange les bandes noires que YouTube ajoute autour
   d'une image 4/3 dans son lecteur 16/9. On ne va pas plus loin : la valeur
   exacte dépendrait du format de chaque bande-annonce, qu'on ne connaît pas -
   et le fond de matière derrière rend les bandes restantes acceptables. */
.rail-visual iframe,
.spotlight-visual iframe,
.game-cover iframe,
.game-detail-cover iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    transform: scale(1.18);
    transform-origin: center;
}

/* Fond de matière : la capture du jeu, très atténuée, DERRIÈRE le lecteur.
   Les bandes noires deviennent une texture qui vient du jeu lui-même plutôt
   qu'un vide. Le motif reste discret - on regarde la vidéo, pas le fond. */
.rail-visual,
.spotlight-visual,
.game-cover,
.game-detail-cover {
    background-image: var(--game-backdrop, none);
    background-size: cover;
    background-position: center;
}

.is-playing::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: var(--game-backdrop, none);
    background-size: cover;
    background-position: center;
    opacity: 0.16;
    filter: blur(2px) saturate(0.8);
    pointer-events: none;
}

.is-playing .game-logo,
.is-playing::after {
    opacity: 0;
    transition: opacity 180ms ease;
}

/* Hors lecture, la carte se réchauffe au survol : la capture apparaît en
   filigrane derrière son propre contenu. */
.rail-card:hover .rail-visual::before,
.game-card:hover .game-cover::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: var(--game-backdrop, none);
    background-size: cover;
    background-position: center;
    opacity: 0.12;
    pointer-events: none;
}

/* Mention des marques : présente, lisible, sans peser sur la page. */
.footer-legal {
    padding-bottom: 22px;
}

.footer-legal p {
    margin: 0;
    max-width: 74ch;
    color: #6b788d;
    font-size: 0.78rem;
    line-height: 1.5;
}

/* ── Espace d'examen : dense, lisible, sans décor ─────────────────────────── */
/* Ecran des entrees de formulaire. « admin-muted » etait deja employe par
   trois gabarits sans qu'aucune regle ne le definisse : il rendait comme du
   texte ordinaire. */
.admin-muted {
    color: var(--muted);
    font-size: 0.85rem;
}

.admin-inline-edit > summary {
    cursor: pointer;
    color: var(--brand);
    font-size: 0.85rem;
    width: fit-content;
}

.admin-submission-message {
    margin: 8px 0 0;
    padding: 10px 12px;
    border-left: 2px solid var(--line-strong);
    color: var(--text-soft);
    font-size: 0.88rem;
    line-height: 1.6;
    white-space: normal;
}

/* Ce qui tombe sous trente jours : la seule alerte qui existe pour une
   proposition que la retention va effacer. */
.admin-expiring {
    color: var(--danger);
    font-weight: 700;
}

.admin-table-wrap { overflow-x: auto; }
/* Parties reçues : « Détail » et « Accepter » côte à côte. */
.partie-actions { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.partie-actions form { margin: 0; }

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}

.admin-table th,
.admin-table td {
    padding: 11px 12px;
    border-bottom: 1px solid var(--line-strong);
    text-align: left;
    vertical-align: top;
}

.admin-table th {
    font-size: 0.76rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--brand);
}

.admin-meta {
    display: block;
    margin-top: 3px;
    color: #7e899e;
    font-size: 0.82rem;
}

.admin-warn { color: #f2a852; }

.admin-pill {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 999px;
    border: 1px solid var(--line-strong);
    font-size: 0.76rem;
    white-space: nowrap;
}

.admin-pill-approved,
.admin-pill-accepted { border-color: #52f2dc; color: #52f2dc; }
.admin-pill-pending,
.admin-pill-to_contact { border-color: #f2a852; color: #f2a852; }
.admin-pill-rejected { border-color: #f25277; color: #f25277; }
.admin-pill-itch { border-color: #9a7cf2; color: #9a7cf2; }

.admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* ── Page de balade : le lien EST la ligne ────────────────────────────────── */
.source-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.source-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--line-strong);
}

.source-row.is-incomplete { background: rgba(242, 168, 82, 0.05); }

.source-link {
    display: flex;
    flex-direction: column;
    gap: 2px;
    color: inherit;
    text-decoration: none;
}

.source-link:hover .source-title,
.source-link:focus-visible .source-title { color: var(--brand); }

.source-title { font-weight: 600; }

.source-url {
    color: #7e899e;
    font-size: 0.82rem;
    word-break: break-all;
}

.source-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

/* Coche de complétude : lisible d'un balayage vertical. */
.source-check {
    display: inline-block;
    width: 1.1em;
    color: #52f2dc;
    font-weight: 700;
}

.source-check-empty { color: #46536a; }

/* Un lien mort se voit avant d'être cliqué. */
.source-row.is-dead .source-url { text-decoration: line-through; opacity: 0.7; }
.source-row.is-dead { background: rgba(242, 82, 119, 0.06); }

/* Choix des visuels : on compare à l'œil, donc les vignettes sont grandes. */
.media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 16px;
}

.media-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    overflow: hidden;
    background: rgba(8, 12, 20, 0.6);
}

.media-card.is-chosen { border-color: var(--brand); }

.media-thumb {
    display: grid;
    place-items: center;
    aspect-ratio: var(--card-ratio);
    background: #04070d;
    overflow: hidden;
}

.media-thumb img { width: 100%; height: 100%; object-fit: cover; }

.media-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
}

/* Pendant le chargement, la vignette masque le lecteur : c'est le moment où
   YouTube affiche son titre et sa jaquette. On ne le découvre qu'une fois
   l'image lancée. */
.is-loading iframe {
    opacity: 0;
}

.is-playing iframe {
    opacity: 1;
    transition: opacity 220ms ease;
}

/* ── Pages de liste : un rythme serré ────────────────────────────────────────
   Le rythme d'origine a été dessiné pour des pages de discours : trois ou
   quatre sections longues, très aérées. La boutique en empile neuf, plus sept
   titres - soit près de 3 300 pixels de vide, trois écrans avant le contenu.
   Une page qui aligne des rangées se parcourt, elle ne se lit pas : on resserre
   là, et là seulement. Les pages éditoriales gardent leur air. */
.is-dense .section {
    padding: clamp(26px, 2.6vw, 44px) 0;
}

.is-dense .page-hero {
    padding: clamp(40px, 4.5vw, 72px) 0 clamp(24px, 2.6vw, 40px);
}

.is-dense .section-heading {
    margin-bottom: 18px;
}

.is-dense .section-heading h2 {
    margin-bottom: 4px;
}

.is-dense .page-hero h1 {
    margin-bottom: 12px;
}

/* Les rangées se suivent : un rayon collé au suivant se lit comme une suite,
   pas comme une succession de pages. */
.is-dense .section-rail {
    padding: clamp(14px, 1.4vw, 22px) 0;
}

.is-dense .section-spotlight {
    padding-bottom: clamp(14px, 1.4vw, 22px);
}

.is-dense .rail-note {
    margin: -4px 0 10px;
}

/* Écarter est irréversible : le bouton ne se confond pas avec les autres. */
.button-danger { border-color: rgba(242, 82, 119, 0.5); color: #f25277; }
.button-danger:hover { border-color: #f25277; background: rgba(242, 82, 119, 0.08); }

/* Bande-annonce et réglage côte à côte : on juge la vidéo en la voyant. */
.trailer-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 22px;
    align-items: start;
}

.trailer-preview {
    position: relative;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    overflow: hidden;
    background: #04070d;
}

.trailer-preview iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

@media (max-width: 860px) {
    .trailer-layout { grid-template-columns: 1fr; }
}

/* Agrandissement d'un visuel : l'image occupe la place, rien d'autre. */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    place-items: center;
    padding: 28px;
    background: rgba(3, 5, 10, 0.92);
}

.lightbox[hidden] { display: none; }

.lightbox figure {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0;
    max-width: min(1200px, 92vw);
}

.lightbox img {
    max-width: 100%;
    max-height: 82vh;
    object-fit: contain;
    border-radius: 10px;
    /* Les captures rétro sont minuscules : on les agrandit sans les lisser,
       sinon un 256x240 devient une bouillie. */
    image-rendering: pixelated;
}

.lightbox figcaption {
    color: #9ba7bb;
    font-size: 0.86rem;
    text-align: center;
}

.lightbox-close {
    position: absolute;
    top: 18px;
    right: 22px;
    width: 42px;
    height: 42px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    background: rgba(8, 12, 20, 0.9);
    color: #f4f7fb;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.lightbox-close:hover { border-color: var(--brand); color: var(--brand); }

body.has-lightbox { overflow: hidden; }

.media-thumb[data-zoom] { cursor: zoom-in; }

/* Navigation d'examen : passer au titre suivant sans revenir à la liste. */
.review-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

/* Le curseur ne doit JAMAIS atteindre le lecteur sur une carte : survoler
   l'iframe fait apparaître les commandes de YouTube, son titre et ses
   suggestions. La carte garde son propre survol, et le clic continue de mener
   à la fiche du jeu au lieu d'être avalé par le lecteur. La prévisualisation
   de l'espace d'examen, elle, reste pilotable : on y juge la vidéo. */
.rail-visual iframe,
.spotlight-visual iframe,
.game-cover iframe,
.game-detail-cover iframe {
    pointer-events: none;
}

/* Le champ de titre ne doit pas voler la vedette au titre lui-même. */
.rename-form { margin-top: 10px; }
.rename-form input[type="text"] {
    flex: 1 1 320px;
    min-height: 40px;
    padding: 8px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: rgba(4, 7, 13, 0.82);
    color: var(--text);
}
.rename-form input[type="text"]:focus { border-color: var(--brand); outline: 0; }

/* Onglets de langue : deux boutons radio et la cascade. Aucun script, donc
   rien à charger et rien qui puisse échouer. */
.lang-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.lang-radio { position: absolute; opacity: 0; pointer-events: none; }

.lang-label {
    order: -1;
    padding: 7px 16px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    color: #9ba7bb;
    font-size: 0.84rem;
    letter-spacing: 0.06em;
    cursor: pointer;
}

.lang-radio:checked + .lang-label {
    border-color: var(--brand);
    color: var(--brand);
}

.lang-radio:focus-visible + .lang-label { outline: 2px solid var(--brand); outline-offset: 2px; }

.lang-panel { display: none; flex: 1 1 100%; }
.lang-radio:checked + .lang-label + .lang-panel { display: block; }

.lang-form {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-width: 780px;
    margin-top: 14px;
}

.lang-form label {
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--brand);
}

.lang-form input[type="text"],
.lang-form textarea {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: rgba(4, 7, 13, 0.82);
    color: var(--text);
    font: inherit;
}

.lang-form textarea { resize: vertical; line-height: 1.55; }
.lang-form input:focus, .lang-form textarea:focus { border-color: var(--brand); outline: 0; }
.lang-form button { align-self: flex-start; margin-top: 6px; }

/* Un emplacement de fichier : son adresse, puis son état sur le serveur. */
.file-slot {
    padding: 14px 0;
    border-bottom: 1px solid var(--line);
}

.file-state {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 6px;
}

.file-state .admin-meta { margin-top: 0; }

/* La une passe en 4:3.
   C'est le format des jeux qu'on montre, et celui de leurs bandes-annonces :
   une image 4:3 dans un cadre 4:3 remplit sans bandes ni recadrage. Les
   vignettes de rangée, elles, gardent leur 16:9 - elles s'alignent, la une
   s'expose. */
.spotlight-visual {
    aspect-ratio: 4 / 3;
}

/* Le lecteur n'a plus rien à rattraper ici : pas d'agrandissement, donc pas de
   recadrage inutile de l'image. */
.spotlight-visual iframe {
    transform: none;
}

@media (max-width: 780px) {
    /* Sur un écran étroit, la une prend déjà toute la largeur : un 4:3 y
       mangerait la moitié de la hauteur utile. */
    .spotlight-visual {
        aspect-ratio: 16 / 9;
    }
}

/* Pagination : discrète, centrée, elle ne prend la parole qu'en fin de liste. */
.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-top: 26px;
}

.pagination .admin-meta { margin-top: 0; }

/* Une case à cocher au fil du formulaire, pas un bloc à part. */
.inline-check {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: #9ba7bb;
    font-size: 0.86rem;
    text-transform: none;
    letter-spacing: 0;
}

/* Sur la fiche, le lecteur remplit son cadre 4:3 sans agrandissement - il n'a
   plus de bandes à rattraper. Et il reste pilotable : on est venu voir la
   bande-annonce, pas la survoler. */
.game-detail-cover iframe {
    transform: none;
    pointer-events: auto;
}

/* Titre de la fiche jeu.
   Un nom de jeu passe souvent sur trois lignes au corps du hero : l'interligne
   de 1,08, correct pour un titre court, ouvre alors de grands blancs entre les
   lignes. On le resserre ici - et seulement ici, les titres éditoriaux gardant
   leur respiration. */
.game-detail-hero h1 {
    /* 0,9 collait : les jambages du « p » et du « y » descendent sous la ligne
       et venaient toucher la mention d'auteur. 0,96 resserre franchement le
       bloc de titre tout en laissant vivre les descendantes. */
    line-height: 0.96;
    letter-spacing: -0.04em;
    margin-bottom: 18px;
}

/* La règle générale remonte cette mention de 10 px pour la coller à un titre
   d'une seule ligne. Ici le titre en fait trois, et cette remontée la faisait
   buter dans les jambages. */
.game-detail-hero .game-detail-creator {
    margin-top: 0;
    margin-bottom: 22px;
}

/* La présentation, en tête de fiche : lisible sans être un pavé. */
.game-detail-pitch {
    max-width: 62ch;
    margin: 0 0 24px;
    color: #c8d0df;
    line-height: 1.7;
}

/* Une démo se distingue d'un jeu possédé, du premier coup d'œil. */
.game-meta .is-demo {
    color: #9a7cf2;
    font-weight: 700;
}

/* Bloc de soutien : présent, chaleureux, jamais criard. Un appel au don qui
   crie ressemble à de la publicité - or c'est un jeu qu'on aide à naître. */
.section-campaign { padding-top: 0; }

.campaign-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 28px;
    align-items: center;
    padding: 26px 28px;
    border: 1px solid rgba(154, 124, 242, 0.45);
    border-radius: 16px;
    background: linear-gradient(120deg, rgba(154, 124, 242, 0.1), rgba(8, 12, 20, 0.6));
}

.campaign-card h2 { margin: 6px 0 10px; font-size: clamp(1.6rem, 2.4vw, 2.2rem); }
.campaign-card .eyebrow { color: #9a7cf2; }

.campaign-dates {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 12px;
    color: #9ba7bb;
    font-size: 0.88rem;
    font-variant-numeric: tabular-nums;
}

.campaign-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

@media (max-width: 820px) {
    .campaign-card { grid-template-columns: 1fr; }
}

/* Chevron du menu dépliant : petit, aligné, sans surprise typographique. */
.nav-caret {
    display: inline-block;
    margin-left: 4px;
    font-size: 0.7em;
    line-height: 1;
    transform: translateY(-1px);
}

.creator-shortcut { margin: 0 0 22px; }

/* Aucune page ne défile latéralement : c'est au contenu large de gérer son
   propre débordement, pas au corps de la page de s'élargir. */
html, body { max-width: 100%; overflow-x: hidden; }

.rail-track { scrollbar-width: thin; }

/* Mes machines : une ligne par machine, l'essentiel à gauche, l'action à droite. */
.machine-list { margin: 0 0 30px; padding: 0; list-style: none; }

.machine-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 0;
    border-bottom: 1px solid var(--line-strong);
}

.machine-pairing { max-width: 640px; }
.pairing-code code { font-size: 1.3rem; letter-spacing: 0.14em; }

/* Parcourir : replié par défaut, ouvert dès qu'un filtre est posé - on ne
   cache pas à quelqu'un ce sur quoi il est en train de filtrer. */
.browse-panel {
    margin-bottom: 22px;
    padding: 14px 16px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: rgba(8, 12, 20, 0.45);
}

.browse-panel summary {
    cursor: pointer;
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--brand);
}

.browse-group-label {
    margin: 16px 0 8px;
    color: #7e899e;
    font-size: 0.8rem;
}

.browse-chips { display: flex; flex-wrap: wrap; gap: 8px; }

.browse-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    color: var(--text);
    font-size: 0.86rem;
    text-decoration: none;
}

.browse-chip:hover { border-color: var(--brand); }
.browse-chip.is-on { border-color: var(--brand); color: var(--brand); }

.browse-count {
    color: #7e899e;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

/* Les types de visuel : une rangée sous les rôles, qui s'enroule plutôt que de
   pousser la fiche en largeur. Le type en cours est allumé comme un rôle - même
   geste, même lecture. */
.media-kinds {
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
}

.media-kinds .admin-meta {
    margin-right: 4px;
}

/* Un titre masque reste dans la balade, en retrait : il n'est pas en ligne,
   mais il est toujours a traiter. Le faire disparaitre le ferait croire regle
   alors que personne ne le voit. */
.source-row.is-hidden-game {
    opacity: 0.5;
    filter: saturate(0.35);
}

.source-row.is-hidden-game:hover,
.source-row.is-hidden-game:focus-within {
    opacity: 1;
    filter: none;
}

/* Records du joueur : le score se lit en colonne, donc en chiffres de largeur
   fixe - sinon les milliers ne s'alignent pas d'une ligne a l'autre. */
.platform-records {
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.platform-records li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0;
    border-bottom: 1px solid var(--line);
}

.platform-record-game {
    color: var(--text-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.platform-record-score {
    color: var(--brand-bright);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.account-identity {
    display: flex;
    align-items: center;
    gap: 10px;
}

.account-avatar-large {
    border-radius: 8px;
    image-rendering: pixelated;
}

/* ── Fiche compte consolidée ──────────────────────────────────────────────── */
.account-hero {
    padding: clamp(34px, 6vw, 66px) 0 clamp(18px, 3vw, 30px);
}

.account-hero-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 20px 28px;
}

.account-hero-identity {
    display: flex;
    align-items: center;
    gap: 18px;
    min-width: 0;
}

.account-hero-avatar {
    width: 76px;
    height: 76px;
    flex: 0 0 auto;
    border-radius: 18px;
    border: 1px solid var(--line-strong);
    background: var(--surface-soft);
    image-rendering: pixelated;
}

.account-hero-avatar--placeholder {
    display: grid;
    place-items: center;
    font-size: 2rem;
    font-weight: 800;
    color: var(--brand-bright);
    position: relative;
    overflow: hidden;
}

/* Le portrait couvre l'initiale des qu'il est dessine : 64 pixels rendus en 76, au plus proche
   voisin, pour garder le pixel carre. */
.account-hero-avatar-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
}

/* Un voile CRT DEVANT la tête : des lignes de balayage, et un léger bombement de verre.
   Deux pixels de période, donc une ligne sombre sur deux, ce qui se lit sur un avatar dessiné
   en gros pixels sans en manger le dessin. Purement décoratif, donc invisible aux lecteurs
   d'écran et retiré quand la personne demande moins d'animations n'a pas lieu d'être ici : il
   ne bouge pas. */
.account-hero-avatar::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: inherit;
    background:
        repeating-linear-gradient(
            to bottom,
            rgba(0, 0, 0, 0.28) 0,
            rgba(0, 0, 0, 0.28) 1px,
            rgba(255, 255, 255, 0.05) 1px,
            rgba(255, 255, 255, 0.05) 2px
        ),
        radial-gradient(120% 120% at 50% 0%, rgba(255, 255, 255, 0.16), transparent 55%);
    mix-blend-mode: overlay;
}

/* La borne du joueur a sa planche : le contour le dit, sans un mot et sans rien a cliquer. */
.account-hero-avatar--sur-borne {
    border-color: var(--brand-bright);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand-bright) 45%, transparent);
}

.account-avatar-family {
    margin: 0 0 12px;
    color: var(--text-soft, inherit);
}

.account-avatar-sheet {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0 0 12px;
    border-radius: 12px;
    border: 1px solid var(--line-strong);
    background: var(--surface-soft);
    image-rendering: pixelated;
}

.account-avatar-status {
    margin: 0 0 12px;
    font-size: 0.92rem;
    min-height: 1.4em;
}

.account-hero-titles {
    min-width: 0;
}

.account-hero-titles .eyebrow {
    margin: 0 0 2px;
}

.account-hero-titles h1 {
    margin: 0 0 6px;
    font-size: clamp(1.9rem, 4vw, 2.7rem);
    line-height: 1.05;
}

.account-hero-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 18px;
    margin: 0;
    color: var(--text-soft);
    font-size: 0.95rem;
}

.account-hero-meta span {
    white-space: nowrap;
}

.account-hero-meta strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.account-hero-logout {
    flex: 0 0 auto;
}

.account-grid {
    /* DEUX colonnes explicites. Le masonry par `column-count` rangeait les cartes pour
       équilibrer les hauteurs : l'ordre devenait celui du navigateur, alors que c'est une
       décision. Sur mobile, une seule colonne, la gauche d'abord. */
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 clamp(18px, 2.4vw, 26px);
    align-items: start;
}

.account-col {
    min-width: 0;
}

@media (min-width: 760px) {
    .account-grid {
        grid-template-columns: 1fr 1fr;
    }
}

.account-card {
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    margin-bottom: clamp(18px, 2.4vw, 26px);
    padding: clamp(22px, 3vw, 30px);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background:
        linear-gradient(160deg, rgba(134, 93, 255, 0.04), transparent 55%),
        var(--surface);
}

.account-card > h2 {
    margin: 0 0 16px;
    font-size: 1.3rem;
}

.account-card h3 {
    margin: 22px 0 10px;
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}

.account-card--records {
    border-color: rgba(134, 93, 255, 0.3);
    background:
        linear-gradient(160deg, rgba(134, 93, 255, 0.08), transparent 58%),
        var(--surface);
}

.account-note {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.account-card .platform-records {
    margin-top: 4px;
    margin-bottom: 0;
}

.account-profile-link {
    margin-top: 16px;
}

.account-download {
    display: inline-block;
    margin-top: 8px;
    padding: 6px 14px;
    border-radius: 999px;
    background: rgba(92, 227, 161, 0.14);
    border: 1px solid rgba(92, 227, 161, 0.3);
    color: var(--success);
    font-size: 0.82rem;
    font-weight: 640;
    text-decoration: none;
}

.account-download:hover {
    background: rgba(92, 227, 161, 0.22);
}

/* ── Modal fiche joueur (rendu façon app, servi par la plateforme) ─────────── */
.np-modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(3, 5, 10, 0.74);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}

.np-modal {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 460px;
    height: min(84vh, 820px);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow);
}

.np-modal-head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 10px 12px 18px;
    border-bottom: 1px solid var(--line);
}

.np-modal-title {
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--text);
}

.np-modal-close {
    border: 0;
    background: none;
    color: var(--muted);
    font-size: 1.6rem;
    line-height: 1;
    padding: 0 10px;
    cursor: pointer;
}

.np-modal-close:hover {
    color: var(--text);
}

.np-modal-frame {
    flex: 1 1 auto;
    width: 100%;
    border: 0;
    background: var(--bg-deep);
}

/* ── Admin : table des clés & licences ───────────────────────────────────── */
.table-scroll {
    overflow-x: auto;
}

.lic-search {
    margin-bottom: 22px;
}

.lic-search input[type="search"] {
    min-width: 240px;
    padding: 9px 12px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface-raised);
    color: var(--text);
    font: inherit;
}

.lic-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.lic-table th {
    padding: 10px 12px;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid var(--line-strong);
    color: var(--muted);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.lic-table td {
    padding: 12px;
    vertical-align: top;
    border-bottom: 1px solid var(--line);
}

.lic-table code {
    color: var(--brand-bright);
    font-size: 0.8rem;
}

.lic-table .admin-meta {
    display: block;
    margin-top: 3px;
}

.lic-num {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.lic-refund-link {
    width: min(260px, 60vw);
    margin-bottom: 8px;
    padding: 6px 8px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface-soft);
    color: var(--brand-bright);
    font-size: 0.75rem;
}

.lic-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
}

.account-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.account-list > li {
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-soft);
    font-size: 0.9rem;
}

.account-list-title {
    display: block;
    font-weight: 720;
    color: var(--text);
    margin-bottom: 4px;
}

.account-list-title a {
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px solid var(--line-strong);
}

.account-list-title a:hover {
    color: var(--brand-bright);
    border-bottom-color: var(--brand);
}

.account-variant {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(134, 93, 255, 0.12);
    color: var(--brand-bright);
    font-size: 0.72rem;
    font-weight: 640;
    vertical-align: middle;
}

.account-list code {
    font-size: 0.82rem;
    color: var(--brand-bright);
    word-break: break-all;
}

.account-tag {
    display: inline-block;
    margin-top: 6px;
    font-size: 0.78rem;
    color: var(--success);
}

.account-tag--muted {
    color: var(--muted);
}

.account-list--rows > li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px 16px;
    flex-wrap: wrap;
}

.account-list--rows a {
    color: var(--brand);
    font-weight: 640;
    text-decoration: none;
}

.account-list--rows a:hover {
    text-decoration: underline;
}

.account-list-side {
    color: var(--text-soft);
    font-size: 0.82rem;
    text-align: right;
}

.account-settings {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.account-setting {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.account-setting-label {
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
}

.account-setting-value {
    font-weight: 720;
    color: var(--text);
}

.account-setting .language-row {
    align-self: flex-start;
}

/* Rangee de reglage : six choix qui passent a la ligne plutot que de deborder. */
.language-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.language-row .language-choice {
    border: 1px solid var(--line-strong);
}

/* Ce sont des boutons de formulaire depuis qu'ils ENREGISTRENT la langue :
   sans ce reset ils herteraient l'apparence native du navigateur. */
.language-row button.language-choice {
    font: inherit;
    background: transparent;
    cursor: pointer;
}

.account-inline-edit > summary {
    cursor: pointer;
    color: var(--brand);
    font-size: 0.85rem;
    width: fit-content;
}

.account-inline-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
}

.account-inline-form select {
    flex: 1 1 180px;
    padding: 9px 12px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface-raised);
    color: var(--text);
    font: inherit;
}

.account-inline-form select option {
    color: #111;
    background: #fff;
}

.account-machines {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.account-machines li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: 0.9rem;
    color: var(--text-soft);
}

.account-linklike {
    padding: 0;
    border: 0;
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: 0.82rem;
    cursor: pointer;
    text-decoration: underline;
}

.account-linklike:hover {
    color: var(--danger);
}

.account-advanced {
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.account-advanced > summary {
    cursor: pointer;
    color: var(--muted);
    font-size: 0.82rem;
    width: fit-content;
}

.account-advanced[open] > summary {
    margin-bottom: 12px;
}

.account-advanced-code {
    margin: 0 0 8px;
}

.account-advanced-code code {
    font-size: 1rem;
    color: var(--brand-bright);
    letter-spacing: 0.04em;
}

.account-advanced-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 12px;
}

/* ── Vue d'ensemble de la flotte ──────────────────────────────────────────── */
.insight-figures {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
    margin-bottom: 28px;
}

.insight-figure {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px 16px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: rgba(8, 12, 20, 0.6);
}

.insight-value {
    font-size: 1.7rem;
    font-weight: 800;
    color: var(--brand-bright);
    font-variant-numeric: tabular-nums;
}

.insight-label {
    font-size: 0.76rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
}

.insight-map {
    margin: 12px 0 28px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    overflow: hidden;
}

.insight-map svg { display: block; width: 100%; height: auto; }
.map-ground { fill: rgba(8, 12, 20, 0.75); }
.map-grid { stroke: rgba(151, 174, 211, 0.12); stroke-width: 1; }
.map-equator { stroke: rgba(151, 174, 211, 0.24); stroke-width: 1; }
.map-land path { fill: rgba(151, 174, 211, 0.13); stroke: rgba(151, 174, 211, 0.34); stroke-width: 0.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.map-dot { vector-effect: non-scaling-stroke; }
.insight-map-caption { margin-top: 12px; }
.map-count {
  fill: #fff; font-weight: 700; text-anchor: middle; dominant-baseline: central;
  font-variant-numeric: tabular-nums; paint-order: stroke;
  stroke: rgba(8, 12, 20, 0.9); stroke-width: 3px; stroke-linejoin: round;
}
.count-swatch {
  display: inline-block; min-width: 1.6em; margin-right: 0.35em; padding: 0 0.2em;
  font-weight: 700; color: #fff; text-align: center; font-variant-numeric: tabular-nums;
}
.map-dot { fill: rgba(134, 93, 255, 0.45); stroke: var(--brand-bright); stroke-width: 1.5; }
/* Deux calques : bornes appairees (cyan) et installs anonymes (ambre). */
.map-dot-paired { fill: rgba(134, 93, 255, 0.5); stroke: var(--brand-bright); stroke-width: 1.5; }
.map-dot-anon { fill: rgba(245, 182, 76, 0.32); stroke: #f5b64c; stroke-width: 1.3; }

/* Titre de groupe de cartes (Parc / Activite de jeu). */
.insight-group-title {
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-soft);
    margin: 6px 0 12px;
}

/* La carte « total installs » se detache : c'est le chiffre-titre. */
.insight-figure-hero {
    background: linear-gradient(135deg, rgba(134, 93, 255, 0.14), rgba(8, 12, 20, 0.6));
    border-color: var(--brand);
}
.insight-figure-hero .insight-value { font-size: 2.1rem; }

/* Pastilles de legende + dans les cartes appaire/anonyme. */
.dot-swatch {
    display: inline-block;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    margin-right: 7px;
    vertical-align: baseline;
}
.swatch-paired { background: var(--brand-bright); }
.swatch-anon { background: #f5b64c; }

.insight-legend { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; }
.insight-legend .legend-item { display: inline-flex; align-items: center; }
.insight-legend .legend-hidden { color: var(--muted); font-style: italic; }

/* Un tableau large defile DANS son cadre : la page, elle, ne part jamais de
   travers. */
.table-scroll { overflow-x: auto; margin-bottom: 28px; }

.insight-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.insight-table th,
.insight-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

.insight-table th {
    color: var(--muted);
    font-size: 0.74rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Les chiffres se comparent en colonne : largeur fixe, alignes a droite. */
.insight-table td.numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.projection-bars {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.projection-bars li {
    display: grid;
    grid-template-columns: 72px 1fr 80px;
    align-items: center;
    gap: 12px;
}

.projection-month { color: var(--muted); font-size: 0.8rem; }

.projection-track {
    height: 10px;
    border-radius: 5px;
    background: rgba(151, 174, 211, 0.12);
    overflow: hidden;
}

.projection-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 5px;
    background: linear-gradient(90deg, var(--brand-deep), var(--brand-bright));
}

.projection-value {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-soft);
}

/* Revendications de droits. */
.claim-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 16px;
    padding: 16px 18px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: rgba(8, 12, 20, 0.6);
}

/* Une revendication deja tranchee reste lisible mais passe au second plan :
   ce qui attend une decision doit sauter aux yeux. */
.claim-card.is-decided { opacity: 0.62; }
.claim-card.is-decided:hover { opacity: 1; }

.claim-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.claim-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px;
    margin: 0;
}

.claim-facts dt {
    color: var(--muted);
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.claim-facts dd { margin: 2px 0 0; }

.claim-evidence {
    margin: 0;
    padding: 10px 12px;
    border-left: 2px solid var(--line-strong);
    color: var(--text-soft);
    font-size: 0.9rem;
}

/* Nom de la machine qui demande a etre autorisee. Il se lit avant le bouton :
   autoriser sans savoir laquelle serait autoriser a l'aveugle. */
.device-link-name {
    margin: 0 0 18px;
    padding: 14px 16px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: rgba(8, 12, 20, 0.6);
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    text-align: center;
}

/* Marche a suivre pour ajouter une machine. Les numeros disent l'ORDRE, qui
   est reel : on ne connecte pas une machine sans APIExpose, ni n'installe un
   jeu sur une machine inconnue du compte. */
.setup-steps {
    list-style: none;
    margin: 0 0 28px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.setup-steps li {
    display: grid;
    grid-template-columns: 44px 1fr;
    gap: 16px;
    align-items: start;
}

.setup-steps h2 { margin: 0 0 6px; font-size: 1.12rem; }
.setup-steps p { margin: 0 0 6px; }

.setup-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid var(--line-strong);
    background: rgba(134, 93, 255, 0.1);
    color: var(--brand-bright);
    font-weight: 800;
}

.setup-address {
    margin: 0 0 18px;
    padding: 16px 18px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: rgba(8, 12, 20, 0.6);
}

.setup-address p { margin: 0 0 8px; color: var(--muted); font-size: 0.9rem; }

/* L'adresse doit pouvoir se recopier a la main : c'est le seul texte de la
   page que quelqu'un tapera peut-etre sur un autre clavier. */
.setup-address code {
    display: block;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
    word-break: break-all;
}

/* Passeport : les ensembles a cocher. Un jeu s'installe souvent de plusieurs
   facons - forcer un choix unique obligerait a mentir des qu'il y en a deux. */
.passport-set {
    margin: 0;
    padding: 12px 14px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
}

.passport-set legend {
    padding: 0 6px;
    color: var(--muted);
    font-size: 0.74rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.passport-check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 4px 14px 4px 0;
}

/* Jauge du createur : le chemin qui RESTE, pas seulement l'etat atteint.
   « 1 machine sur 3 » se comprend d'un coup d'oeil ; « provisoire » ne dit pas
   ce qu'il faudrait pour ne plus l'etre. */
.gauge { margin: 0 0 28px; }

.gauge-track {
    height: 12px;
    border-radius: 6px;
    background: rgba(151, 174, 211, 0.14);
    overflow: hidden;
    margin-bottom: 8px;
}

.gauge-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 6px;
    background: linear-gradient(90deg, var(--brand-deep), var(--brand-bright));
}

/* Le niveau de confiance se lit AVANT le contenu du passeport : il dit ce que
   tout le reste vaut. Trois couleurs, du plus prudent au plus assure. */
.passport-confidence {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.passport-confidence-declared { background: rgba(151, 174, 211, 0.18); color: var(--text-soft); }
.passport-confidence-provisional { background: rgba(255, 201, 107, 0.18); color: var(--warning); }
.passport-confidence-confirmed { background: rgba(92, 227, 161, 0.18); color: var(--success); }

/* La mention « declare par le createur » precede les champs qu'elle couvre :
   la lire apres les avoir lus serait la lire trop tard. */
.passport-declared-note {
    margin: 0 0 10px;
    color: var(--muted);
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* La parole du createur a son propre cadre : la ranger dans le passeport
   laissait croire qu'elle avait ete verifiee comme le reste. */
.declared-card {
    margin: 0 0 28px;
    padding: 20px 22px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface-soft);
}

.declared-card dl {
    display: grid;
    gap: 14px;
    margin: 0;
}

.declared-card dt {
    margin-bottom: 4px;
    color: var(--muted);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.declared-card dd { margin: 0; }

/* Bloc « Cette edition ». La nature passe en tete parce qu'elle decide de la
   lecture du reste : une restauration ne se lit pas comme un original. */
.edition-kind {
    margin: 0 0 6px;
    font-size: 1.12rem;
    font-weight: 700;
    color: var(--text);
}

/* La contrepartie de la regle qui oblige a expliquer : ce qu'elle fait ecrire
   doit se voir, sinon la regle ne sert a rien. */
.edition-modification {
    margin: 0 0 16px;
    padding-left: 12px;
    border-left: 2px solid var(--brand-bright);
    color: var(--text-soft);
    font-size: 0.94rem;
}

.edition-credits {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

/* L'empreinte a SON cadre. Le bloc au-dessus est declare puis examine ; ceci
   est mesure sur le contenu. Les poser ensemble donnerait a une declaration
   l'autorite d'une mesure. */
.edition-fingerprint {
    padding: 18px 22px;
    border: 1px dashed var(--line);
    border-radius: 14px;
}

.edition-fingerprint dl {
    display: grid;
    gap: 10px;
    margin: 0;
}

.edition-fingerprint dt {
    margin-bottom: 3px;
    color: var(--muted);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
}

.edition-fingerprint dd { margin: 0; }

/* Un condense se lit caractere par caractere quand on le compare, et il doit
   pouvoir se selectionner d'un geste sur telephone. */
.edition-fingerprint code {
    display: block;
    overflow-wrap: anywhere;
    user-select: all;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-soft);
}

/* ── Accueil refondu (CDC UI/UX v1.0) ─────────────────────────────────────── */

/* Les trois publics des le premier ecran : les deux entrees complementaires
   restent des liens discrets, sous les deux boutons hierarchises. */
.hero-audiences {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    margin: 18px 0 0;
}

/* La carte de performance du hero. Elle montre une performance REELLE quand il
   y en a une ; sinon elle montre ce qu'elle contiendra, sous sa mention. */
.perf-card {
    position: relative;
    padding: 22px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
}

.perf-card-sample { border-style: dashed; }

.perf-top {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 18px;
}

.perf-top span { display: block; color: var(--muted); font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; }
.perf-top strong { display: block; font-size: 1.05rem; }

.perf-lines { display: grid; gap: 12px; margin: 0 0 16px; }
.perf-lines dt { color: var(--muted); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; }
.perf-lines dd { margin: 2px 0 0; font-size: .98rem; }
.perf-score { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 1.2rem; }
.perf-foot { margin: 0; color: var(--text-soft); font-size: .86rem; }

/* Un statut se lit sans la couleur : la pastille porte son mot. */
.badge-sample,
.badge-soon {
    display: inline-block;
    padding: 3px 10px;
    border: 1px solid var(--line);
    border-radius: 999px;
    color: var(--muted);
    font-size: .72rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    white-space: nowrap;
}

.badge-sample { margin-left: auto; }
.badge-soon { align-self: center; }

/* Un bloc vide sans cadre se lit comme une panne. Ici, c'est l'etat correct
   de la plateforme, et il doit le dire lui-meme. */
.empty-card {
    padding: 26px;
    border: 1px dashed var(--line);
    border-radius: 18px;
    background: var(--surface-soft);
    text-align: center;
}

.empty-card h3 { margin: 0 0 8px; font-size: 1.1rem; }
.empty-card p { max-width: 62ch; margin: 0 auto 18px; color: var(--text-soft); }

.play-grid,
.replay-grid {
    display: grid;
    gap: 16px;
    /* auto-FIT, pas auto-fill : avec deux cartes dans une grille prevue pour
       cinq, auto-fill garde trois pistes vides a droite. */
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.play-card,
.replay-card {
    padding: 20px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
}

.play-card h3,
.replay-card h3 { margin: 0 0 6px; font-size: 1.04rem; }
.play-rule { margin: 0 0 4px; color: var(--muted); font-size: .84rem; }
.play-count { margin: 0 0 14px; color: var(--text-soft); font-size: .88rem; font-variant-numeric: tabular-nums; }
.play-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 0; }

.replay-card dl { display: grid; gap: 8px; margin: 0 0 14px; }
.replay-card dt { color: var(--muted); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; }
.replay-card dd { margin: 2px 0 0; }

.section-more { margin-top: 22px; }
.section-note { max-width: 68ch; margin-top: 20px; color: var(--muted); font-size: .88rem; }

/* Streamers et createurs : le texte porte, la fiche d'exemple accompagne. */
.audience-layout {
    display: grid;
    gap: 28px;
    align-items: start;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 900px) {
    .section-creators .audience-layout {
        grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
        /* Sans centrage, l'ecart de hauteur entre les deux colonnes tombe en
           entier sous la fiche et se lit comme un trou. */
        align-items: center;
    }
}

.audience-points { margin: 18px 0 22px; padding-left: 18px; display: grid; gap: 10px; }
.audience-points li { color: var(--text-soft); }
.audience-points strong { color: var(--text); }
.audience-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin: 22px 0 0; }

.sample-card {
    padding: 22px;
    border: 1px dashed var(--line);
    border-radius: 18px;
    background: var(--surface-soft);
}

.sample-top { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.sample-top > span:first-child { color: var(--muted); font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; }
.sample-card dl { display: grid; gap: 12px; margin: 0 0 16px; }
.sample-card dt { color: var(--muted); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; }
.sample-card dd { margin: 2px 0 0; }
.sample-card > p { margin: 0; color: var(--muted); font-size: .84rem; }

/* Une colonne sur telephone, hero compris. */
@media (max-width: 720px) {
    .hero-audiences { flex-direction: column; gap: 10px; }
    .play-grid,
    .replay-grid { grid-template-columns: minmax(0, 1fr); }
    .audience-actions { flex-direction: column; align-items: stretch; }
    .audience-actions .button { width: 100%; text-align: center; }
    .badge-soon { align-self: flex-start; }
}

/* L'action se pose la ou le regard finit de lire la rangee. */
.section-start .audience-actions {
    justify-content: center;
    margin-top: 34px;
}

@media (max-width: 720px) {
    .section-start .audience-actions { justify-content: stretch; }
}

/* ── Accueil : rythme serre et captures ───────────────────────────────────── */

/* Le site respire a dessein ; l'accueil, lui, doit tenir. On compresse ICI,
   sans toucher aux pages que personne n'a critiquees. */
.page-home .hero,
.page-streamers .page-hero {
    min-height: 0;
    padding: clamp(48px, 5vw, 76px) 0 clamp(44px, 4.5vw, 64px);
}

.page-home .hero-grid {
    gap: clamp(32px, 4vw, 56px);
}

.page-home .section,
.page-streamers .section {
    padding: clamp(52px, 5vw, 78px) 0;
}

.page-home .section-heading,
.page-streamers .section-heading {
    margin-bottom: 30px;
}

.page-home .section-heading h2,
.page-streamers .section-heading h2 {
    margin-bottom: 12px;
}

.page-home h1 {
    margin-bottom: 14px;
}

.page-home .hero-lead {
    margin-bottom: 22px;
}

.page-home .hero-actions {
    margin-bottom: 14px;
}

.page-home .journey-list li,
.page-streamers .journey-list li {
    min-height: 0;
    padding-bottom: 4px;
}

.page-home .journey-list li > span,
.page-streamers .journey-list li > span {
    margin-bottom: 20px;
}

.page-home .mission-banner {
    padding: clamp(40px, 4vw, 60px) 0;
}

/* Les captures : un cadre qui les pose comme des preuves, pas comme du decor.
   width/height sont dans le HTML pour que rien ne bouge quand elles arrivent. */
.shot {
    margin: 26px 0 0;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
    overflow: hidden;
}

.shot img {
    display: block;
    width: 100%;
    height: auto;
}

.shot figcaption {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 0.84rem;
    text-align: left;
}

/* Une capture verticale prise en pleine largeur ecraserait le bloc : on la
   borne, et on la centre. */
.shot-tall {
    max-width: 340px;
    margin-inline: auto;
}

.shot-wide {
    max-width: 640px;
    margin-inline: auto;
}

.empty-actions {
    margin: 0;
}

/* Le bloc streamers passe en deux colonnes quand la place le permet : le
   texte porte, la capture montre. */
@media (min-width: 900px) {
    .section-streamers .audience-layout {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        align-items: center;
    }

    .section-streamers .shot {
        margin-top: 0;
    }
}

/* ── Accueil : rattraper les vides ────────────────────────────────────────── */

/* 7vw etait taille pour un titre court. Celui-ci fait quatre lignes et 435 px,
   soit la moitie du hero avant meme d'avoir dit quoi que ce soit. */
.page-home h1 {
    font-size: clamp(2.3rem, 4.4vw, 3.9rem);
    margin: 18px 0 18px;
}

/* La colonne imposait 540 px de haut et centrait une carte de 315 : le vide
   etait fabrique ici. La carte occupe desormais sa colonne. */
.page-home .hero-visual {
    min-height: 0;
    place-items: stretch;
}

/* Deux colonnes SEULEMENT au-dessus du palier ou la page repasse en une
   seule. Posee globalement, cette regle ecrasait la colonne de texte a 0 px
   sur telephone. */
@media (min-width: 1001px) {
    /* Les deux blocs alignes en HAUT (demande user 2026-10-03) : centre, le texte flottait au
       milieu de la carte du jeu de la semaine, plus haute que lui. */
    .page-home .hero-grid {
        grid-template-columns: minmax(0, 1.15fr) minmax(340px, 0.85fr);
        align-items: start;
    }
}

.page-home .perf-card {
    width: 100%;
}

/* Cartes a gauche, capture a droite : empiler la figure sous la grille
   ouvrait un vide de chaque cote de l'image. */
.section-split {
    display: grid;
    gap: 24px;
    align-items: start;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 980px) {
    .section-split {
        grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
        align-items: stretch;
    }

    .section-split .shot {
        margin-top: 0;
        max-width: none;
        display: flex;
        flex-direction: column;
    }

    .section-split .shot img {
        flex: 1;
        min-height: 0;
        object-fit: cover;
        object-position: top center;
    }
}

/* La capture verticale ferait un couloir de 880 px en pleine largeur. On garde
   le haut, ou vit l'information. */
.shot-tall img {
    max-height: 460px;
    object-fit: cover;
    object-position: top center;
}

/* Le bloc streamers : la capture remplit sa colonne au lieu de flotter. */
@media (min-width: 900px) {
    .section-streamers .shot img {
        height: 100%;
        object-fit: cover;
    }
}

/* ── Page streamers : les quatre etapes et les deux colonnes ─────────────── */

/* Quatre etapes dans une grille de trois laissaient la derniere seule sur une
   rangee. */
.page-streamers .journey-list {
    grid-template-columns: repeat(4, 1fr);
}

/* Quatre cartes ici, deux la : auto-fit replie les pistes inutilisees et sert
   les deux cas sans qu'on compte a la main. */
.page-streamers .pl-cards {
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

@media (max-width: 1100px) {
    .page-streamers .journey-list { grid-template-columns: repeat(2, 1fr); }
}

/* Le texte porte, la capture montre : la regle a deux colonnes existait, mais
   scopee aux sections de l'accueil. */
@media (min-width: 900px) {
    .section-fair .audience-layout {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        align-items: center;
    }

    .section-fair .shot { margin-top: 0; }
}

/* ── Captures de records ─────────────────────────────────────────────────── */

/* Ces images sont a la DEFINITION D'ORIGINE du jeu. Les laisser lisser
   detruirait le travail fait pour les obtenir ainsi. */
.record-shot img {
    display: block;
    image-rendering: pixelated;
}

/* Dans le hero, la capture porte : on la donne large, sans depasser le double
   de sa definition, ou le grossissement redeviendrait visible. */
.record-shot {
    margin: -22px -22px 16px;
    border-bottom: 1px solid var(--line);
    background: #05050c;
    overflow: hidden;
}

.record-shot img {
    width: 100%;
    height: auto;
}

/* Une capture verticale prise en pleine largeur ferait un couloir : on la
   borne en hauteur et on garde le haut de l'ecran de jeu. */
/* Le hero : un bandeau qui prend la largeur de la carte. Une capture
   verticale y est recadree plutot que noyee dans du noir. */
.record-shot-tall {
    height: 190px;
}

.record-shot-tall img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/* Le cadre des records est un tube comme les autres : la forme et le voile
   viennent de `crt-tube`, il ne reste ici que ce qui lui appartient. La
   hauteur fixe et le `cover` d'avant recadraient l'image, donc parfois le
   score - ce que la capture est censee prouver. */

.record-origin {
    margin: 0 0 10px;
    color: var(--muted);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ── Video du premier ecran ──────────────────────────────────────────────── */

/* La place du lecteur est prise d'avance : son arrivee ne pousse rien, donc
   ne fait rater aucun clic. */
.hero-video {
    position: relative;
    aspect-ratio: 16 / 9;
    min-height: 200px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: #05050c;
    overflow: hidden;
}

.hero-video iframe,
.video-facade {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Une video de fond : le lecteur deborde du cadre, qui rogne le bandeau de titre en haut et
   le logo en bas a droite (YouTube les pose au depart, meme sans commandes), et il ne recoit
   pas la souris, qui les ferait revenir. Le son se commande par le bouton a cote. */
.hero-video iframe {
    transform: scale(1.28);
    transform-origin: center;
    pointer-events: none;
}

/* Le premier ecran fige sur son affiche pendant qu'une autre lecture a la place. */
.hero-video .hero-poster {
    position: absolute;
    inset: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity .25s ease;
    pointer-events: none;
}

.hero-video.is-paused .hero-poster,
.hero-video.is-veiled .hero-poster {
    opacity: 1;
}

.video-facade {
    display: block;
    padding: 0;
    background: none;
    cursor: pointer;
}

.video-facade img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Le bouton de lecture se voit sur une image claire comme sur une sombre. */
.video-play {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 68px;
    height: 68px;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(10, 8, 24, .72);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .28);
}

.video-play::after {
    position: absolute;
    top: 50%;
    left: 54%;
    width: 0;
    height: 0;
    content: "";
    transform: translate(-50%, -50%);
    border-top: 12px solid transparent;
    border-bottom: 12px solid transparent;
    border-left: 20px solid #fff;
}

.video-facade:hover .video-play,
.video-facade:focus-visible .video-play {
    background: rgba(134, 93, 255, .92);
}

/* La duree reelle, annoncee avant le clic. */
.video-meta {
    position: absolute;
    right: 12px;
    bottom: 12px;
    padding: 5px 11px;
    border-radius: 999px;
    background: rgba(5, 5, 12, .78);
    color: #fff;
    font-size: .78rem;
}

.video-meta b {
    font-variant-numeric: tabular-nums;
}

.video-note {
    margin: 12px 0 0;
    color: var(--muted);
    font-size: .82rem;
}

@media (max-width: 720px) {
    .hero-video { min-height: 0; }
}

/* ── Accueil : records, volumes et emplacements ──────────────────────────── */

.record-grid {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

.record-card {
    display: flex;
    flex-direction: column;
    padding: 20px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
}

.record-card h3 { margin: 0 0 4px; font-size: 1.04rem; }

/* La regle en clair, avec son code d'origine a cote pour qui le connait. */
.record-rule {
    margin: 0 0 14px;
    color: var(--text-soft);
    font-size: .86rem;
}

.record-code {
    margin-left: 6px;
    padding: 2px 7px;
    border: 1px solid var(--line);
    border-radius: 999px;
    color: var(--muted);
    font-size: .68rem;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.record-lines { display: grid; gap: 9px; margin: 0 0 12px; }
.record-lines dt { color: var(--muted); font-size: .7rem; letter-spacing: .06em; text-transform: uppercase; }
.record-lines dd { margin: 2px 0 0; }

.record-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin: auto 0 0;
    padding-top: 14px;
}

/* Chaque nombre dit ce qu'il compte : le libelle passe donc AVANT, en petit,
   et la valeur en grand dessous. */
.community-stats {
    display: grid;
    gap: 14px;
    margin: 0 0 28px;
    padding: 20px 22px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface-soft);
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}

.community-stats dt {
    color: var(--muted);
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.community-stats dd {
    margin: 4px 0 0;
    font-size: 1.5rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* L'emplacement d'un jeu a venir. En pointilles et vide : un cadre qui attend
   se lit comme une attente, une image inventee se lirait comme une promesse. */
.free-card { border-style: dashed; }

.free-slot {
    display: grid;
    place-items: center;
    height: 96px;
    margin: -20px -20px 14px;
    border-bottom: 1px dashed var(--line);
    background: #05050c;
}

.free-slot span {
    width: 30px;
    height: 30px;
    border: 2px solid var(--line);
    border-radius: 8px;
}

.free-badge {
    margin: 0 0 8px;
    color: var(--muted);
    font-size: .7rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.free-facts {
    margin: 12px 0 0;
    padding-left: 18px;
    color: var(--text-soft);
    font-size: .86rem;
}

.free-facts li + li { margin-top: 5px; }
.free-facts li::marker { color: var(--brand-bright); }


/* ── Le tube cathodique ───────────────────────────────────────────────────
   Partout ou le site montre un ecran de jeu : les jeux du moment, les records
   de l'accueil, la fiche d'un jeu. Meme langage que la video du premier ecran,
   pour que la page soit d'un seul tenant.

   L'IMAGE PASSE SOUS LE VOILE, et il faut le dire : elle porte un `transform`,
   donc un contexte d'empilement, et sans ordre explicite elle repassait
   au-dessus des lignes - le tube etait la sans qu'on le voie.

   Aucune couche ne prend les clics : les commandes et les liens restent
   accessibles dessous. */
.crt-tube {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: #05070c;
    box-shadow: inset 0 0 38px rgba(0, 0, 0, .7), inset 0 0 0 1px rgba(255, 255, 255, .04);
}

.crt-tube img {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    /* `contain` et non `cover` : sur la fiche d'un record, un recadrage
       couperait le score, qui est ce que l'image atteste. */
    object-fit: contain;
    image-rendering: pixelated;
    /* Le verre bombe : coins en ellipse, et l'image gonfle d'un rien pour que
       ses bords touchent le cadre. */
    border-radius: 7% / 9%;
    transform: scale(1.015);
    filter: contrast(1.08) saturate(1.12) brightness(1.02);
}

/* Le balayage : une ligne sombre sur trois, les valeurs de la video. */
.crt-tube::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: repeating-linear-gradient(
        to bottom,
        rgba(0, 0, 0, .3) 0,
        rgba(0, 0, 0, .3) 1px,
        transparent 1px,
        transparent 3px
    );
}

/* Le reflet d'une lampe sur le verre, le halo des zones claires, et les bords
   qui s'assombrissent vers les coins. */
.crt-tube::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background:
        linear-gradient(118deg, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, .03) 26%, transparent 44%),
        radial-gradient(120% 80% at 50% 45%, rgba(150, 200, 255, .07), transparent 60%),
        radial-gradient(135% 105% at 50% 50%, transparent 62%, rgba(0, 0, 0, .34) 100%);
}

/* La bande de balayage qui descend : un element a elle, les deux
   pseudo-elements etant pris. Sept secondes, comme la video. */
.crt-scan {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: 22%;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, .05), transparent);
    animation: hero-crt-scan 7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .crt-scan { animation: none; opacity: 0; }
}

/* Les jeux du moment et les records de l'accueil : le tube deborde du padding
   de la carte, pour toucher ses bords. */
.featured-shot,
.record-shot-frame {
    margin: -20px -20px 14px;
    border-bottom: 1px solid var(--line);
}

/* Un emplacement sans titre n'a pas de tube - il n'a rien a montrer - mais
   garde la forme des autres pour que la rangee reste alignee. */
.featured-shot-empty {
    display: grid;
    place-items: center;
    aspect-ratio: 4 / 3;
    background: #05070c;
    box-shadow: none;
}

.featured-shot-empty::before,
.featured-shot-empty::after { content: none; }

.featured-shot-empty span {
    width: 30px;
    height: 30px;
    border: 2px solid var(--line);
    border-radius: 8px;
}

.featured-card h3 { overflow-wrap: anywhere; }

.featured-synopsis {
    margin: 10px 0 0;
    color: var(--text-soft);
    font-size: .88rem;
    line-height: 1.5;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    overflow: hidden;
}

.featured-machine {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: .72rem;
}

.featured-card .play-count { margin-top: 12px; }

/* Le bouton respire. La ligne de comptage qui l'ecartait du resume a ete
   retiree, et il se retrouvait colle au texte. */
.featured-card .play-actions { margin-top: 16px; }
.featured-credit { margin-top: 6px; font-size: .8rem; }

.hero-hint {
    margin: 14px 0 0;
    color: var(--muted);
    font-size: .88rem;
}

/* Les deux publics secondaires, cote a cote et moins appuyes que le parcours
   joueur, comme le cadrage le demande. */
.section-audiences .pl-cards { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.section-audiences .pl-card .eyebrow { margin-bottom: 8px; }

.mission-banner .audience-actions { margin-top: 18px; }

/* ── Premier ecran cinema : la video en grand, le texte dessous ──────────── */

.page-home .hero-cinema {
    padding-top: 0;
    padding-bottom: clamp(40px, 4vw, 60px);
}

.hero-stage {
    position: relative;
    margin-bottom: clamp(26px, 3vw, 40px);
}

/* Le 16/9 pleine largeur ferait 810 px de haut sur un grand ecran, et le titre
   passerait sous la ligne de flottaison. On borne la hauteur et l'image se
   recadre : le mouvement reste, la promesse reste lisible. */
.hero-cinema .hero-video {
    width: 100%;
    /* Hauteur FIXEE, pas un rapport : `aspect-ratio` avec `max-height`
       retrecit la boite au lieu de la recadrer, et la video n'occupait que
       928 px sur un ecran de 1440. */
    aspect-ratio: auto;
    height: clamp(300px, 46vh, 520px);
    min-height: 0;
    border: 0;
    border-radius: 0;
}

.hero-cinema .hero-video img {
    object-fit: cover;
}

/* Le lecteur garde son 16/9 quoi qu'on lui dise : `object-fit` ne touche pas
   ce que YouTube dessine dedans. On lui donne donc la plus grande des deux
   dimensions 16/9 et on le recentre, le cadre masquant le debordement. */
.hero-cinema .hero-video iframe {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100vw;
    height: 56.25vw;
    min-width: 177.78vh;
    min-height: 100%;
    /* Un rien plus grand que le cadre : quand celui-ci est presque en 16/9, le bandeau de
       titre que YouTube pose au depart tomberait sinon dans l'image. */
    transform: translate(-50%, -50%) scale(1.15);
}

/* Un fondu vers le fond de page : la video se termine sans couture au lieu de
   s'arreter net sur une arete. */
.hero-stage::after {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 120px;
    content: "";
    pointer-events: none;
    background: linear-gradient(to bottom, transparent, var(--bg));
}

/* Le bouton de son : il n'apparait que lorsque la lecture automatique a eu
   lieu, donc uniquement quand il sert a quelque chose. */
.video-sound {
    position: absolute;
    right: clamp(14px, 3vw, 34px);
    bottom: clamp(18px, 3vw, 34px);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: 999px;
    background: rgba(5, 5, 12, .78);
    color: #fff;
    font-size: .82rem;
    font-weight: 600;
    cursor: pointer;
}

.video-sound:hover,
.video-sound:focus-visible {
    border-color: var(--brand-bright);
    background: rgba(134, 93, 255, .92);
}

.video-sound-on {
    width: 0;
    height: 0;
    border-top: 7px solid transparent;
    border-bottom: 7px solid transparent;
    border-left: 11px solid currentColor;
}

.hero-copy-wide {
    max-width: 780px;
}

.page-home .hero-cinema h1 {
    margin-top: 16px;
}

@media (max-width: 720px) {
    .hero-cinema .hero-video { height: clamp(220px, 34vh, 320px); }
    .hero-stage::after { height: 70px; }
}

/* ── Voile cathodique sur le bandeau ─────────────────────────────────────── */

/* Le contraste et la saturation d'un tube : un peu plus dur, un peu plus
   sature qu'une dalle plate. Applique au lecteur lui-meme. */
.hero-cinema .hero-video iframe,
.hero-cinema .hero-video img {
    filter: contrast(1.12) saturate(1.18) brightness(1.02);
}

/* Les lignes de balayage. Le pas de 3 px tient sur un ecran ordinaire comme
   sur un ecran a forte densite ; plus fin, elles disparaissent au rendu. */
.hero-crt,
.hero-crt-glow {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}

/* Pas de mix-blend-mode : une iframe forme son propre contexte de
   composition, et la couche se melangeait au fond du parent, pas a la video.
   Le bandeau devenait entierement noir. */
.hero-crt {
    background:
        repeating-linear-gradient(
            to bottom,
            rgba(0, 0, 0, .3) 0,
            rgba(0, 0, 0, .3) 1px,
            transparent 1px,
            transparent 3px
        );
}

/* Le halo des zones claires et l'assombrissement des bords, dans la meme
   couche : un tube n'a pas de coins parfaitement eclaires. */
.hero-crt-glow {
    background:
        radial-gradient(120% 80% at 50% 45%, rgba(150, 200, 255, .07), transparent 60%),
        radial-gradient(135% 105% at 50% 50%, transparent 62%, rgba(0, 0, 0, .34) 100%);
}

/* Un balayage lent, volontairement a peine visible. Il donne le vivant du
   tube sans attirer l'oeil sur lui-meme. */
@keyframes hero-crt-scan {
    0% { transform: translateY(-100%); }
    100% { transform: translateY(100%); }
}

.hero-crt::after {
    position: absolute;
    right: 0;
    left: 0;
    height: 22%;
    content: "";
    background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, .05), transparent);
    animation: hero-crt-scan 7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .hero-crt::after { animation: none; opacity: 0; }
}

/* Page /claim - réclamer un record depuis son téléphone. */
.claim-record { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; margin-bottom: 22px; padding-bottom: 22px; border-bottom: 1px solid rgba(255, 255, 255, .08); }
.claim-record .claim-game { font-size: 1.4rem; font-weight: 800; color: var(--text); }
.claim-record .claim-rules { font-size: .8rem; color: var(--muted); text-transform: uppercase; letter-spacing: .12em; }
.claim-record .claim-score { font-size: 2.6rem; font-weight: 800; font-variant-numeric: tabular-nums; color: #ffd24a; margin-top: 8px; }
.claim-record .claim-score small { font-size: .85rem; color: var(--muted); font-weight: 600; letter-spacing: .04em; }
.claim-as { color: var(--muted); margin-bottom: 14px; }
.claim-done-title { font-size: 1.2rem; }
.claim-done-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
#claim-actions .legal-note { margin: 6px 0 16px; }

/* Records certifiés dans l'espace compte + machines liées (claim Lot 3.B/D) */
.certified-records { list-style: none; margin: 12px 0 16px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.certified-record { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 14px; border: 1px solid var(--line, rgba(140,165,220,.18)); border-radius: 12px; background: rgba(12,20,44,.35); }
.certified-record-id { min-width: 0; }
.certified-record-id strong { display: block; }
.certified-record-figures { display: flex; align-items: baseline; gap: 14px; flex: none; }
.certified-record-score { font-weight: 800; color: #ffd24a; font-variant-numeric: tabular-nums; }
.certified-record-score small { color: var(--muted); font-weight: 600; font-size: .8em; }
.certified-record-rank { color: var(--muted); font-variant-numeric: tabular-nums; font-weight: 700; }
/* Les parties non certifiees du compte : le meme gabarit, en retrait, et un titre de sous-bloc. */
.account-subtitle { margin: 18px 0 4px; font-size: 1rem; }
.certified-record.is-uncertified { opacity: .8; border-style: dashed; }
.certified-record.is-uncertified .certified-record-rank { font-weight: 500; }
/* Un motif long (« réglages du jeu (NVRAM) non conformes ») ne doit pas écraser le nom du jeu
   en une colonne d'un mot : la carte se plie, le motif passe à la ligne et s'aligne à droite. */
.certified-record.is-uncertified .certified-record-link { flex-wrap: wrap; }
.certified-record.is-uncertified .certified-record-id { flex: 1 1 14rem; }
.certified-record.is-uncertified .certified-record-figures { flex: 0 1 auto; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; min-width: 0; row-gap: 2px; }
.certified-record.is-uncertified .certified-record-rank { white-space: normal; text-align: right; }
/* Plus petit et dans une boîte qui défile : une borne de test en laisse des dizaines, et la
   carte du compte n'a pas à s'allonger d'autant. Quatre cartes visibles, le reste au défilement. */
.certified-records--uncertified { max-height: 17rem; overflow-y: auto; font-size: .86em; gap: 6px; padding-right: 6px; scrollbar-width: thin; }
.certified-records--uncertified .certified-record-link { padding: 8px 12px; gap: 10px; }
.certified-records--uncertified .certified-record-figures { gap: 10px; }
.machine-linked { margin-top: 28px; }
.machine-linked .machine-row strong { font-weight: 700; }

/* Record certifié cliquable vers son board + badge de monde (Phase 1/2a) */
.certified-record { padding: 0; }
/* Carte cliquable, PAS un lien bleu : couleur d'encre au repos, accent OR au survol. */
.certified-record-link { display: flex; flex: 1; width: 100%; box-sizing: border-box; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 14px; text-decoration: none; color: var(--text); border-radius: 12px; }
.certified-record-link .certified-record-id strong { color: var(--text); }
a.certified-record-link:hover { background: rgba(255, 210, 74, 0.06); }
a.certified-record-link:hover .certified-record-id strong { color: #ffd24a; }

/* Curseur « main » sur TOUS les interactifs - certains <button> restaient en flèche
   (le <button> par défaut = cursor:default ; seuls les <a> avaient la main). */
button, .button, summary, [role="button"], [data-nav-toggle], [data-partner-toggle], [data-language-toggle], .language-choice[href] { cursor: pointer; }
button:disabled, .button:disabled, button[aria-disabled="true"], .button[aria-disabled="true"] { cursor: not-allowed; }


/* ── Suivre un joueur ────────────────────────────────────────────────────────
   Le composant vit ici et non dans une feuille de page : le pseudo s'affiche
   au classement, sur un contest, dans une salle, sur une fiche de jeu. Une
   copie par page aurait derive. */

/* Les NOMS qui menent quelque part : un pseudo vers sa fiche, un jeu vers la sienne.
   Ils gardent la couleur du texte - ce sont des noms, pas des liens de navigation - mais
   portent un trait fin au repos. Sans lui, rien ne distingue un nom cliquable d'un nom
   mort, et il faut promener la souris sur la page pour decouvrir ce qui repond. */
.nf-pseudo,
.rk-game-link,
.ps-scores a,
.record-card h3 a,
.certified-record-id strong a {
    color: var(--text);
    font-weight: 700;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: rgba(151, 174, 211, 0.38);
    text-underline-offset: .22em;
    /* Le trait ne doit pas couper les jambages : il passe derriere. */
    text-decoration-skip-ink: auto;
    transition: color .12s ease, text-decoration-color .12s ease;
}

.nf-pseudo:hover,
.nf-pseudo:focus-visible,
.rk-game-link:hover,
.rk-game-link:focus-visible,
.ps-scores a:hover,
.ps-scores a:focus-visible,
.record-card h3 a:hover,
.record-card h3 a:focus-visible,
.certified-record-id strong a:hover,
.certified-record-id strong a:focus-visible {
    color: var(--brand-bright);
    text-decoration-color: var(--brand);
}

/* Une PASTILLE ronde, pleine, avec son signe gras au centre. Un contour fin se perdait
   a cote d'un pseudo ; un rond de couleur se voit et se vise. */
.nf-follow {
    margin-left: .45em;
    padding: 0;
    /* Un rond veut une largeur EGALE a sa hauteur : en `em`, les deux suivent la taille
       du texte a cote duquel il se pose. */
    width: 1.45em;
    height: 1.45em;
    line-height: 1;
    font-size: .92em;
    font-weight: 800;
    color: #fff;
    background: var(--brand);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    /* Le signe change - « + » puis « ✓ » - mais le rond, lui, ne bouge pas :
       une ligne qui tressaute a chaque clic se remarque. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: -.28em;
    transition: background-color .12s ease, transform .12s ease;
}

/* Un element remplace : aucune metrique de fonte, donc le centrage de la boite flex
   tombe juste. */
.nf-follow svg {
    display: block;
    width: .62em;
    height: .62em;
}

.nf-follow.nf-wide svg {
    width: .82em;
    height: .82em;
}

.nf-follow:hover,
.nf-follow:focus-visible {
    background: var(--brand-bright);
    transform: scale(1.08);
}

/* Deja suivi : le rond se retire, il a fait son travail. Il reste visible et cliquable
   pour se desabonner, sans continuer a appeler l'oeil comme une chose a faire. */
.nf-follow.is-on {
    color: var(--brand-bright);
    background: rgba(134, 93, 255, .18);
    box-shadow: inset 0 0 0 1px var(--brand);
}

.nf-follow.is-on:hover,
.nf-follow.is-on:focus-visible {
    background: rgba(134, 93, 255, .3);
}

.nf-follow[disabled] {
    opacity: .5;
    cursor: progress;
}

/* La case de suivi avec son etat ecrit. Elle ne sert que la ou elle est SEULE - une
   fiche - parce qu'en colonne cinquante « Suivre » noieraient les pseudos. La largeur
   fixe des cases muettes ne s'applique donc pas ici. */
.nf-follow.nf-wide {
    width: auto;
    height: auto;
    gap: .4em;
    padding: .34em .85em;
    border-radius: 999px;
    line-height: 1.35;
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .02em;
    vertical-align: baseline;
}

/* La liste des suivis. Chaque ligne porte un nom qui mene quelque part et un bouton pour
   defaire : c'est tout ce qu'on vient y faire. */
.account-follows {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.account-follow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .55rem 0;
    border-bottom: 1px solid var(--line);
}

.account-follow:last-child {
    border-bottom: 0;
}

/* « En direct », en tete des suivis. La pastille bat : c'est ce qui distingue une chose qui
   se passe MAINTENANT d'une ligne de liste. */
.account-live {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0 0 1.1rem;
    padding: 0;
    list-style: none;
}

.account-live-row {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .7rem;
    border: 1px solid rgba(240, 75, 189, 0.3);
    border-radius: var(--radius-sm);
    background: rgba(240, 75, 189, 0.06);
}

.account-live-what {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .4rem;
}

.account-live-dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--magenta);
    animation: nelfe-live-pulse 1.8s ease-in-out infinite;
}

@keyframes nelfe-live-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

/* Un battement permanent est fatigant pour qui y est sensible, et il n'apporte rien de plus
   que la couleur. */
@media (prefers-reduced-motion: reduce) {
    .account-live-dot {
        animation: none;
    }
}

/* Le reglage des notifications, en tete des suivis. */
.account-push {
    margin: 0 0 1.2rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--line);
}

.account-push-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.account-push .account-note {
    margin-top: .6rem;
}

/* ── Le registre des notifications ───────────────────────────────────────── */
/* Sous le reglage du push, et non a sa place : un push refuse ou jamais souscrit
   ne doit rien effacer. Une liste sobre, qui se parcourt sans etre une corvee. */
/* Les quatre familles, en cases a cocher. Elles ne coupent que la remise : la liste
   ci-dessous garde tout, et c'est pour cela qu'on peut decocher sans rien perdre. */
.account-notif-prefs {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.4rem;
}

.account-notif-prefs label {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .88rem;
    cursor: pointer;
}

.account-notif-prefs input:disabled + span { opacity: .55; }

.account-notifs {
    list-style: none;
    margin: 0 0 1.2rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.account-notif {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .4rem 1rem;
    padding: .5rem .7rem;
    border-radius: 8px;
    background: color-mix(in srgb, var(--line) 22%, transparent);
    font-size: .9rem;
}

.account-notif time {
    flex: none;
    font-size: .76rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* Pas encore vue : un liseré a gauche, rien de plus. La liste se lit en balayant,
   et un fond criard ferait perdre les lignes deja lues. */
.account-notif.is-unread {
    border-left: 3px solid var(--brand-bright);
    padding-left: calc(.7rem - 3px);
}

/* Ce qui invalide une partie se distingue de ce qui la raconte. */
.account-notif-critical.is-unread {
    border-left-color: var(--warn, #f59e0b);
}

.account-notifs-empty {
    margin: 0 0 1.2rem;
}

/* Les plus anciennes, repliees sous les cinq dernieres : un lien discret, pas un bouton. */
.account-notifs-more {
    margin: -0.8rem 0 1.2rem;
}

.account-notifs-more > summary {
    cursor: pointer;
    font-size: .82rem;
    color: var(--muted);
    padding: .3rem .1rem;
}

.account-notifs-more > summary:hover,
.account-notifs-more > summary:focus-visible {
    color: var(--text);
}

.account-notifs-more[open] > summary {
    margin-bottom: .4rem;
}

/* Le hero est calibre pour une page d'ACCUEIL : sur une page de contenu — classements,
   fiches, salles — il ouvre un vide qu'il faut franchir avant de lire quoi que ce soit.
   On le resserre, en laissant tranquilles les heros deja courts (`compact-hero`). */
.page-hero:not(.compact-hero) {
    padding: clamp(52px, 6.5vw, 96px) 0 clamp(34px, 4.5vw, 58px);
}

/* Le meme raisonnement entre deux blocs. */
.rk-board {
    padding-top: clamp(22px, 2.8vw, 38px);
}

/* Le sceau sur les cartes de la home : meme discretion qu'au classement. */
.perf-seal {
    display: inline-block;
    margin-right: .3em;
    vertical-align: -.1em;
}

/* La carte de record etait trop HAUTE : chaque ligne prenait toute la largeur alors que
   « score » et « place mondiale » sont courts et se lisent ensemble. Ils passent donc cote
   a cote ; le joueur, lui, garde sa ligne — c'est le nom qu'on cherche en premier. */
.record-card .record-lines {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .5rem 1rem;
    margin: 0;
}

.record-card .record-lines > div:first-child {
    grid-column: 1 / -1;
}

.record-card .record-lines dt {
    margin-bottom: .1rem;
    color: var(--muted);
    font-size: .68rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    font-weight: 700;
}

.record-card .record-lines dd {
    margin: 0;
}

/* Le meme code couleur que le certificat de record : un score certifie se reconnait a sa
   couleur, et deux teintes pour la meme chose obligeraient a se demander si c'est bien la
   meme. */
.record-card .perf-score {
    display: flex;
    align-items: center;
    gap: .35rem;
    color: #ffcb05;
    font-family: ui-monospace, Consolas, monospace;
    font-size: 1.32rem;
    font-weight: 800;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 26px #ffcb0528;
}

/* Le sceau MENE au certificat : il doit se viser, donc grandir un peu au survol. */
.perf-seal-link {
    display: inline-flex;
    flex: none;
    transition: transform .12s ease;
}

.perf-seal-link:hover,
.perf-seal-link:focus-visible {
    transform: scale(1.18);
}

.record-card .record-origin {
    margin: .7rem 0 0;
}

.record-card .record-actions {
    margin-top: .9rem;
}

/* Les jeux mis en avant : la meme carte qu'un record, avec la capture en jeu seule. Sur la
   capture d'un record, le tube CONTIENT l'image parce qu'un recadrage couperait le score qu'elle
   atteste. Ici il n'y a rien a attester : l'ecran REMPLIT le tube, et un shoot'em up vertical
   ne se reduit plus a une bande etroite entre deux marges sombres.

   La classe s'appelle record-spotlight et non spotlight-card : ce dernier nom est celui de la
   vitrine de la boutique (grille a deux colonnes, 28 px entre chaque element, effet au survol),
   et les cartes en heritaient : c'est ce qui les faisait si hautes. */
.crt-tube img.spotlight-shot {
    object-fit: cover;
}

/* Le lien vers le vote du vendredi, sous le titre de la section, et sur la meme ligne les trois jeux
   en tete du vote (2026-10-09). Le titre de la section s'elargit pour les y tenir ; au-dela, la
   rangee passe a la ligne. */
.section-records .section-heading {
    max-width: none;
}

.section-heading .records-programme {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 14px;
    margin: 14px 0 0;
}

.vote-leaders-label {
    color: var(--muted);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.vote-leaders {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Un jeu en tete : son rang, son ecran en noir et blanc comme sur la page du vote, son nom et ses
   voix. Tout le bloc mene a son ecran sur la page du vote. */
.vote-leader {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 5px 13px 5px 6px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface-soft);
    color: var(--text);
    text-decoration: none;
    transition: border-color .15s ease, transform .15s ease;
}

.vote-leader:hover,
.vote-leader:focus-visible {
    border-color: var(--violet);
    transform: translateY(-1px);
}

.vote-leader:focus-visible {
    outline: 2px solid var(--violet);
    outline-offset: 2px;
}

.vote-leader-rank {
    display: grid;
    place-items: center;
    flex: none;
    width: 1.45em;
    height: 1.45em;
    border-radius: 6px;
    background: var(--violet);
    color: #fff;
    font-size: .72rem;
    font-weight: 800;
}

.vote-leader-screen {
    flex: none;
    width: 46px;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: 22% / 30%;
    background: #05070c;
    box-shadow: 0 0 0 1px #1a2132, 0 0 0 3px #0b0f18;
}

.vote-leader-screen img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    image-rendering: pixelated;
    filter: grayscale(1) contrast(1.15) brightness(1.1);
}

.vote-leader-text {
    display: grid;
    min-width: 0;
    line-height: 1.2;
}

.vote-leader-text strong {
    max-width: 11rem;
    overflow: hidden;
    font-size: .86rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.vote-leader-text span {
    color: #b9a6ff;
    font-size: .74rem;
    font-weight: 700;
}

@media (prefers-reduced-motion: reduce) {
    .vote-leader {
        transition: none;
    }

    .vote-leader:hover,
    .vote-leader:focus-visible {
        transform: none;
    }
}

/* ── Le compteur des scores publies (2026-10-09) ─────────────────────────────
   Une carte sous le titre et ses boutons, a gauche de la carte du dernier jeu ouvert, dans la
   couleur des scores certifies : le nombre monte de 0 jusqu'a lui (js/compteur.js). Elle a sa
   largeur d'arrivee des le depart : le nombre grandit dedans sans la faire bouger. */
.hero-counter {
    display: grid;
    gap: 8px;
    width: 100%;
    max-width: 520px;
    margin-top: 28px;
    padding: 16px 22px 18px;
    border: 1px solid rgba(255, 203, 5, .18);
    border-radius: 20px;
    background: linear-gradient(180deg, rgba(255, 203, 5, .06), rgba(9, 12, 22, .72) 70%);
    box-shadow: 0 18px 50px rgba(0, 0, 0, .3);
}

.hero-counter-label {
    color: var(--muted);
    font-size: .7rem;
    font-weight: 800;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.hero-counter-value {
    margin: 0;
    color: #ffcb05;
    font-family: ui-monospace, Consolas, monospace;
    font-size: clamp(2.6rem, 6vw, 4.4rem);
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 34px rgba(255, 203, 5, .22);
}

.record-spotlight .record-rule {
    margin-bottom: 8px;
}

/* LE RECORD EN AVANT (2026-10-02). Le score et son detenteur, puis les boutons, forment le pied
   de la carte et descendent tout en bas : d'une carte a l'autre ils tombent a la meme hauteur,
   que le titre tienne sur une ligne ou deux. Le score garde la couleur des scores certifies. */
.spotlight-foot {
    display: grid;
    gap: .85rem;
    margin-top: auto;
    padding-top: .9rem;
}

.spotlight-record {
    display: grid;
    gap: .2rem;
    min-width: 0;
    padding: .7rem .9rem .75rem;
    border: 1px solid rgba(255, 203, 5, .16);
    border-radius: 12px;
    background: rgba(255, 203, 5, .045);
}

.spotlight-record-label {
    color: var(--muted);
    font-size: .66rem;
    font-weight: 800;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.spotlight-record-score {
    color: #ffcb05;
    font-family: ui-monospace, Consolas, monospace;
    font-size: 1.7rem;
    font-weight: 800;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 26px #ffcb0528;
}

.spotlight-record-player {
    overflow: hidden;
    color: var(--text-soft);
    font-size: .9rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.spotlight-record-player strong {
    color: var(--text);
    font-weight: 800;
}

.spotlight-record-free {
    color: var(--brand-bright);
    font-size: .98rem;
    font-weight: 800;
}

/* Les deux boutons pleine largeur, l'un sous l'autre : cote a cote, ils passaient a la ligne
   selon la largeur de la carte et ne s'alignaient plus d'une carte a l'autre. */
.record-card.record-spotlight .record-actions {
    display: grid;
    grid-template-columns: 1fr;
    gap: .5rem;
    margin: 0;
    padding-top: 0;
}

.record-card.record-spotlight .record-actions .button {
    width: 100%;
}


/* MA diffusion en cours. Encadree, contrairement aux directs des autres : c'est la seule
   ligne de cette carte sur laquelle on peut agir, et un bouton d'arret doit se trouver. */
.account-live-mine {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
    margin: 0 0 .8rem;
    padding: .55rem .7rem;
    border: 1px solid rgba(224, 36, 94, .35);
    border-radius: 12px;
    background: rgba(224, 36, 94, .07);
}

.account-live-mine .account-live-what {
    flex: 1 1 auto;
}

/* ── Accueil : le dernier jeu ouvert au scoring, a droite du titre ──────────
   Le hero devient deux colonnes des qu'il y a une carte a montrer : le texte
   garde sa largeur de lecture, la carte prend le reste. Le lecteur n'arrive
   qu'au clic ; la vignette occupe sa place exacte, donc rien ne saute quand
   l'iframe la remplace. Le credit de la source vit juste dessous. */
.hero-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
    align-items: center;
}

@media (min-width: 981px) {
    .hero-grid.has-launch {
        grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr);
        gap: 48px;
        align-items: start;
    }
}

.launch-card {
    display: grid;
    gap: 12px;
    padding: 18px;
    border: 1px solid var(--line);
    border-radius: 20px;
    background: rgba(9, 12, 22, .72);
    box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
    backdrop-filter: blur(6px);
}

.launch-card .eyebrow {
    margin: 0;
}

.launch-title {
    margin: 0;
    font-size: 1.35rem;
    line-height: 1.2;
}

.launch-video {
    position: relative;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: #05050c;
    overflow: hidden;
}

/* L'effet de `crt-tube`, mais a la hauteur de l'IMAGE : la vignette prend toute la largeur de la
   carte, sans bandes noires, et le tube suit ses proportions, celles du jeu. Un jeu vertical
   donne une carte plus haute ; il ne se reduit plus a une colonne au milieu du noir. */
.launch-video.crt-tube {
    aspect-ratio: auto;
}

.launch-video.crt-tube img {
    height: auto;
    max-height: none;
    object-fit: fill;
}

/* La facade entre dans le flux : c'est son image qui donne sa hauteur au tube. */
.launch-video.crt-tube .video-facade {
    position: relative;
    height: auto;
}

/* Le bouton de lecture au-dessus du verre : l'image porte un z-index sous le balayage, et le
   bouton, qui n'en avait pas, passait dessous. */
.launch-video .video-play {
    z-index: 3;
}

/* L'apercu au survol d'un jeu sorti : la capsule passe SOUS le verre du tube (lignes, reflet,
   balayage restent par-dessus), au-dessus de la capture. Le fond flou et l'effacement que la
   boutique pose sur ses cartes en lecture ne s'appliquent pas ici : ils effaceraient le tube.
   Le bouton de lecture s'efface le temps de l'apercu ; un clic lit toujours avec le son. */
.crt-tube > iframe {
    z-index: 1;
    border: 0;
}

.crt-tube.is-playing::before {
    opacity: 1;
    filter: none;
}

.crt-tube.is-playing::after {
    opacity: 1;
}

.launch-video.is-playing .video-play {
    opacity: 0;
    transition: opacity 180ms ease;
}

/* La capsule lancee : le lecteur reprend le 16:9 de la video, sans balayage par-dessus.
   app.js pose data-lance sur le support au clic. */
.launch-video[data-lance="1"] {
    aspect-ratio: 16 / 9;
}

.launch-video[data-lance="1"]::before,
.launch-video[data-lance="1"]::after,
.launch-video[data-lance="1"] .crt-scan {
    display: none;
}

.launch-video iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* La capsule pas encore publique : l'image seule, sans bouton qui promettrait
   une lecture que YouTube refuserait. */
.launch-video-still img {
    display: block;
    width: 100%;
}

/* ── Les televiseurs de l'accueil (2026-09-17) ──────────────────────────────
   Le meme ecran que la programmation, pour que le site n'ait qu'un rendu : tube
   aux coins en ellipse, cadre sombre, balayage, reflet et vignettage, verre un
   peu moins bombe (#tv-bombe, carte posee par app.js). L'ecran quitte le bord
   de la carte : un cadre de televiseur colle a un bord ne se lit plus. */
.crt-tube.crt-tv {
    border: 0;
    border-radius: 11% / 15%;
    box-shadow:
        0 0 0 2px #1a2132,
        0 0 0 5px #0b0f18,
        0 12px 28px rgba(0, 0, 0, .5);
}

.featured-shot.crt-tv,
.record-shot-frame.crt-tv {
    margin: 5px 5px 18px;
    border-bottom: 0;
}

.crt-tube.crt-tv img {
    border-radius: 0;
    transform: scale(1.03);
}

.crt-bombe .crt-tube.crt-tv img {
    filter: url(#tv-bombe) contrast(1.08) saturate(1.12) brightness(1.02);
}

.crt-tube.crt-tv::after {
    border-radius: inherit;
    background:
        radial-gradient(90% 60% at 30% 18%, rgba(255, 255, 255, .14), transparent 55%),
        radial-gradient(120% 90% at 50% 50%, transparent 58%, rgba(0, 0, 0, .5) 100%);
    box-shadow: inset 0 0 26px rgba(0, 0, 0, .75), inset 0 0 0 1px rgba(255, 255, 255, .05);
}

/* L'apercu au survol : le tube CHAUFFE tant que YouTube montre ses commandes (lignes qui
   defilent, bande claire qui remonte), puis la video s'efface en fondu a la sortie. */
.crt-tube.crt-tv.is-loading::before {
    background-image:
        linear-gradient(to bottom, transparent 0, rgba(255, 255, 255, .08) 46%, rgba(255, 255, 255, .13) 50%, transparent 58%),
        repeating-linear-gradient(to bottom, rgba(0, 0, 0, .34) 0, rgba(0, 0, 0, .34) 1px, transparent 1px, transparent 3px);
    background-size: 100% 260%, 100% 3px;
    animation: crt-chauffe 2.2s linear infinite;
}

@keyframes crt-chauffe {
    from { background-position: 0 130%, 0 0; }
    to { background-position: 0 -130%, 0 -30px; }
}

.crt-tube.crt-tv.is-leaving > iframe {
    opacity: 0;
    transition: opacity .3s ease .1s;
}

.crt-filters {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

/* L'INVITATION A SCORER, a la fin de l'apercu (decision du 2026-09-17) : elle prend tout l'ecran,
   devant la video arretee et devant le verre, et porte les gestes de la carte. Cachee sans
   `display: none`, pour qu'elle arrive en fondu. */
.crt-tv .tv-fin {
    position: absolute;
    inset: 0;
    z-index: 4;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 8px;
    padding: 8% 10%;
    border-radius: inherit;
    background: radial-gradient(120% 90% at 50% 45%, rgba(10, 13, 24, .82), rgba(3, 4, 9, .94));
    text-align: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity .35s ease, visibility 0s linear .35s;
}

.crt-tv.is-ended .tv-fin {
    opacity: 1;
    visibility: visible;
    transition: opacity .35s ease, visibility 0s;
}

.tv-fin-titre {
    margin: 0;
    color: #fff;
    font-size: clamp(1.05rem, 2vw, 1.4rem);
    font-weight: 800;
    line-height: 1.15;
}

.tv-fin-texte {
    margin: 0;
    max-width: 32ch;
    color: #ffcb05;
    font-size: .92rem;
    font-weight: 700;
    line-height: 1.3;
}

.tv-fin-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: 6px 0 0;
}

@media (prefers-reduced-motion: reduce) {
    .crt-tube.crt-tv.is-loading::before { animation: none; }
}

.launch-credit {
    margin: 0;
    color: #8fa2bf;
    font-size: .78rem;
}

/* Le bloc RECORD des cartes de jeu (.spotlight-record), un cran plus grand sur la carte du
   jeu de la semaine : c'est la premiere chose qu'on voit de la page. */
.launch-record .spotlight-record-score {
    font-size: 2.1rem;
}

.launch-record .spotlight-record-player {
    font-size: 1rem;
}

.launch-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/* ── Compteur de lectures d'un replay ────────────────────────────────────────
   Discret à côté du bouton : une information, pas un appel. L'œil dit ce que
   c'est sans lire le mot, et le nombre tient sur une ligne en toute langue. */
.play-count {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 8px;
    color: #8fa2bf;
    font-size: .82rem;
    font-weight: 600;
    white-space: nowrap;
    vertical-align: middle;
    font-variant-numeric: tabular-nums;
}

.play-count-icon {
    flex: none;
    opacity: .85;
}

/* ── Un geste vers la borne se voit partir ───────────────────────────────────
   Apres un clic sur « Lancer le jeu », « Replay » ou « Rejoindre », le bouton
   se grise quelques secondes : la borne a la demande, la marteler n'apporte
   rien. Les boutons portent aussi `disabled`, qui a deja son style ; cette
   regle sert aux liens, qui ne connaissent pas cet attribut. */
.is-cooling {
    opacity: .55;
    cursor: progress;
}

/* ── Parties reçues (gestion) ─────────────────────────────────────────────── */
/* Une page de lecture : l'état se voit à la couleur, le reste reste sobre pour
   que l'œil descende la colonne des verdicts sans être retenu ailleurs. */
.pill {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid var(--line-strong);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
}
.pill.ok   { color: #4fbf7b; border-color: rgba(79, 191, 123, 0.45); }
.pill.ko   { color: #c8556b; border-color: rgba(200, 85, 107, 0.45); }
.pill.wait { color: #d9a441; border-color: rgba(217, 164, 65, 0.45); }
.pill.off  { color: var(--muted); }

.admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; }

.filters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
}
.filters input,
.filters select {
    padding: 7px 10px;
    border-radius: 8px;
    border: 1px solid var(--line-strong);
    background: var(--surface, #12172a);
    color: inherit;
    font: inherit;
}

.pager {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
}

#partie-detail {
    width: min(920px, 92vw);
    max-height: 82vh;
    border: 1px solid var(--line-strong);
    border-radius: 14px;
    background: var(--surface, #12172a);
    color: inherit;
    padding: 16px 18px;
}
#partie-detail::backdrop { background: rgba(4, 6, 14, 0.72); }
.detail-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 10px;
}
.detail-body {
    max-height: 64vh;
    overflow: auto;
    font-size: 0.8rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}

/* LES EMPREINTES DE LA ROM, sous le nom du jeu (nelfe-board.js). Discretes au repos : une
   precision pour qui veut refaire le record, pas une donnee du classement. */
.rk-rom {
    display: grid;
    gap: 4px;
    margin-top: 4px;
}

.rk-rom-carts {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.rk-rom-cart {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 6px 2px 4px;
    font: inherit;
    font-size: 0.68rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.02em;
    color: var(--muted);
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 6px;
    cursor: pointer;
    transition: color .12s ease, border-color .12s ease, background .12s ease;
}

.rk-rom-cart svg {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.rk-rom-cart:hover,
.rk-rom-cart:focus-visible,
.rk-rom-cart[aria-expanded="true"] {
    color: var(--text-soft);
    border-color: var(--line-strong);
}

.rk-rom-cart[aria-expanded="true"] {
    background: var(--surface-raised);
}

.rk-rom-cart:focus-visible,
.rk-rom-copy:focus-visible {
    outline: 2px solid var(--brand-bright);
    outline-offset: 1px;
}

/* Le tableau garde ses cellules sur une ligne ; l'empreinte, elle, doit pouvoir se couper. */
.rk-rom-detail {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 4px 6px;
    max-width: 36ch;
    white-space: normal;
}

.rk-rom-detail[hidden] {
    display: none;
}

.rk-rom-value {
    flex: 1 1 20ch;
    min-width: 0;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--text-soft);
    word-break: break-all;
    overflow-wrap: anywhere;
    user-select: all;
}

.rk-rom-copy {
    flex: none;
    padding: 2px 8px;
    font: inherit;
    font-size: 0.68rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--brand-bright);
    background: color-mix(in srgb, var(--brand) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--brand) 40%, transparent);
    border-radius: 6px;
    cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
    .rk-rom-cart {
        transition: none;
    }
}

/* Heberger un noeud NelfePlay (2026-10-07) : la page des hebergeurs, liee depuis le pied de page. Elle
   reprend les blocs des pages partenaires ; ne vit ici que ce qui lui est propre. */
.node-hero {
    background:
        radial-gradient(circle at 78% 38%, rgba(92, 227, 161, 0.09), transparent 31rem),
        linear-gradient(to bottom, rgba(14, 20, 34, 0.65), transparent);
}

.node-why {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

.node-why article {
    padding: 28px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(13, 18, 30, 0.76);
}

.node-why h3 {
    margin-bottom: 12px;
}

.node-why p {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}

/* L'adresse que le noeud recevra : elle se coupe plutot que de deborder d'une carte etroite. */
.node-roles-grid article > span {
    overflow-wrap: anywhere;
}

.node-columns {
    display: grid;
    align-items: start;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(40px, 6vw, 80px);
}

.node-columns h2 {
    margin-bottom: 30px;
    font-size: clamp(1.8rem, 3vw, 2.6rem);
}

.node-pair article {
    min-height: 0;
}

.node-pair h2 {
    margin-bottom: 10px;
    font-size: 1.45rem;
    letter-spacing: -0.02em;
}

/* Cinq etapes sur une ligne ; en dessous, la grille des etapes garde ses deux colonnes puis une. */
@media (min-width: 1001px) {
    .process-grid.node-steps {
        grid-template-columns: repeat(5, 1fr);
    }

    .process-grid.node-steps li {
        padding: 24px;
    }
}

@media (max-width: 1000px) {
    .node-why,
    .node-columns {
        grid-template-columns: 1fr;
    }
}

/* La candidature : la liste du type d'hebergement et les cases des roles. Les cases vivent hors de
   .field, dont les regles de champ de saisie (hauteur, cadre) les deformeraient. */
.submission-form .field select {
    width: 100%;
    min-height: 50px;
    padding: 12px 40px 12px 14px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background-color: rgba(4, 7, 13, 0.82);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path stroke='%238f9bb0' stroke-width='1.8' fill='none' d='M1 1.5l5 5 5-5'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    color: var(--text);
    font: inherit;
    appearance: none;
    -webkit-appearance: none;
    transition: border-color 160ms ease, box-shadow 160ms ease;
}

.submission-form .field select option {
    background: #fff;
    color: #111;
}

.submission-form .field select:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 4px rgba(134, 93, 255, 0.08);
    outline: 0;
}

.submission-form .field select[aria-invalid="true"] {
    border-color: var(--danger);
}

.node-roles {
    display: grid;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    grid-column: 1 / -1;
    gap: 8px;
}

.node-roles legend {
    margin-bottom: 10px;
    padding: 0;
    color: var(--text-soft);
    font-size: 0.78rem;
    font-weight: 750;
}

.node-roles legend span {
    color: var(--brand);
}

.node-role-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px 20px;
}

.node-docker {
    align-self: end;
    padding-bottom: 15px;
}

@media (max-width: 640px) {
    .node-role-grid {
        grid-template-columns: 1fr;
    }

    .node-docker {
        padding-bottom: 0;
    }
}

.node-pair .trust-icon {
    font-size: 1rem;
}

/* Les serveurs NelfePlay (2026-10-07) : le central et ses miroirs, leur etat en pastille. Le tableau
   defile seul sur un telephone ; la page, jamais. */
.server-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(13, 18, 30, 0.76);
}

.server-table {
    width: 100%;
    min-width: 640px;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.server-table th,
.server-table td {
    padding: 14px 18px;
    border-bottom: 1px solid var(--line);
    text-align: left;
    vertical-align: top;
}

.server-table tbody tr:last-child td {
    border-bottom: 0;
}

.server-table th {
    font-size: 0.74rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.server-table time {
    font-variant-numeric: tabular-nums;
}

.server-meta {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: 0.82rem;
}

.server-empty,
.server-cta {
    margin: 18px 0 0;
    color: var(--muted);
}

.server-cta {
    margin-top: 28px;
}

/* Le code d'enrolement d'un miroir, affiche une fois a l'admin : il se recopie sans erreur. */
.mirror-code {
    font-size: 1.6rem;
    letter-spacing: 0.08em;
    font-variant-numeric: tabular-nums;
}

/* « Mes serveurs » (2026-10-08) : le code d'enrolement de l'hebergeur et son kit d'installation. */
.server-code {
    display: grid;
    gap: 6px;
    padding: 12px 0;
}

.server-code p {
    margin: 0;
}

.server-kit {
    margin-top: 16px;
}

.server-kit summary {
    cursor: pointer;
    font-weight: 600;
}

.server-kit h3 {
    margin: 18px 0 8px;
    font-size: 1rem;
}

.server-kit pre {
    margin: 0 0 8px;
    padding: 12px 14px;
    overflow-x: auto;
    background: var(--surface-soft);
    border: 1px solid var(--line);
    border-radius: 8px;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 0.85rem;
    line-height: 1.5;
}

.server-files {
    display: grid;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.server-files li {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    align-items: baseline;
}

/* La copie figee du site statique (CDC infra §7 bis, 2026-10-07) : ce qu'un miroir affiche a la
   place d'un formulaire, et la ligne de pied de page qui dit qu'on lit une copie. */
.central-only {
    display: grid;
    justify-items: start;
    gap: 16px;
}

.central-only p {
    margin: 0;
    color: var(--text-soft);
}

.footer-copy {
    padding-bottom: 26px;
}

.footer-copy p {
    max-width: 74ch;
    margin: 0;
    color: #6b788d;
    font-size: 0.78rem;
    line-height: 1.5;
}

.footer-copy a {
    color: var(--brand-bright);
}
