/* ============================================================
   Snake'on — site public. Reprise du design du 07/10 : le site ressemble au jeu.

   Direction : l'interface du menu du jeu, posée sur l'arène. La vidéo du vrai moteur est la
   scène ; l'aurore du menu du jeu (WebGL, voir portal.js) se mêle à elle. Les textes vivent sur
   des panneaux TRANSPARENTS à bord fin et coins coupés : l'arène se voit au travers.

   Polices : celles du menu du jeu (cahier §0.4) — Unbounded pour les titres, Sora pour le texte.
   Mesure : grep -n -E "\-\-h-(display|ui)" "/home/matt/mini-jeux/Snake'on/index.html".
   Couleurs : celles du menu du jeu (bloc #menuScreen de son index.html), une par rôle de texte
   (section 2). Graisses et interlettrages : ceux du jeu (section 3).

   Lisibilité : un panneau laisse passer 40 % de l'arène. Avec ce réglage, le texte courant tient
   le contraste AA même si l'arène était d'un blanc pur sous lui (outillage/verifier-design.py,
   bloc F), donc aussi sur les vraies images de la vidéo (outillage/verifier-mobile.py, bloc I).
   Un texte petit dont la couleur est moins lumineuse (date, étiquette, action) porte sa propre
   pastille ou sa propre plaque, plus sombre.

   Contrainte : la CSP de production interdit tout style en ligne. Tout ce qui se voit est déclaré ici.
   ============================================================ */

/* ---------- 1. Polices ---------- */
/* Unbounded : « block » et non « swap », pour que le titre de marque n'apparaisse jamais dans une
   police de repli. build.py précharge les deux fichiers (mêmes adresses qu'ici). */
@font-face { font-family: 'Unbounded'; src: url('/assets/unbounded-var.woff2') format('woff2'); font-weight: 200 900; font-style: normal; font-display: block; }
@font-face { font-family: 'Sora'; src: url('/assets/sora-var.woff2') format('woff2'); font-weight: 100 800; font-style: normal; font-display: swap; }

/* ---------- 2. Jetons ---------- */
:root {
  color-scheme: dark;

  /* Palette du jeu. En commentaire : la variable du jeu dont vient chaque valeur. */
  --encre: #0f0f13;                        /* --bg : fond réel du jeu */
  --nuit: #07060e;                         /* --m-ink : encre du menu */
  --nuit-3: #17142b;                       /* --m-ink-3 */
  --menthe: #00ffcc;                       /* --accent, --solo */
  --cyan: #22d3ff;                         /* --solo-2 */
  --violet: #a283ff;                       /* --multi : le multijoueur */
  --or: #ffcf4d;                           /* --m-gold : compteur de pièces */
  --danger: #ff0055;                       /* --danger : réservé au trait qui barre le prix de base (cahier §4) */
  --blanc-lilas: #f3f1ff;                  /* --m-text */
  --lilas: #a9a4c8;                        /* --m-muted */
  --trait: rgb(196 186 255 / 16%);         /* --m-line */
  --trait-fort: rgb(196 186 255 / 28%);    /* --m-line-2 */

  /* Une couleur par rôle de texte */
  --c-titre: var(--menthe);                /* titres */
  --c-texte: var(--blanc-lilas);           /* texte courant, navigation */
  --c-date: var(--or);                     /* dates et mentions */
  --c-action: var(--cyan);                 /* liens et actions */
  --c-second: var(--violet);               /* accent secondaire : le multijoueur */
  --c-discret: var(--lilas);               /* pied de page, champs inactifs : seulement sur un fond presque opaque */

  /* Fonds. Un panneau laisse voir l'arène ; pastilles et plaques d'action sont plus sombres. */
  --fond-carte: rgb(7 6 14 / 60%);         /* encre du menu du jeu, comme son panneau #menuBrowse (55 à 72 %) */
  --fond-carte-survol: rgb(7 6 14 / 72%);
  --fond-pastille: rgb(14 12 28 / 72%);    /* .m-pill du jeu */
  --fond-action: rgb(12 10 26 / 78%);      /* .m-line-btn et .m-ghost du jeu (72 %), renforcé pour le cyan */
  --fond-actif: rgb(6 28 26 / 80%);        /* entrée courante : encre teintée de menthe */

  /* Typographie */
  --titres: 'Unbounded', 'Arial Black', system-ui, sans-serif;   /* --h-display du jeu */
  --interface: 'Sora', 'Segoe UI', system-ui, sans-serif;        /* --h-ui du jeu */
  --t-meta: 13px;                          /* pastilles : dates, étiquettes */
  --t-petit: 14px;
  --t-corps: 16px;
  --t-chapo: 18px;
  --t-h3: clamp(19px, 0.5vw + 15px, 22px);
  --t-h2: clamp(19px, 0.4vw + 16px, 22px);
  --t-h1: clamp(21px, 5.2vw + 3px, 40px);

  /* Forme et mouvement */
  --c: 14px;                               /* coin coupé d'un panneau : --m-bevel du jeu */
  --detente: cubic-bezier(.2, .8, .2, 1);  /* --m-ease : courbe du menu du jeu */
  --mesure: 940px;                         /* largeur maximale d'une colonne de contenu */
  --chevron: polygon(0 0, 50% 0, 100% 50%, 50% 100%, 0 100%, 50% 50%);   /* .m-lane-mark du jeu */
  --fleche: polygon(0 0, calc(100% - 18px) 0, 100% 50%, calc(100% - 18px) 100%, 0 100%, 10px 50%);   /* --m-arrow du jeu */
}

/* ---------- 3. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--encre);
  touch-action: manipulation;           /* pas de zoom au double toucher ; le zoom au pincement reste permis */
  scroll-padding-top: 104px;
  scrollbar-color: #3b3760 var(--nuit);
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
}
body.portal {
  margin: 0; min-height: 100svh;
  display: flex; flex-direction: column;
  color: var(--c-texte);
  font: 400 var(--t-corps)/1.6 var(--interface);   /* le jeu : 400 15px/1.45 Sora ; ici 16 px, plancher du corps de texte */
  -webkit-font-smoothing: antialiased;
}
::selection { color: var(--nuit); background: var(--menthe); }

/* Titres : Unbounded, couleur du rôle « titre ». Graisses du jeu : 900 pour un titre de page (.m-sec-title,
   .m-mode-name : -0.01em), 700 pour un intertitre (.m-lane-title). */
h1, h2, h3 { margin: 0; font-family: var(--titres); color: var(--c-titre); text-wrap: balance; overflow-wrap: break-word; }
h1 { font-size: var(--t-h1); font-weight: 900; line-height: 1.12; letter-spacing: -.01em; }
h2 { font-size: var(--t-h2); font-weight: 700; line-height: 1.2; }
h3 { font-size: var(--t-h3); font-weight: 700; line-height: 1.25; }
p { margin: 0; max-width: 66ch; text-wrap: pretty; }

a { color: var(--c-action); text-decoration-thickness: 1px; text-underline-offset: .22em; }
button, input { font: inherit; color: inherit; }
button, summary, a { -webkit-tap-highlight-color: transparent; }
button, summary { cursor: pointer; }
button:disabled { cursor: not-allowed; }
svg { display: block; max-width: 100%; }
.icon { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* Focus clavier : l'anneau du jeu (2 px menthe, décalé de 3 px), doublé d'un halo d'encre pour rester lisible
   sur l'arène. Les panneaux sont dessinés par un pseudo-élément : l'anneau n'est jamais rogné par un clip-path. */
:where(a, button, input, summary):focus-visible {
  outline: 2px solid var(--menthe); outline-offset: 3px;
  box-shadow: 0 0 0 6px rgb(7 6 14 / 88%);
}
#contenu:focus { outline: none; }

.skip-link {
  position: fixed; top: -100px; left: 16px; z-index: 300;
  padding: 12px 20px; color: var(--nuit); background: var(--menthe);
  font-weight: 700; letter-spacing: .04em; text-decoration: none;
}
.skip-link:focus { top: 12px; }

/* ---------- 4. La scène : arène (vidéo du moteur), voile, aurore ---------- */
.arene-fond { position: fixed; inset: 0; z-index: -1; overflow: hidden; background: var(--encre); }
/* Le centre de la vidéo (la caméra y suit le plus gros serpent) tombe au centre de la zone de contenu. */
.arene-fond video {
  position: absolute; top: 50%; left: 60%;
  min-width: 100%; min-height: 100%; width: auto; height: auto;
  transform: translate(-50%, -50%);
  opacity: .94;
  transition: opacity .7s ease-out;
  /* Fond pur : jamais cible d'un toucher, d'une sélection ni d'un appui long (iOS). */
  pointer-events: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
/* iOS pose son bouton de lecture sur une vidéo dont la lecture automatique est refusée (mode économie d'énergie) : la vidéo de
   fond n'en montre jamais, c'est le bouton pause du site qui la relance. Une règle par pseudo-élément : un navigateur qui n'en
   connaît pas un n'invalide que celui-là. Contrôle : outillage/verifier-mobile.py, bloc G. */
.arene-fond video::-webkit-media-controls { display: none !important; }
.arene-fond video::-webkit-media-controls-start-playback-button { display: none !important; -webkit-appearance: none; }
.arene-fond video::-webkit-media-controls-overlay-play-button { display: none !important; -webkit-appearance: none; }
.arene-fond video::-webkit-media-controls-panel { display: none !important; -webkit-appearance: none; }
.arene-fond video::-webkit-media-controls-play-button { display: none !important; -webkit-appearance: none; }
.arene-fond video::-webkit-media-controls-enclosure { display: none !important; -webkit-appearance: none; }
/* Avec le script, l'arène se rallume en fondu à chaque page au lieu d'apparaître d'un coup. */
html.js .arene-fond video:not(.pret) { opacity: 0; }
/* Voile : léger sur l'arène (le clip doit se voir), dense sur la colonne de navigation où l'aurore prend le relais.
   Le dégradé vertical est celui du menu du jeu (#menuScrim), adouci en bas : le site n'a pas de barre d'onglets à porter. */
.arene-voile {
  position: absolute; inset: 0;
  background:
    /* trame d'écran : habille l'agrandissement de la vidéo (1280×520 étirée). Allégée (26 % → 14 %) : l'arène est plus
       lumineuse qu'avant, la trame se voyait trop sur les gros serpents. */
    repeating-linear-gradient(0deg, rgb(7 6 14 / 14%) 0 1px, transparent 1px 3px),
    linear-gradient(90deg, rgb(7 6 14 / 90%) 0%, rgb(7 6 14 / 72%) 18%, rgb(7 6 14 / 14%) 42%, rgb(7 6 14 / 6%) 100%),
    linear-gradient(180deg, rgb(7 6 14 / 30%) 0%, rgb(7 6 14 / 0%) 28%, rgb(7 6 14 / 0%) 70%, rgb(7 6 14 / 36%) 100%);
}
/* Aurore. Sans WebGL (ou script absent, ou appareil trop lent) : ce dégradé fixe, aux teintes de
   l'aurore du jeu. Quand le shader tourne, portal.js pose data-aurore et le dégradé s'efface. */
#aurore {
  position: absolute; inset: 0; width: 100%; height: 100%;
  background:
    radial-gradient(58% 46% at 6% 22%, rgb(61 255 182 / 13%), transparent 72%),
    radial-gradient(46% 52% at 0% 78%, rgb(164 130 255 / 17%), transparent 72%),
    radial-gradient(40% 34% at 26% 100%, rgb(34 211 255 / 12%), transparent 72%),
    radial-gradient(34% 30% at 100% 100%, rgb(255 94 181 / 7%), transparent 72%);
}
html[data-aurore='anime'] #aurore, html[data-aurore='fige'] #aurore { background: none; }

/* ---------- 5. Le panneau : forme commune des cartes, blocs de navigation et boutons ----------
   Un pseudo-élément porte le fond, le filet et les deux coins coupés (--m-bevel du jeu : haut gauche et bas droit).
   Les coins sont coupés par clip-path ; leur filet est redessiné par deux dégradés en diagonale, sinon le coin resterait nu.
   Réglages par variables : --fond (couleur), --bord (filet), --c (taille du coin). */
.carte, .button, .animation-toggle, .menu-toggle, .menu-close, .breadcrumbs, .mode-switch a, .text-link,
#sidebar .home-link, #sidebar details, #sidebar .category-link, #sidebar .play-link {
  position: relative; isolation: isolate;
}
.carte::before, .button::before, .animation-toggle::before, .menu-toggle::before, .menu-close::before,
.breadcrumbs::before, .mode-switch a::before, .text-link::before,
#sidebar .home-link::before, #sidebar details::before, #sidebar .category-link::before, #sidebar .play-link::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(to bottom right, transparent calc(50% - .7px), var(--bord) calc(50% - .2px), var(--bord) calc(50% + .9px), transparent calc(50% + 1.4px)) top left / var(--c) var(--c) no-repeat,
    linear-gradient(to bottom right, transparent calc(50% - 1.4px), var(--bord) calc(50% - .9px), var(--bord) calc(50% + .2px), transparent calc(50% + .7px)) bottom right / var(--c) var(--c) no-repeat,
    var(--fond);
  box-shadow: inset 0 0 0 1px var(--bord);
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c));
  transition: background-color .22s ease, box-shadow .22s ease;
}

/* Carte de contenu : panneau transparent, bord fin lilas du jeu, liseré menthe à gauche (défaut) ou en haut.
   Le texte y porte une ombre d'encre, comme les titres que le jeu pose sur son fond vivant : elle détache les lettres
   d'un serpent qui passe dessous (elle n'est pas comptée dans les contrastes calculés par les contrôles). */
.carte {
  --fond: var(--fond-carte); --bord: var(--trait-fort);
  min-width: 0;
  padding: clamp(18px, 2.2vw, 28px) clamp(18px, 2.4vw, 32px);
  text-shadow: 0 1px 2px rgb(7 6 14 / 85%), 0 0 10px rgb(7 6 14 / 60%);
}
.carte::after {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  left: 0; top: var(--c); bottom: 0; width: 2px;
  background: linear-gradient(180deg, var(--menthe), rgb(0 255 204 / 0%));
  opacity: .75;
  transition: opacity .25s ease, box-shadow .25s ease, background-color .25s ease;
}
.carte--haut::after {
  left: var(--c); right: 0; top: 0; bottom: auto; width: auto; height: 2px;
  background: linear-gradient(90deg, var(--menthe), rgb(34 211 255 / 0%));
}
.carte--nu::after { content: none; }

/* Pastille : la forme des compteurs du menu du jeu (.m-pill, .m-net). Elle porte les textes petits dont la couleur
   (or, violet, menthe) ne suffirait pas sur un panneau transparent : son fond est plus sombre. */
time, .mode-label, .split .prose > h2:first-child {
  display: flex; align-items: center; width: fit-content; max-width: 100%;
  min-height: 30px; padding: 4px 13px; border-radius: 999px;
  border: 1px solid var(--trait-fort); background-color: var(--fond-pastille);
  font: 600 var(--t-meta)/1.25 var(--interface); letter-spacing: .02em;
  font-variant-numeric: tabular-nums; text-shadow: none;
}
time { border-color: rgb(255 207 77 / 36%); color: var(--c-date); }
/* Étiquette d'un mode : l'insigne du menu du jeu (.m-badge : coins de 6 px, capitales espacées), à la couleur de sa voie —
   menthe pour le solo, violet pour le multijoueur. Elle peut tenir sur deux lignes dans une carte étroite. */
.mode-label, .split .prose > h2:first-child {
  --voie: var(--menthe);
  min-height: 26px; padding: 5px 11px; border-radius: 6px;
  border-color: rgb(0 255 204 / 36%); color: var(--voie);
  font-size: 11.5px; line-height: 1.35; letter-spacing: .12em; text-transform: uppercase;
}
.voie-multi .mode-label, .voie-multi.split .prose > h2:first-child { --voie: var(--c-second); border-color: rgb(162 131 255 / 42%); }

/* ---------- 6. En-tête ---------- */
.site-header {
  position: sticky; top: 0; z-index: 90;
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(min-content, 1fr);
  align-items: center; column-gap: 12px;
  min-height: 84px; padding: 10px max(24px, calc((100vw - 1680px) / 2 + 40px));
  background: linear-gradient(180deg, rgb(7 6 14 / 92%), rgb(7 6 14 / 74%));   /* #menuTopbar du jeu : même encre, plus dense en haut */
  -webkit-backdrop-filter: blur(12px);   /* Safari avant 18 */
  backdrop-filter: blur(12px);
}
/* Liseré de l'en-tête : un trait fin qui s'éteint vers les bords, sous le titre. */
.site-header::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgb(196 186 255 / 28%) 24%, rgb(0 255 204 / 70%) 50%, rgb(196 186 255 / 28%) 76%, transparent);
}

/* Titre SNAKE'ON, dessiné comme celui du jeu (cahier §1 et §7) : Unbounded 900, dégradé balayant,
   apostrophe chevron, O animé. La taille suit la largeur d'écran pour que le titre reste centré entre
   les deux boutons de droite et leur espace miroir à gauche, jusqu'à 320 px de large
   (le titre mesure 6,53 em ; 222 px = deux fois les deux boutons, plus marges et écarts du mobile). */
.brand {
  grid-column: 2; display: inline-flex; align-items: center; min-height: 44px;
  font-size: clamp(15px, calc((100vw - 222px) / 6.6), 44px);
  text-decoration: none;
}
.wm {
  display: inline-flex; align-items: center;
  font-family: var(--titres); font-weight: 900; line-height: 1; letter-spacing: -.035em;
  user-select: none;
}
.wm-t {
  padding-inline-end: .05em; margin-inline-end: -.05em;  /* l'interlettrage négatif ne rogne pas la dernière lettre */
  background: linear-gradient(100deg, #fff 0%, #eafff7 35%, #00ffcc 50%, #fff 65%, #fff 100%);
  background-size: 260% 100%; background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: wm-balayage 7s var(--detente) infinite;
  filter: drop-shadow(0 0 .4em rgb(0 255 204 / 25%));
}
@keyframes wm-balayage { 0%, 55% { background-position: 100% 0; } 100% { background-position: -60% 0; } }
.wm-apos {
  display: inline-block; width: .16em; height: .26em; margin: 0 .05em 0 .06em; align-self: flex-start;
  transform: translateY(.04em); background: var(--cyan);
  clip-path: polygon(0 0, 45% 0, 100% 50%, 45% 100%, 0 100%, 55% 50%);
}
/* Le O : un anneau fermé (il doit se lire « O ») dont un reflet fait le tour en 14 s, au rythme du O
   du jeu. Anneau abstrait : aucun serpent n'est redessiné. */
.wm-o {
  position: relative; flex: none; width: .78em; height: .78em; margin: 0 .04em 0 .03em;
  animation: wm-tour 14s linear infinite;
  filter: drop-shadow(0 0 .2em rgb(0 255 204 / 45%));
}
.wm-o::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(#00ffcc 0deg, #22d3ff 110deg, #00ffcc 230deg, #f2fffb 300deg, #00ffcc 360deg);
  -webkit-mask: radial-gradient(closest-side, transparent 37%, #000 40%, #000 96%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 37%, #000 40%, #000 96%, transparent 100%);
}
@keyframes wm-tour { to { transform: rotate(360deg); } }
/* Le bouton pause arrête aussi le titre. */
html.en-pause .wm-t, html.en-pause .wm-o { animation-play-state: paused; }

/* Texte réel des caractères que le titre dessine en CSS (apostrophe, O) : lu par les moteurs et les IA, invisible, hors de la mise en page. */
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
/* Accueil : enveloppe <h1> du titre de l'en-tête (cahier §2, pas de gros titre redondant). Elle ne dessine rien : même colonne de la grille, aucune marge, police et interlettrage hérités. */
.brand-titre { grid-column: 2; display: flex; margin: 0; font: inherit; letter-spacing: inherit; text-wrap: inherit; }

/* Boutons de l'en-tête. PC : pause en haut à droite. Mobile : pause à côté du bouton Menu (cahier §1). */
.header-actions { grid-column: 3; justify-self: end; display: flex; align-items: center; gap: 6px; }
.animation-toggle, .menu-toggle, .menu-close {
  --c: 9px; --fond: var(--fond-pastille); --bord: var(--trait-fort);   /* .m-iconbtn du jeu : même fond, même filet */
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 44px; min-height: 44px; padding: 0 14px;
  border: 0; background: none; color: var(--c-texte);
  font: 600 13px/1 var(--interface); letter-spacing: .04em;
  transition: color .2s ease, transform .12s ease;
}
.animation-toggle .icon { width: 18px; height: 18px; }
.ico-lecture { display: none; fill: currentColor; }
.en-pause .animation-toggle { --bord: rgb(0 255 204 / 45%); color: var(--menthe); }   /* classe de <html>, posée par portal.js : fond arrêté */
.en-pause .animation-toggle .ico-pause { display: none; }
.en-pause .animation-toggle .ico-lecture { display: block; }
.animation-toggle:active, .menu-toggle:active, .menu-close:active { transform: translateY(1px); }
/* Menu et Fermer n'existent que sur mobile. */
.menu-toggle, .menu-close, #sidebar .drawer-brand { display: none; }

/* ---------- 7. Disposition : colonne gauche + zone de contenu ---------- */
.layout {
  flex: 1; width: 100%; max-width: 1680px; margin: 0 auto;
  display: grid; grid-template-columns: 272px minmax(0, 1fr); align-items: start;
  gap: clamp(20px, 2.6vw, 40px);
  padding: 28px 40px 72px;
}
#contenu {
  min-width: 0; min-height: 62svh;
  display: grid; grid-template-columns: minmax(0, var(--mesure)); align-content: start; gap: 18px;
}
.journal, .article-list, .content-pad, .editorial { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: 18px; }

/* ---------- 8. Colonne de navigation ----------
   Chaque entrée reprend l'en-tête d'une voie du menu du jeu (SOLO, MULTIJOUEUR) : chevron de voie, puis le nom en
   Unbounded 700 espacé de .14em (.m-lane-title). Les blocs restent cerclés (cahier §1). */
#sidebar { --h-ligne: 56px; }
#sidebar a { text-decoration: none; }
#sidebar nav { display: grid; gap: 10px; }
#sidebar .home-link, #sidebar details, #sidebar .category-link, #sidebar .play-link {
  --c: 12px; --fond: var(--fond-carte); --bord: var(--trait-fort);
}
#sidebar .home-link, #sidebar summary, #sidebar .category-link {
  display: flex; align-items: center; gap: 12px;
  min-height: var(--h-ligne); padding: 10px 18px 10px 44px;
  color: var(--c-texte); font: 700 13px/1.2 var(--titres); letter-spacing: .14em;
  text-shadow: 0 1px 2px rgb(7 6 14 / 85%);
  transition: color .2s ease, transform .12s ease;
}
/* Chevron de voie (.m-lane-mark du jeu) : éteint au repos, il s'allume au survol et reste allumé, avec sa lueur, sur
   la page courante. Seuls opacity, transform et filter changent : aucune propriété de mise en page n'est animée. */
#sidebar .home-link::after, #sidebar .category-link::after, #sidebar details::after {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  left: 18px; top: calc((var(--h-ligne) - 14px) / 2); width: 12px; height: 14px;
  background: var(--menthe); clip-path: var(--chevron);
  opacity: .4;
  transition: opacity .25s ease, transform .3s var(--detente);
}
#sidebar .home-link[aria-current='page'], #sidebar .category-link[aria-current='page'] {
  --fond: var(--fond-actif); --bord: rgb(0 255 204 / 40%); color: var(--menthe);
}
#sidebar .home-link[aria-current='page']::after, #sidebar .category-link[aria-current='page']::after, #sidebar details[open]::after { opacity: 1; }
#sidebar .home-link:active, #sidebar .category-link:active, #sidebar summary:active { transform: translateY(1px); }

#sidebar details { padding-bottom: 8px; }
#sidebar details:not([open]) { padding-bottom: 0; }
/* Guide ouvert : le bloc porte une liste de liens, son fond se renforce (la menthe de l'entrée courante y tient le contraste). */
#sidebar details[open] { --fond: var(--fond-carte-survol); --bord: rgb(0 255 204 / 26%); }
#sidebar summary { justify-content: space-between; list-style: none; }
#sidebar summary::-webkit-details-marker { display: none; }
#sidebar summary::after {
  content: ''; flex: none; width: 8px; height: 8px; margin-right: 2px;
  border-right: 2px solid var(--menthe); border-bottom: 2px solid var(--menthe);
  transform: translateY(-2px) rotate(45deg); transition: transform .25s var(--detente);
}
#sidebar details[open] > summary { color: var(--menthe); }
#sidebar details[open] > summary::after { transform: translateY(2px) rotate(225deg); }
#sidebar details > a {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 8px 18px 8px 44px;
  color: var(--c-texte); font: 500 15px/1.2 var(--interface);
  text-shadow: 0 1px 2px rgb(7 6 14 / 85%);
  transition: color .2s ease, background-color .2s ease;
}
/* Tiret dessiné, qui s'allonge au survol. Sa boîte garde une largeur fixe : seul un transform
   l'étire, pour que le libellé ne bouge jamais (aucune propriété de mise en page n'est animée). */
#sidebar details > a::before {
  content: ''; flex: none; width: 16px; height: 2px; background: currentColor; opacity: .45;
  transform: scaleX(.6); transform-origin: 0 50%;
  transition: transform .25s var(--detente), opacity .2s ease;
}
#sidebar details > a[aria-current='page'] { color: var(--menthe); font-weight: 600; }
#sidebar details > a[aria-current='page']::before { transform: none; opacity: 1; }
#sidebar details > a:active { background: rgb(0 255 204 / 10%); }

#sidebar .discord-link { justify-content: flex-start; }
.discord-logo { width: 22px; height: auto; flex: none; color: #5865f2; }
#sidebar .discord-link[aria-current='page'] .discord-logo { color: #8f9bff; }

/* Accès au jeu : le bouton fantôme du menu du jeu (.m-ghost : Unbounded 700, .06em). */
#sidebar .play-link {
  --fond: var(--fond-action); --bord: rgb(0 255 204 / 55%);
  display: flex; align-items: center; justify-content: center;
  min-height: var(--h-ligne); margin-top: 18px; padding: 10px 16px;
  color: var(--menthe); font: 700 12.5px/1.2 var(--titres); letter-spacing: .06em; text-align: center;
  transition: color .2s ease, transform .12s ease, filter .2s ease;
}
#sidebar .play-link[aria-current='page'] { --fond: var(--fond-actif); --bord: var(--menthe); }
#sidebar .play-link:active { transform: translateY(1px); }

/* ---------- 9. Contenu ---------- */
/* Panneau de titre d'une page : le chapô est du texte courant, plus grand. */
.page-heading p, .article-heading p { margin-top: 12px; font-size: var(--t-chapo); line-height: 1.5; }
.article-heading time { margin-bottom: 14px; }

/* Dev blog : date · titre · texte */
.news-item { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.news-item > time { align-self: start; }
.news-copy { min-width: 0; }
.news-copy h3 a { color: var(--c-titre); text-decoration: none; transition: color .2s ease; }
/* Toute la carte ouvre l'article : le lien du titre couvre le panneau. */
.news-copy h3 a::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.news-copy h3 a:focus-visible { outline: none; box-shadow: none; }
.news-copy h3 a:focus-visible::after { outline: 2px solid var(--menthe); outline-offset: 3px; box-shadow: 0 0 0 6px rgb(7 6 14 / 88%); }
.news-copy p { margin-top: 10px; }

/* Actions secondaires : le bouton fantôme du jeu (.m-ghost), sur sa propre plaque. */
.text-link, .breadcrumbs, .mode-switch a {
  --c: 8px; --fond: var(--fond-action); --bord: rgb(34 211 255 / 42%);
  display: inline-flex; align-items: center; gap: 9px; min-height: 44px;
  color: var(--c-action); font: 700 12.5px/1 var(--titres); letter-spacing: .06em; text-decoration: none; text-shadow: none;
  transition: color .2s ease, transform .12s ease;
}
.text-link { margin-top: 14px; padding: 0 14px 0 16px; }
.text-link .icon { width: 18px; height: 18px; transition: transform .3s var(--detente); }

/* Retour (fil d'Ariane) : un chevron dessiné, puis le nom de la page parente */
.breadcrumbs { justify-self: start; padding: 0 16px 0 14px; }
.breadcrumbs::after {
  content: ''; order: -1; flex: none; width: 7px; height: 7px;
  border-left: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform .3s var(--detente);
}
.breadcrumbs:active, .text-link:active { transform: translateY(1px); }

/* Texte long */
.prose > * + * { margin-top: 16px; }
.prose > section + section, .prose > h2:not(:first-child) { margin-top: 32px; }
.prose h2 + p { margin-top: 10px; }
/* Lien dans une phrase : même couleur que le texte (même contraste), reconnu à son soulignement de la couleur des actions. */
.prose a { color: var(--c-texte); text-decoration-color: var(--c-action); text-decoration-thickness: 2px; overflow-wrap: anywhere; }
.editorial > .button { justify-self: start; }
/* Fiche d'un mode : l'intitulé du type de partie est une étiquette (pastille, section 5), la première phrase un chapô. */
.split .prose > h2:first-child + p { margin-top: 14px; font-size: var(--t-chapo); line-height: 1.5; }
.mode-switch { display: flex; flex-wrap: wrap; gap: 10px; }
.mode-switch a { --c: 9px; padding: 0 18px; }
.mode-switch a:active { transform: translateY(1px); }

/* Guide : cartes des modes. Le nom reprend .m-mode-name du jeu (Unbounded 900). */
.mode-grid, .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: 18px; }
.mode-card { display: block; color: var(--c-texte); text-decoration: none; }
.mode-card h2 { font-size: 21px; font-weight: 900; letter-spacing: -.01em; transition: color .2s ease; }
.mode-card .mode-label { margin-top: 10px; }
.mode-card p:not(.mode-label) { margin-top: 12px; }

/* Boutique : l'or du compteur de pièces du jeu marque le bandeau. */
.promo-banner {
  --bord: rgb(255 207 77 / 38%);
  padding-block: 18px;
  /* Le texte de la remise est en or, couleur que la boutique ne donne à rien d'autre (cahier §4). Gras et d'au moins
     19 px : c'est un grand texte au sens du contraste, tenu même sur une arène claire. */
  color: var(--or);
  font: 700 clamp(19px, 0.6vw + 16px, 22px)/1.35 var(--interface);
  font-variant-numeric: tabular-nums;
}
.promo-banner::after { opacity: 1; background: var(--or); box-shadow: 0 0 14px rgb(255 207 77 / 50%); }
.product-card { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; }
.diamond { width: min(100%, 150px); margin: 0 auto 14px; }
.diamond svg { width: 100%; height: auto; }
.product-card .diamond { background: radial-gradient(closest-side, rgb(0 255 204 / 16%), transparent); }
.product-card h2 { font-size: 20px; }
/* Prix : Unbounded, chiffres tabulaires. Prix de base petit, barré d'un trait rouge fin en diagonale ;
   prix remisé en gros à côté (cahier §4). */
.price-block {
  display: flex; align-items: baseline; gap: 14px;
  margin: 14px 0 18px; padding-top: 14px; border-top: 1px solid var(--trait);
  font-family: var(--titres); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.price-base { position: relative; font: 500 15px/1 var(--interface); }
.price-base::after {
  content: ''; position: absolute; left: -8%; right: -8%; top: 50%; height: 1.5px;
  background: var(--danger); transform: rotate(-12deg);
}
.price-final { color: var(--menthe); font-size: 28px; font-weight: 900; line-height: 1; letter-spacing: -.01em; text-shadow: 0 1px 2px rgb(7 6 14 / 85%), 0 0 22px rgb(0 255 204 / 35%); }
.price-block.big { margin-top: 18px; }
.price-block.big .price-base { font-size: 18px; }
.price-block.big .price-final { font-size: 40px; }
.product-card .button { width: 100%; padding-inline: 12px; }

.product-detail { display: grid; grid-template-columns: minmax(200px, .8fr) minmax(0, 1.2fr); gap: 18px; }
.product-detail > .diamond { width: auto; margin: 0; display: grid; place-items: center; background: radial-gradient(closest-side, rgb(0 255 204 / 13%), transparent 78%); }
.product-detail > .diamond svg { width: min(100%, 220px); }
.purchase-panel h1 { font-size: clamp(24px, 3vw, 36px); }
.account-field { margin: 4px 0 20px; }
/* Libellé de champ : .m-lbl du jeu (Sora 600, capitales espacées). */
.account-field label { display: block; margin-bottom: 8px; font: 600 12px/1.3 var(--interface); letter-spacing: .18em; text-transform: uppercase; }
/* Champ : .m-input du jeu (fond d'encre, filet lilas, coins de 10 px). */
.account-field input {
  width: 100%; min-height: 48px; padding: 0 14px;
  border: 1px solid var(--trait-fort); border-radius: 10px;
  color: var(--c-texte); background: var(--fond-pastille); caret-color: var(--menthe);
}
.account-field input::placeholder { color: var(--c-discret); opacity: 1; }
.account-field input:disabled { color: var(--c-discret); -webkit-text-fill-color: var(--c-discret); opacity: 1; cursor: not-allowed; }

/* Questions fréquentes */
.faq { display: grid; gap: 10px; }
.faq details { padding: 0; }
.faq details::after { opacity: .4; }
.faq details[open]::after { opacity: 1; }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 60px; padding: 14px clamp(18px, 2.4vw, 32px);
  color: var(--c-texte); font-weight: 600; line-height: 1.35; list-style: none;
  transition: color .2s ease;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; flex: none; width: 8px; height: 8px;
  border-right: 2px solid var(--c-action); border-bottom: 2px solid var(--c-action);
  transform: translateY(-2px) rotate(45deg); transition: transform .25s var(--detente);
}
.faq details[open] > summary::after { transform: translateY(2px) rotate(225deg); }
.faq details p { padding: 0 clamp(18px, 2.4vw, 32px) 20px; }

/* Avis, plateformes, Discord, page introuvable */
.notice.carte { --bord: var(--trait); padding-block: 18px; }
.notice.carte::after { opacity: .4; }
.platform-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.platform h2 { font-size: 20px; }
.platform p { margin-top: 10px; }
.discord-page { display: grid; justify-items: center; gap: 18px; padding-block: 40px; text-align: center; }
.discord-page .discord-logo { width: 64px; }
.discord-page .notice { padding: 12px 18px; border: 1px solid var(--trait); border-radius: 14px; background: rgb(7 6 14 / 55%); }
.empty-state p { margin-top: 12px; }
.empty-state .button { margin-top: 22px; }

/* ---------- 10. Boutons ----------
   Bouton principal : le « LANCER » du menu du jeu (.m-go) — flèche, dégradé menthe → cyan, Unbounded 900 espacé de .06em,
   texte d'encre #04120c. La couleur de fond (menthe) reste déclarée sous le dégradé : c'est elle que lit le contrôle de contraste.
   Bouton secondaire : le bouton fantôme du jeu (.m-ghost). */
.button {
  --c: 10px; --fond: var(--menthe); --bord: transparent;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 50px; padding: 0 30px 0 26px; border: 0; background: none;
  color: #04120c; font: 900 14px/1.2 var(--titres); letter-spacing: .06em;
  text-align: center; text-decoration: none; text-shadow: none;
  transition: color .2s ease, transform .12s ease, filter .2s ease;
}
.button:not(.secondary)::before {
  background: linear-gradient(90deg, var(--menthe), var(--cyan)) var(--fond);
  box-shadow: none; clip-path: var(--fleche);
}
.button .icon { transition: transform .3s var(--detente); }
.button.secondary {
  --fond: var(--fond-action); --bord: rgb(34 211 255 / 50%);
  padding: 0 22px; color: var(--c-action); font-weight: 700; font-size: 12.5px;
}
.button:active { transform: translateY(1px); }
.button:disabled { --fond: var(--nuit-3); color: var(--c-discret); transform: none; }
.button:disabled:not(.secondary)::before { background: var(--fond); }

/* ---------- 11. Survol (appareils à pointeur seulement : pas de survol collé au doigt) ---------- */
@media (hover: hover) {
  a:hover { color: #fff; }
  .animation-toggle:hover, .menu-toggle:hover, .menu-close:hover { --fond: rgb(23 20 43 / 92%); --bord: rgb(0 255 204 / 45%); color: #fff; }

  #sidebar .home-link:hover, #sidebar .category-link:hover, #sidebar summary:hover { color: #fff; }
  #sidebar .home-link:hover, #sidebar .category-link:hover, #sidebar details:hover { --fond: var(--fond-carte-survol); --bord: rgb(0 255 204 / 34%); }
  #sidebar .home-link[aria-current='page']:hover, #sidebar .category-link[aria-current='page']:hover { --fond: rgb(8 40 36 / 88%); --bord: rgb(0 255 204 / 60%); color: var(--menthe); }
  #sidebar .home-link:hover::after, #sidebar .category-link:hover::after, #sidebar details:hover::after { opacity: 1; transform: translateX(3px); }
  #sidebar details > a:hover { color: #fff; background: rgb(196 186 255 / 10%); }
  #sidebar details > a:hover::before { transform: none; opacity: 1; background: var(--menthe); }
  #sidebar details > a[aria-current='page']:hover { color: var(--menthe); background: rgb(0 255 204 / 10%); }
  #sidebar .play-link:hover { --fond: var(--menthe); --bord: var(--menthe); color: #04120c; filter: drop-shadow(0 0 12px rgb(0 255 204 / 45%)); }

  .news-item:hover, .mode-card:hover, .product-card:hover { --fond: var(--fond-carte-survol); --bord: rgb(0 255 204 / 40%); }
  .news-item:hover::after, .mode-card:hover::after, .product-card:hover::after { opacity: 1; box-shadow: 0 0 14px rgb(0 255 204 / 55%); }
  .news-item:hover h3 a, .mode-card:hover h2 { color: #fff; }
  .news-item:hover .text-link .icon, .button:hover .icon { transform: translateX(5px); }
  .news-item:hover .text-link { --bord: var(--cyan); color: #fff; }

  .text-link:hover, .breadcrumbs:hover, .mode-switch a:hover { --fond: rgb(8 30 40 / 90%); --bord: var(--cyan); color: #fff; }
  .breadcrumbs:hover::after { transform: translateX(-3px) rotate(45deg); }

  .button:hover { color: #04120c; filter: brightness(1.1) drop-shadow(0 0 12px rgb(0 255 204 / 45%)); }
  .button.secondary:hover { --fond: rgb(8 30 40 / 90%); --bord: var(--cyan); color: #fff; filter: none; }
  .button:disabled:hover { --fond: var(--nuit-3); color: var(--c-discret); filter: none; }

  .prose a:hover { color: #fff; text-decoration-color: #fff; }
  .faq summary:hover { color: #fff; }
  .site-footer nav a:hover { color: #fff; text-decoration: underline; }
}

/* ---------- 11 bis. Appui (doigt posé : le panneau réagit comme au survol, le survol n'existant pas au toucher) ---------- */
.news-item:active, .mode-card:active, .product-card:active { --fond: var(--fond-carte-survol); --bord: rgb(0 255 204 / 40%); }
.news-item:active::after, .mode-card:active::after, .product-card:active::after { opacity: 1; }
.site-footer nav a:active { color: #fff; }
.footer-brand:active, .brand:active { opacity: .8; }
.faq summary:active { color: #fff; }

/* ---------- 12. Pied de page ---------- */
.site-footer {
  position: relative; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 32px;
  padding: 12px max(24px, calc((100vw - 1680px) / 2 + 40px));
  background: rgb(7 6 14 / 88%);
  font-size: var(--t-petit);
}
.site-footer::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--trait-fort) 20%, var(--trait-fort) 80%, transparent);
}
.footer-brand { display: inline-flex; align-items: center; min-height: 44px; font-size: 20px; text-decoration: none; }
.footer-brand .wm-t, .footer-brand .wm-o { animation: none; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 0 28px; margin-left: auto; }
.site-footer nav a { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; color: var(--c-discret); font-weight: 500; letter-spacing: .02em; text-decoration: none; }

/* ---------- 13. Apparition des cartes au défilement ----------
   portal.js ne marque « a-venir » que les cartes situées sous le premier écran ; celles déjà visibles
   ne bougent pas. Sans script, ou avec le mouvement réduit, rien n'est jamais masqué. */
.a-venir { opacity: 0; transform: translateY(18px); }
.a-venir.vue { opacity: 1; transform: none; transition: opacity .5s ease-out, transform .6s var(--detente); }
.a-venir.vue:nth-child(3n + 2) { transition-delay: .06s; }
.a-venir.vue:nth-child(3n) { transition-delay: .12s; }

/* ---------- 14. Transitions entre pages (View Transitions inter-documents, déclarées en CSS) ----------
   L'en-tête et la colonne restent en place, seul le contenu change : comme dans un menu de jeu.
   Navigateurs sans prise en charge : changement de page ordinaire. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: entete; }
  #contenu { view-transition-name: contenu; }
  ::view-transition-old(contenu) { animation: vt-sortie .14s ease-in both; }
  ::view-transition-new(contenu) { animation: vt-entree .34s var(--detente) both; }
  ::view-transition-group(contenu), ::view-transition-group(colonne) { animation-duration: .3s; animation-timing-function: var(--detente); }
}
@keyframes vt-sortie { to { opacity: 0; transform: translateY(-8px); } }
@keyframes vt-entree { from { opacity: 0; transform: translateY(14px); } }
@keyframes tiroir { from { opacity: 0; transform: translateY(-10px); } }

/* ---------- 15. Écrans intermédiaires ---------- */
@media (min-width: 761px) {
  /* La marge négative laisse la place aux anneaux de focus et aux lueurs dans la colonne défilante. */
  #sidebar { position: sticky; top: 112px; max-height: calc(100svh - 136px); margin: -8px; padding: 8px; overflow-y: auto; scrollbar-width: thin; }
  .news-item { grid-template-columns: 9.5rem minmax(0, 1fr); column-gap: 24px; }
  .news-item > time { margin-top: 1px; }
}
@media (min-width: 761px) and (prefers-reduced-motion: no-preference) {
  #sidebar { view-transition-name: colonne; }
}
@media (max-width: 1100px) and (min-width: 761px) {
  .layout { grid-template-columns: 236px minmax(0, 1fr); padding-inline: 24px; gap: 22px; }
  .news-item { grid-template-columns: minmax(0, 1fr); }
}

/* Paysage de téléphone (largeur assez grande pour la colonne, hauteur courte) : en-tête et colonne resserrés
   pour que les cinq entrées tiennent à l'écran sans défiler dans la colonne. Cibles gardées à 44 px. */
@media (min-width: 761px) and (max-height: 520px) {
  html { scroll-padding-top: 76px; }
  .site-header { min-height: 60px; padding-block: 6px; }
  .brand { font-size: 30px; }
  .layout { padding-top: 14px; }
  #sidebar { --h-ligne: 44px; top: 72px; max-height: calc(100svh - 84px); }
  #sidebar nav { gap: 6px; }
  #sidebar .home-link, #sidebar summary, #sidebar .category-link { padding-block: 4px; }
  #sidebar .play-link { margin-top: 10px; padding-block: 4px; }
}

/* ---------- 16. Mobile : même interface, adaptée ----------
   Le complémentaire EXACT de `(min-width: 761px)` (sections 15) : `(max-width: 760px)` laissait sans règle les largeurs
   fractionnaires entre 760 et 761 px (zoom du navigateur). Le seuil lu par portal.js est ce même `(min-width: 761px)`. */
@media not all and (min-width: 761px) {
  html { scroll-padding-top: 76px; }
  .arene-fond video { left: 50%; opacity: .95; }
  .arene-voile {
    background:
      repeating-linear-gradient(0deg, rgb(7 6 14 / 14%) 0 1px, transparent 1px 3px),
      linear-gradient(180deg, rgb(7 6 14 / 26%) 0%, rgb(7 6 14 / 4%) 26%, rgb(7 6 14 / 8%) 66%, rgb(7 6 14 / 50%) 100%);
  }
  #aurore {
    background:
      radial-gradient(90% 34% at 0% 100%, rgb(164 130 255 / 18%), transparent 72%),
      radial-gradient(80% 30% at 100% 100%, rgb(61 255 182 / 13%), transparent 72%),
      radial-gradient(70% 22% at 50% 0%, rgb(34 211 255 / 10%), transparent 72%);
  }

  /* En-tête : titre centré, pause et Menu côte à côte à droite, en pictogrammes de 44 px.
     Leurs libellés restent dans la page pour les lecteurs d'écran. */
  .site-header { min-height: 60px; padding: 8px 10px; column-gap: 6px; }
  .pause-label, .menu-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .animation-toggle, .menu-toggle { width: 44px; padding: 0; }
  .menu-toggle, .menu-close { display: inline-flex; }
  .menu-toggle { color: var(--menthe); }

  .layout { display: block; padding: 16px 14px 56px; }
  #contenu { min-height: 60svh; gap: 14px; }
  .journal, .article-list, .content-pad, .editorial { gap: 14px; }

  /* Menu ouvrable : mêmes catégories que la colonne du PC */
  #sidebar {
    --h-ligne: 60px;
    display: none; position: fixed; inset: 0; z-index: 100;
    padding: 8px 12px 40px; overflow-y: auto; overscroll-behavior: contain;
    /* Opaque : rien de la page ne doit transparaître sous les libellés. Les teintes sont celles du fond de repli du menu du jeu. */
    background:
      radial-gradient(90% 40% at 0% 100%, rgb(162 131 255 / 20%), transparent 72%),
      radial-gradient(80% 34% at 100% 0%, rgb(61 255 180 / 12%), transparent 72%),
      var(--nuit);
  }
  body.menu-open { overflow: hidden; }
  body.menu-open #sidebar { display: block; animation: tiroir .26s var(--detente) both; }
  .menu-close { float: right; padding: 0 14px; color: var(--menthe); }
  #sidebar .drawer-brand {
    display: inline-flex; align-items: center; min-height: 44px; margin-left: 4px;
    color: #fff; font: 900 22px/1 var(--titres); letter-spacing: -.035em;
  }
  #sidebar .drawer-brand span { color: var(--menthe); }
  #sidebar nav { clear: both; padding-top: 20px; }
  #sidebar .home-link, #sidebar summary, #sidebar .category-link { font-size: 14px; }
  #sidebar details > a { min-height: 48px; font-size: 17px; }
  #sidebar .play-link { font-size: 13.5px; }

  .product-detail, .platform-grid { grid-template-columns: minmax(0, 1fr); }
  .product-detail > .diamond svg { width: min(100%, 180px); }
  .price-block.big .price-final { font-size: 34px; }
  .purchase-panel > .button { width: 100%; }
  .discord-page { padding-block: 30px; }
  .site-footer { padding: 14px 16px 20px; }
  .site-footer nav { margin-left: 0; width: 100%; }
}

/* ---------- 17. Mouvement réduit ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
  .wm-t, .wm-o { animation: none; }
  .a-venir { opacity: 1; transform: none; }
}
