/* BloxMasters : fichier assemblé par ops/scripts/bloxmasters/build_front.mjs, ne pas modifier à la main (sources dans src/css). */

/* ===== css/tokens.css ===== */
/* BloxMasters - jetons de la refonte (cahier docs/BLOXMASTERS_DESIGN.md, sections 3.1 à 3.5).

   Tous les jetons vivent sur body.bx et non sur :root : site_menu.css redéfinit :root{--accent:...}
   (orange d'Halloween), et une variable posée sur body gagne pour tout ce qui est dedans, quel que
   soit l'ordre des feuilles. Aucune autre teinte que celles-ci dans le jeu (cahier 9.1). */

/* Archivo hébergée sur le site (copie de styles/raids/fonts.css). Police variable 400 à 800.
   U+202F est volontairement HORS de la plage latin : l'Archivo hébergée la dessine à 0,09 em.
   Les chiffres du jeu utilisent donc U+00A0 comme séparateur (BM.fmt). */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url(/assets/fonts/archivo/archivo-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url(/assets/fonts/archivo/archivo-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-202E, U+2030-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Archivo 900 (titres de page, gros chiffres) et JetBrains Mono (500, 700) viennent de Google Fonts
   (lien du <head>), comme sur l'accueil et Onyx. La face 900 de Google complète l'Archivo hébergée
   (400 à 800) sans la recouvrir. Google ne sert pas « Archivo Expanded » : la demander ne chargeait
   rien et les titres en 900 retombaient sur l'Archivo 800. */

body.bx {
  /* Surfaces : bffr/style.css:9-25 et styles/raids/ds.css:25-67 */
  --bg: #070709;
  --bg-2: #0e0e14;
  --card: #101019;
  --card-2: #16161f;
  --panel-grad: linear-gradient(165deg, #12121a, #0c0c12);
  --line: rgba(255, 255, 255, .08);
  --line-2: rgba(255, 255, 255, .14);
  --scrim: rgba(4, 4, 7, .72);

  /* Textes */
  --ink: #f2f2f6;
  --ink-2: #cdd2e0;     /* texte secondaire lisible */
  --ink-3: #9c9cab;     /* libellés, métadonnées : minimum pour un texte de 13 px */
  --ink-4: #7e7e8b;     /* seulement 15 px et plus, ou texte non essentiel */

  /* Accent unique */
  --accent: #a78bff;
  --accent-2: #c3b0ff;
  --accent-deep: #6c4df0;
  --accent-rgb: 167, 139, 255;
  --accent-dim: rgba(167, 139, 255, .12);
  --accent-line: rgba(167, 139, 255, .38);
  --on-accent: #0b0b10;

  /* Discord : actions Discord seulement */
  --discord: #5865f2;
  --discord-rgb: 88, 101, 242;

  /* États */
  --ok: #3be08a;  --ok-dim: rgba(59, 224, 138, .12);  --ok-line: rgba(59, 224, 138, .4);
  --bad: #ff7676; --bad-dim: rgba(255, 118, 118, .12); --bad-line: rgba(255, 118, 118, .42);
  --warn: #ffb020; --warn-dim: rgba(255, 176, 32, .12); --warn-line: rgba(255, 176, 32, .42);

  /* Médailles (ds.css) */
  --medal-or: #f4c542; --medal-ar: #c9d1dc; --medal-br: #d98a4e;

  /* Raretés : couleurs du jeu, variante sombre pour les cadres, forme rgb */
  --r1: #aeb4bb; --r1-2: #5d636a; --r1-rgb: 174, 180, 187;   /* Commun */
  --r2: #4fc8df; --r2-2: #1f6f7e; --r2-rgb: 79, 200, 223;    /* Peu commun */
  --r3: #8f63ff; --r3-2: #4a2fa0; --r3-rgb: 143, 99, 255;    /* Rare */
  --r4: #d52be4; --r4-2: #74137d; --r4-rgb: 213, 43, 228;    /* Légendaire */
  --r5: #ee2f32; --r5-2: #82151a; --r5-rgb: 238, 47, 50;     /* Mythique */
  --r6: #f2c14e; --r6-2: #8a6516; --r6-rgb: 242, 193, 78;    /* Divin */
  /* Chromatique (demande de ratox du 09/10 : « un chromatique en rainbow, clean ») : le spectre entier en couleurs
     franches, du rouge au rose, pour le liseré de la carte, la pastille et le cadre du sachet ; le même en cercle
     pour les points irisés. Seul arc-en-ciel permis par le cahier (§5.5, §13). */
  --chroma: linear-gradient(135deg, #ff4d4d 0%, #ff9f2e 15%, #ffe04a 30%, #3fe08a 45%, #29c8f2 60%, #4f76ff 75%, #b45cff 88%, #ff5aa8 100%);
  --chroma-ring: conic-gradient(from 225deg, #ff4d4d, #ff9f2e, #ffe04a, #3fe08a, #29c8f2, #4f76ff, #b45cff, #ff5aa8, #ff4d4d);

  /* Polices */
  --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --display: 'Archivo', system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', monospace;

  /* Formes */
  --r-s: 11px; --r-m: 14px; --r-l: 18px; --r-xl: 22px;
  --shadow-card: 0 14px 34px -14px rgba(0, 0, 0, .75);
  --shadow-pop: 0 24px 60px -24px rgba(0, 0, 0, .8);
  --hl: inset 0 1px 0 rgba(255, 255, 255, .035);
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-out: cubic-bezier(.16, .84, .2, 1);

  /* Mise en page */
  --head-h: 64px;
  --maxw: 1240px;
  --maxw-wide: 1480px;
  --gutter: clamp(16px, 3vw, 32px);

  /* Couches (cahier 3.1). Le décor saisonnier (60) et le tiroir du menu commun (125, bouton 130)
     sont posés par les feuilles du site : ces valeurs les entourent. */
  --z-head: 70;
  --z-drop: 75;
  --z-selbar: 80;
  --z-fab: 90;
  --z-scene: 140;
  --z-modal: 150;
  --z-toast: 160;

  margin: 0; min-height: 100vh;
  background: var(--bg); color: var(--ink);
  font: 400 15px/1.55 var(--font);
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
  color-scheme: dark;
}
/* Thème saisonnier : le fond reste noir, comme sur l'accueil et Onyx dont les sections peignent --bg
   sur toute la largeur. theme.css repeint html et body en nuit de saison, en !important (spécificité
   0,1,1 et 0,1,2) : ces deux règles passent devant (0,2,2). Le logo, la bannière et les toiles de
   saison restent (cahier 2.8). #070709 = --bg, posé en dur car html ne voit pas les jetons de body.bx. */
html[data-theme]:has(> body.bx) { background: #070709 !important; }
html[data-theme] body.bx { background: var(--bg) !important; }
/* Le tiroir du menu commun lit --ink-2 / --ink-3 avec le sens de la famille « new » (bffr/style.css:9-25) :
   on lui rend ses valeurs pour qu'il soit identique à celui de l'accueil. */
body.bx .navmenu, body.bx .navtoggle { --ink-2: #9C9CAB; --ink-3: #80808E; }
body.bx ::selection { background: rgba(167, 139, 255, .35); }
body.bx :focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }


/* ===== css/shell.css ===== */
/* BloxMasters - coquille : base, en-tête, menu du jeu sur téléphone, conteneur des vues, pied de page,
   bouton flottant, thème saisonnier, états de chargement, d'erreur et de jeu fermé.
   Cahier docs/BLOXMASTERS_DESIGN.md, sections 2 et 3.4 à 3.5. Les composants réutilisables (boutons,
   panneaux, listes...) sont dans components.css. */

/* ── 1. Base ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: 76px; scrollbar-color: #2b2b38 transparent; }
[hidden] { display: none !important; }
/* :where() = spécificité nulle : la moindre classe d'un composant ou d'une page passe devant. */
:where(body.bx) img, :where(body.bx) svg { max-width: 100%; }
:where(body.bx) img { vertical-align: middle; }
:where(body.bx) a { color: inherit; }
:where(body.bx) button, :where(body.bx) input, :where(body.bx) select, :where(body.bx) textarea { font: inherit; color: inherit; }
:where(body.bx) button { cursor: pointer; }
:where(body.bx) p, :where(body.bx) h1, :where(body.bx) h2, :where(body.bx) h3, :where(body.bx) h4, :where(body.bx) figure { margin: 0; }
/* Échelle typographique (cahier 3.3) : h2 = titre de section, h3 = titre de bloc. */
:where(body.bx) h1 { font: 900 clamp(1.75rem, 1.1rem + 2.4vw, 2.9rem)/.95 var(--display); letter-spacing: -.025em; }
:where(body.bx) h2 { font: 800 clamp(1.15rem, 1rem + .8vw, 1.5rem)/1.1 var(--display); letter-spacing: -.02em; color: var(--ink); }
:where(body.bx) h3 { font: 700 1.06rem/1.25 var(--font); letter-spacing: -.005em; color: var(--ink); }
:where(body.bx) h4 { font: 700 15px/1.3 var(--font); }
:where(body.bx) b, :where(body.bx) strong { font-weight: 700; }
body.bx.is-locked { overflow: hidden; }

.bx-skip { position: absolute; left: 12px; top: -60px; z-index: 200; padding: 10px 16px; border-radius: 999px;
  background: var(--accent); color: var(--on-accent); font: 800 14px/1 var(--font); text-decoration: none; transition: top .15s; }
.bx-skip:focus { top: 12px; }
.bx-noscript { margin: 40px auto; max-width: 560px; padding: 0 16px; text-align: center; color: var(--ink-2); }

/* ── 2. En-tête (cahier 2.3) ───────────────────────────────────────────────── */
body.bx .bx-head {
  position: sticky; top: 0; z-index: 70;            /* au-dessus du décor saisonnier (60) */
  display: flex; align-items: center; gap: 10px;
  min-height: var(--head-h); padding: 8px 82px 8px var(--gutter);   /* 82 px : place du bouton du menu commun */
  background: rgba(7, 7, 9, .86);
  -webkit-backdrop-filter: saturate(140%) blur(14px); backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid var(--line);
}
body.bx .navtoggle:not(.open) { top: calc((var(--head-h) - 46px) / 2); right: clamp(14px, 2.4vw, 28px); }
body.bx .navtoggle, body.bx .navmenu button, body.bx .navmenu input { font-family: inherit; }
/* Champ « Chercher une page... » du tiroir : 16 px sur téléphone et tablette, comme tous les champs du jeu
   (cahier 4.6), sinon Safari iOS zoome. navmenu_v2.js injecte ses styles après les nôtres avec un sélecteur
   à identifiant (#navMenu .nv2-search input, 14 px) : il faut l'identifiant ici aussi. */
@media (max-width: 960px) { body.bx #navMenu .nv2-search input { font-size: 16px; } }

.bx-brand { display: inline-flex; align-items: center; gap: 11px; flex: 0 0 auto; padding: 4px 8px 4px 0; text-decoration: none; }
.bx-brand__logo { width: 36px; height: 36px; border-radius: 10px; box-shadow: 0 6px 20px rgba(0, 0, 0, .5); }
.bx-brand b { display: block; font: 800 15px/1 var(--font); letter-spacing: -.02em; color: #fff; }   /* 800 : l'Archivo hébergée s'arrête à 800 */
.bx-brand small { display: block; margin-top: 3px; font: 700 9px/1 var(--font); letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3); }

/* Navigation du jeu (PC) : texte seul, sans icône */
.bx-nav { display: flex; align-items: center; gap: 2px; flex: 1 1 auto; min-width: 0; margin-left: 10px; }
.bx-nav a, .bx-nav summary {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  height: 40px; padding: 0 12px; border-radius: 11px;
  color: var(--ink-3); font: 600 .9rem/1 var(--font); white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: color .15s, background-color .15s;
}
.bx-nav a:hover, .bx-nav summary:hover { color: var(--ink); background: rgba(255, 255, 255, .045); }
.bx-nav a[aria-current="page"] { color: var(--ink); background: var(--accent-dim); box-shadow: inset 0 -2px 0 var(--accent); }

/* Menu déroulant « Plus » (modèle .rgnav-menu, ds.css:169-191) */
.bx-nav__more { position: relative; }
.bx-nav__more > summary { list-style: none; -webkit-user-select: none; user-select: none; }
.bx-nav__more > summary::-webkit-details-marker { display: none; }
.bx-nav .bx-nav__car { width: 12px; height: 12px; opacity: .55; transition: transform .2s; }
.bx-nav__more[open] > summary { color: var(--ink); background: rgba(255, 255, 255, .06); }
.bx-nav__more[open] .bx-nav__car { transform: rotate(180deg); }
.bx-nav__more.has-current > summary { color: var(--ink); background: var(--accent-dim); box-shadow: inset 0 -2px 0 var(--accent); }
.bx-nav__menu {
  position: absolute; top: calc(100% + 10px); left: 0; z-index: 75;
  display: flex; flex-direction: column; gap: 2px; min-width: 240px; padding: 8px;
  background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-l);
  box-shadow: var(--shadow-pop), var(--hl);
  animation: bx-pop .16s var(--ease);
}
.bx-nav__menu a { display: flex; width: 100%; height: 40px; padding: 0 12px; border-radius: 12px; color: var(--ink-2); font-weight: 650; }
.bx-nav__menu a:hover { color: var(--ink); background: var(--card-2); }
.bx-nav__menu a[aria-current="page"] { color: var(--accent-2); background: var(--accent-dim); box-shadow: none; }
.bx-nav__menu a .bx-badge { margin-left: auto; }

/* Fin de l'en-tête : pièces, cloche, avatar (cahier 2.3, 2.5) */
.bx-head__end { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; margin-left: auto; }
.bx-head__end .bx-skel--ava { flex: 0 0 36px; }
a.bx-coin { transition: border-color .15s, background-color .15s; }
a.bx-coin:hover { border-color: var(--line-2); background: rgba(255, 255, 255, .07); }

@media (max-width: 1180px) and (min-width: 961px) {
  .bx-head__end .bx-coin--onyx { display: none; }   /* le solde Onyx reste dans le menu du compte */
  .bx-nav a, .bx-nav summary { padding: 0 9px; }
}

/* Téléphone (960 px et moins) : en-tête dans le flux, sans flou. relative et non static : il reste dans
   le flux mais garde son z-index 70, sinon le décor de saison (60) se dessine par-dessus. */
@media (max-width: 960px) {
  .bx-nav { display: none; }
  body.bx .bx-head { position: relative; -webkit-backdrop-filter: none; backdrop-filter: none; background: #09090c; min-height: 56px; padding: 8px 70px 8px 14px; }
  body.bx #navToggle, body.bx .navtoggle:not(.open) { position: absolute; top: 6px; right: 14px; width: 44px; height: 44px; }
  .bx-brand { padding-top: 0; padding-bottom: 0; min-height: 40px; }   /* 56 px tout compris : le bouton du menu commun (44 px à 6 px du haut) reste centré */
  .bx-head__end { margin-left: auto; }
  .bx-head__end .bx-coin--onyx { display: none; }   /* components.css vient après : il faut la classe parente */
  /* Cibles tactiles de 40 px (cahier 9.2), comme .bx-btn--sm et .bx-chip sous 960 px. */
  .bx-head__end .bx-coin { height: 40px; }
  .bx-head__end .bx-avabtn { width: 40px; height: 40px; flex-basis: 40px; }
}
/* Petit téléphone. Joueur : le logo seul, pour laisser la place au solde de Beli, à la cloche et à
   l'avatar. Visiteur : la marque reste, le bouton devient « Se connecter ». */
@media (max-width: 480px) {
  body.bx.is-player .bx-brand { gap: 0; padding-right: 0; min-width: 40px; }
  body.bx.is-player .bx-brand > span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .bx-head__end .bx-hide-sm { display: none; }
  .bx-head__end .bx-coin { padding: 0 11px; }
}

/* Menu du compte et notifications (cahier 2.5) : panneaux .bx-pop de components.css */
.bx-notifs .bx-row { align-items: flex-start; min-height: 0; }
.bx-notifs .bx-row__meta { white-space: normal; overflow: visible; margin-top: 2px; line-height: 1.4; }
.bx-notifs .bx-row__title { white-space: normal; }
.bx-notifs .bx-empty { padding: 28px 12px; }

/* ── 3. Menu du jeu sur téléphone (cahier 2.4, modèle .rgmnav) ─────────────── */
.bx-mnav { display: none; }
@media (max-width: 960px) {
  .bx-mnav { position: relative; z-index: 70; display: block; margin: 10px 14px 0; background: var(--card); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--hl); }
  .bx-mnav > summary { display: flex; align-items: center; gap: 10px; min-height: 50px; padding: 0 14px; list-style: none; color: var(--ink); font: 700 .95rem/1 var(--font); cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .bx-mnav > summary::-webkit-details-marker { display: none; }
  .bx-mnav .bx-mnav__ic { width: 20px; height: 20px; flex: 0 0 20px; color: var(--accent-2); }
  .bx-mnav__cur { color: var(--ink-3); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .bx-mnav .bx-mnav__car { width: 16px; height: 16px; flex: 0 0 16px; margin-left: auto; opacity: .6; transition: transform .2s; }
  .bx-mnav[open] > summary { border-bottom: 1px solid var(--line); }
  .bx-mnav[open] .bx-mnav__car { transform: rotate(180deg); }
  .bx-mnav__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding: 10px; }
  .bx-mnav__grid a { position: relative; display: flex; align-items: center; justify-content: center; min-height: 48px; padding: 6px; border-radius: 13px; background: var(--bg-2); border: 1px solid var(--line); color: var(--ink-2); font: 650 .84rem/1.15 var(--font); text-align: center; text-decoration: none; }
  .bx-mnav__grid a[aria-current="page"] { color: var(--ink); background: var(--accent-dim); border-color: var(--accent-line); }
  .bx-mnav__grid a .bx-badge { position: absolute; top: -6px; right: -4px; }
}

/* ── 4. Conteneur des vues (cahier 3.4, 3.5) ───────────────────────────────── */
.bx-main { display: block; min-height: 52vh; max-width: var(--maxw); margin: 0 auto; padding: 28px var(--gutter) 24px; }
.bx-main.is-wide { max-width: var(--maxw-wide); }
.bx-main.is-bleed { max-width: none; padding: 0; }
/* Le contenu passe devant le décor de saison (60) : titres, liens et boutons ne sont plus barrés par les
   toiles, qui restent visibles dans les marges (main n'a pas de fond). La vitrine (is-bleed) garde les
   toiles sur sa bannière, comme l'accueil du site. Fenêtres, menus et toasts sont ajoutés au body. */
body.bx .bx-main:not(.is-bleed) { position: relative; z-index: 61; }
body.bx .bx-main:focus, body.bx .bx-main:focus-visible,
body.bx .bx-modal__box:focus-visible, body.bx .bx-pop:focus-visible { outline: none; }   /* conteneurs focalisés par le script, pas des commandes */
@media (max-width: 960px) { .bx-main { padding-top: 18px; } .bx-main.is-bleed { padding-top: 0; } }
.bx-wrap { max-width: 1280px; margin: 0 auto; padding: 0 var(--gutter); }

/* Entrée de vue : backwards (et non both) pour qu'aucune transformation ne reste sur les enfants.
   Le routeur pose .is-settled une fois la vue affichée : un nouveau rendu de la même page ne rejoue pas l'entrée. */
.bx-main > * { animation: bx-in .32s var(--ease) backwards; }
.bx-main.is-settled > * { animation: none; }
@keyframes bx-in { from { opacity: 0; transform: translateY(6px); } }
@keyframes bx-pop { from { opacity: 0; transform: translateY(-4px); } }

/* Squelette de chargement d'une vue (BM.skelHtml) : il n'apparaît qu'après 150 ms, une vue rapide ne clignote pas. */
.bx-main > .bx-skelpage { animation: bx-fade .2s ease-out .15s backwards; }
.bx-skelpage { display: grid; gap: 14px; }
.bx-skelpage__ph { display: grid; gap: 12px; margin: 6px 0 8px; }
.bx-skelpage__facts { display: flex; gap: 8px; }

/* ── 5. Pied de page (cahier 2.7) ──────────────────────────────────────────── */
.bx-foot { border-top: 1px solid var(--line); padding: 34px 0 48px; margin-top: 56px; }
.bx-foot.has-fab { padding-bottom: 110px; }
/* Le pied de page s'aligne sur le conteneur de la vue, comme sur /raid : 1240 px sur une page de jeu,
   1480 px sur une page large (album, duel, nouvel échange). La vitrine (is-bleed) garde les 1280 px de
   ses sections. Les deux règles ont la même spécificité : la seconde l'emporte pour une page large. */
body.bx:has(> .bx-main:not(.is-bleed)) .bx-foot > .bx-wrap { max-width: var(--maxw); }
body.bx:has(> .bx-main.is-wide) .bx-foot > .bx-wrap { max-width: var(--maxw-wide); }
.bx-foot__top { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 26px; }
.bx-foot__brand { display: inline-flex; align-items: center; gap: 10px; min-height: 40px; text-decoration: none; }
.bx-foot__brand img { width: 32px; height: 32px; border-radius: 9px; }
.bx-foot__brand b { font: 800 .98rem/1 var(--font); color: var(--ink); }
.bx-foot__links { display: flex; flex-wrap: wrap; gap: 6px 18px; }
/* Cible de 40 x 40 au moins (cahier 9.2), « CGV » et « Onyx » compris : 6 px de marge intérieure de chaque
   côté, repris par une marge négative, élargissent la zone cliquable sans déplacer le texte. */
.bx-foot__links a, .bx-foot__legal a { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; min-height: 40px; margin: 0 -6px; padding: 0 6px;
  color: var(--ink-3); font-size: .84rem; font-weight: 600; text-decoration: none; }
.bx-foot__links a:hover, .bx-foot__legal a:hover { color: var(--ink); }
.bx-foot__legal { display: flex; flex-wrap: wrap; align-items: center; gap: 0 18px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.bx-foot__legal span { color: var(--ink-3); font-size: .8125rem; }
.bx-foot__copy { max-width: 780px; margin: 12px 0 0; color: var(--ink-3); font-size: .8125rem; line-height: 1.6; }

/* ── 6. Bouton flottant « Rejoindre », visiteur sur la vitrine seulement (cahier 2.6) ── */
.bx-fab { position: fixed; right: 20px; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); z-index: 90;
  display: inline-flex; align-items: center; gap: 9px; min-height: 46px; padding: 0 18px; border-radius: 999px;
  background: var(--discord); color: #fff; font: 750 .9rem/1 var(--font); text-decoration: none;
  box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .8); transition: opacity .2s ease, transform .2s var(--ease), visibility 0s; }
@media (hover: hover) { .bx-fab:hover { transform: translateY(-2px); } }
.bx-fab svg { width: 20px; height: 20px; flex: 0 0 20px; }
/* Effacé tant qu'un bouton Discord de la vitrine est à l'écran (main.js, watchFab) : invisible, ni cliquable
   ni atteignable au clavier une fois le fondu terminé. */
.bx-fab.is-away { opacity: 0; transform: translateY(16px); pointer-events: none; visibility: hidden;
  transition: opacity .2s ease, transform .2s var(--ease), visibility 0s linear .2s; }
@media (max-width: 600px) { .bx-fab { width: 48px; min-height: 48px; padding: 0; justify-content: center; } .bx-fab span { display: none; } }

/* ── 7. Thème saisonnier (cahier 2.8) : logo, bannière, place du décor du site ── */
html[data-theme="halloween"] .bx-brand__logo,
html[data-theme="halloween"] .bx-foot__brand img { content: url('/img/halloween/logo_halloween_96.png'); }
html[data-theme="noel"] .bx-brand__logo,
html[data-theme="noel"] .bx-foot__brand img { content: url('/img/noel/logo_noel_96.png'); }
.bx-hero__bg, .bx-final__bg { background-image: url('/bffr/assets/hero-banner.webp'); }
html[data-theme="halloween"] .bx-hero__bg, html[data-theme="halloween"] .bx-final__bg { background-image: url('/img/halloween/banniere_halloween.jpg'); }
html[data-theme="noel"] .bx-hero__bg, html[data-theme="noel"] .bx-final__bg { background-image: url('/img/noel/banniere_noel.jpg'); }

/* Décor de saison du site (#bffr-theme-deco, posé par theme.js : toiles ou givre .bffr-deco-a et -b,
   araignée -c, z-index 60). theme.css le colle en haut du document en 200 px : sous l'en-tête collant,
   il traversait le titre et le lien de retour, et l'araignée était coupée par le bas de l'en-tête.
   Ici il part du bas de l'en-tête et ne prend que la marge laissée à gauche et à droite du contenu
   (--deco-w : marge moins 16 px, entre 64 et 120 px). html[data-theme] en tête de sélecteur : theme.css
   est ajouté après nos feuilles et passerait devant à spécificité égale. */
html[data-theme] body.bx #bffr-theme-deco {
  --deco-max: var(--maxw);
  --deco-w: clamp(64px, (100vw - var(--deco-max)) / 2 + var(--gutter) - 16px, 120px);
  top: var(--head-h);
}
html[data-theme] body.bx:has(> .bx-main.is-wide) #bffr-theme-deco { --deco-max: var(--maxw-wide); }
html[data-theme] body.bx:has(> .bx-main.is-bleed) #bffr-theme-deco { --deco-max: 1280px; }   /* .bx-wrap des sections de la vitrine */
html[data-theme] body.bx #bffr-theme-deco .bffr-deco-a,
html[data-theme] body.bx #bffr-theme-deco .bffr-deco-b { width: var(--deco-w); }
html[data-theme] body.bx #bffr-theme-deco .bffr-deco-c { left: calc(var(--deco-w) * .42 - 17px); }   /* suspendue dans la toile de gauche */
/* Marge trop étroite pour une toile entière (page large sous 1576 px, page de jeu sous 1336 px, vitrine
   sous 1024 px, où son texte remonte en haut de la bannière) : la toile de 64 px empiète d'une trentaine de
   pixels au plus sur le contenu. Elle s'efface à 30 % pour que ses fils ne se lisent plus sur le titre,
   et l'araignée se retire. */
@media (min-width: 961px) and (max-width: 1575px) {
  html[data-theme] body.bx:has(> .bx-main.is-wide) #bffr-theme-deco :is(.bffr-deco-a, .bffr-deco-b) { opacity: .3; }
  html[data-theme] body.bx:has(> .bx-main.is-wide) #bffr-theme-deco .bffr-deco-c { display: none; }
}
@media (min-width: 961px) and (max-width: 1335px) {
  html[data-theme] body.bx:has(> .bx-main:not(.is-bleed)) #bffr-theme-deco :is(.bffr-deco-a, .bffr-deco-b) { opacity: .3; }
  html[data-theme] body.bx:has(> .bx-main:not(.is-bleed)) #bffr-theme-deco .bffr-deco-c { display: none; }
}
@media (min-width: 961px) and (max-width: 1023px) {
  html[data-theme] body.bx #bffr-theme-deco :is(.bffr-deco-a, .bffr-deco-b) { opacity: .3; }
  html[data-theme] body.bx #bffr-theme-deco .bffr-deco-c { display: none; }
}
/* Téléphone et tablette : 14 à 16 px de marge, et le menu du jeu juste sous l'en-tête. Une toile ne peut
   y tenir sans passer sous le titre ou le lien de retour : la saison se lit au logo et à la bannière. */
@media (max-width: 960px) {
  html[data-theme] body.bx #bffr-theme-deco > div { display: none; }
}

/* ── 8. Jeu fermé (cahier 2.9) ─────────────────────────────────────────────── */
.bx-closed { display: grid; justify-items: center; gap: 14px; max-width: 560px; margin: clamp(24px, 8vh, 80px) auto 0; padding: 36px 28px 32px; text-align: center; }
.bx-closed__art { width: 96px; height: 96px; object-fit: contain; }
.bx-closed .bx-h1 { margin-top: 4px; }
.bx-closed p { max-width: 440px; font-size: 15px; color: var(--ink-2); }
.bx-closed__act { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }
@media (max-width: 600px) { .bx-closed { padding: 28px 18px 24px; } .bx-closed__act .bx-btn { flex: 1 1 100%; } }

/* Page réservée aux joueurs : invitation à se connecter (remplace « Connecte-toi pour jouer ») */
.bx-gate { display: grid; justify-items: center; gap: 14px; max-width: 560px; margin: clamp(8px, 4vh, 40px) auto 0; padding: 30px 26px 28px; text-align: center; }
.bx-gate__fan { position: relative; width: 300px; max-width: 100%; height: 196px; margin-bottom: 6px; }
.bx-gate__fan > div { position: absolute; left: 50%; top: 10px; width: 128px; margin-left: -64px; }
.bx-gate__fan > div:nth-child(1) { transform: translate(-82px, 14px) rotate(-8deg); }
.bx-gate__fan > div:nth-child(3) { transform: translate(82px, 14px) rotate(8deg); }
.bx-gate__fan > div:nth-child(2) { z-index: 2; }
.bx-gate h2 { max-width: 420px; text-wrap: balance; }
.bx-gate p { color: var(--ink-3); font-size: 13px; }
.bx-gate__act { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 6px; }
@media (max-width: 600px) { .bx-gate { padding: 24px 16px 22px; } .bx-gate__fan { width: 260px; height: 172px; } .bx-gate__fan > div { width: 112px; margin-left: -56px; } .bx-gate__fan > div:nth-child(1) { transform: translate(-70px, 12px) rotate(-8deg); } .bx-gate__fan > div:nth-child(3) { transform: translate(70px, 12px) rotate(8deg); } }

/* ── 9. Mouvement réduit (cahier 3.5) : réglage système ET réglage du jeu ──── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
body.reduce-motion *, body.reduce-motion *::before, body.reduce-motion *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }


/* ===== css/components.css ===== */
/* BloxMasters - composants communs (cahier docs/BLOXMASTERS_DESIGN.md, section 4).
   Toutes les classes portent le préfixe bx- (bxc pour la carte, bxb pour le dos : card.css).

   ════════════════════════════════════════════════════════════════════════════
   SOMMAIRE DES CLASSES : une ligne d'usage chacune. Les pages n'inventent pas d'autre
   bouton, pastille, panneau ou liste : elles composent avec ce qui suit.
   ════════════════════════════════════════════════════════════════════════════
   TEXTE
   .bx-h1            titre de page en capitales (Archivo 900), un seul par vue
   h2 / h3           titre de section / de bloc : styles par défaut, aucune classe nécessaire
   .bx-intro         paragraphe d'introduction (1.05rem, --ink-2, 560 px max)
   .bx-small         petit texte 13 px --ink-3 (métadonnées, notes)
   .bx-micro         micro-libellé 11 px en capitales espacées (au-dessus d'un chiffre, d'un bloc)
   .bx-kicker        surtitre « // TEXTE » en accent, VITRINE SEULEMENT
   .hl               UN mot mis en avant dans un titre ou une phrase (couleur accent)
   .stroke           UNE ligne de titre en contour violet, VITRINE SEULEMENT
   .bx-num           chiffre en mono 700 à chasse fixe (« 1 818 »), toujours via BM.fmt
   .bx-time          minuterie en mono (BM.dur : « 2 h 05 », « 24 min » ; BM.clock : « 04:12 »)
   .bx-amt           montant + icône de monnaie dans une phrase (BM.beliHtml, BM.onyxHtml)
   .bx-link          lien d'action dans un texte (accent clair, gras)
   .bx-plink         lien vers un profil de joueur (BM.playerLink)
   .bx-back          lien de retour discret en tête de page (« Marché », « Toutes les guildes »), flèche BM.icon('back')
   .bx-sr            texte réservé aux lecteurs d'écran (invisible)
   BOUTONS (4.1)
   .bx-btn           bouton secondaire en pilule ; + .bx-btn--primary (UN par zone), --discord
                     (connexion / rejoindre seulement), --ghost, --danger, --lg, --sm, --icon (40 px carré)
   .bx-iconbtn       bouton rond de 40 px à icône seule (cloche, son, « ... ») ; accepte un .bx-badge
   .bx-avabtn        bouton avatar rond de 36 px ; accepte un .bx-badge
   PASTILLES ET CHIFFRES (4.2)
   .bx-pill          pastille d'information en capitales ; + --ok, --warn, --bad, --accent,
                     --chroma (« Chromatique » précédé du point irisé : <span class="bx-pill bx-pill--chroma"><i></i>Chromatique</span>)
   .bx-rar[data-r]   pastille de rareté hors carte : point + nom complet (à poser avec .bx-pill)
   .bx-badge         compteur rond accent (navigation, onglets, cloche)
   .bx-coin          pièce Beli / Onyx en pilule (BM.coinHtml) ; .bx-coin__ic--beli / --onyx = l'image ;
                     .bx-coin__plus = « + » de recharge après le montant (option plus de BM.coinHtml)
   .bx-fact, .bx-facts  puce « libellé <b>chiffre</b> » et leur rangée (remplacent les tuiles de chiffres) ;
                     <b class="is-text"> pour une date ou un mot (police du texte, pas la mono)
   .bx-big           gros chiffre seul (Archivo 900) ; <small> pour l'unité
   .bx-tagc[data-c]  couleur d'étiquette du joueur (slate, sea, leaf, sun, coral, rose, sand, ink) ;
                     .bx-tagdot = son point de couleur
   PANNEAUX ET SECTIONS (4.3)
   .bx-panel         panneau standard (dégradé, filet, liseré) ; + --flat, --feature (lueur accent en haut)
   .bx-pad           marge intérieure d'un panneau (22 px, 16 px sur téléphone)
   .bx-panel__head   en-tête de panneau (titre h3 + actions), filet dessous
   .bx-sec           titre de section h2 + filet qui s'efface ; .bx-sec__more = lien « Tout voir »
   .bx-ph            en-tête de page : .bx-h1 + .bx-ph__sub (faits) à gauche, .bx-ph__act (2 actions max) à droite
   .bx-how           lien « Comment ça marche » (ouvre BM.how)
   .bx-help          bouton « ? » après un mot du jeu (BM.helpBtn) : rond de 22 px, zone touchable de 40 px ;
                     ouvre sa définition (BM.HELP) au doigt comme à la souris, à la place d'une infobulle
   .bx-scene         en-tête illustré d'une page à sujet (Raid, Guilde, Profil) ; --rc-rgb teinte la lueur
   .bx-cols          deux colonnes égales (14 px d'écart), une seule sous 760 px
   .bx-stack         pile verticale (12 px d'écart)
   .bx-inline        rangée qui passe à la ligne (8 px d'écart), centrée verticalement
   .bx-grow          prend la place restante dans une rangée
   ONGLETS ET FILTRES (4.4)
   .bx-tabs          onglets en pilule segmentée (aria-selected ou aria-current sur l'actif) ;
                     + --grid (grille sur téléphone pour plus de 3 onglets) ; .bx-count = compteur mono
   .bx-chips         rangée de puces qui défile (BM.watchChips pose .is-overflow)
   .bx-chip          puce de filtre (aria-pressed="true" quand active) ; .bx-count = compteur mono
   LISTES (4.5)
   .bx-list          liste verticale (souvent dans un .bx-panel)
   .bx-row           ligne de liste 56 px : __rank, __main (__title, __meta), __num ; .is-me = la ligne du joueur
   .bx-ava           avatar Discord rond 32 px ; --sm 24 px, --md 44 px, --lg 96 px
   .bx-presence      enveloppe d'un .bx-ava ; .is-on ajoute le point vert « en ligne » (8 px, sans lueur)
   .bx-mini          miniature de carte dans une liste (BM.miniHtml) ; .bx-mini__vis = vignette 40 px teintée (BM.miniVisHtml)
   .bx-row__vis      vignette 36 px d'une ligne (illustration en cover ou pièce de monnaie : notifications) ;
                     .is-ava = avatar rond, .is-empty = place vide qui garde l'alignement des titres
   .bx-row__time     heure relative en mono 11 px, à droite d'une ligne
   .bx-menu          liste d'actions d'un menu (BM.menu, menu du compte) : .bx-row compactes de 44 px
   .bx-table         tableau d'administration (en-têtes en micro-libellé, chiffres en mono à droite)
   CHAMPS (4.6)
   .bx-field         libellé (span en micro-libellé) + champ
   .bx-input, .bx-select, .bx-textarea   champs (16 px sur téléphone : pas de zoom Safari)
   .bx-search        champ de recherche avec loupe (BM.icon('search') + .bx-input)
   .bx-stepper       saisie d'un montant : bouton moins, valeur, bouton plus
   .bx-switch        interrupteur (label > input[type=checkbox] + texte)
   FENÊTRES, MENUS, NOTIFICATIONS (4.8, 4.9)
   .bx-modal         fenêtre (BM.modal) ; feuille qui monte du bas sur téléphone ; __box (.is-wide), __head, __body, __foot
   .bx-modal__text   texte courant d'une fenêtre (15 px --ink-2)
   .bx-pop           panneau ancré sous un bouton (BM.popover, BM.menu, compte, notifications)
   .bx-toasts, .bx-toast   notifications passagères (BM.toast) ; .is-ok / .is-err colorent le filet
   BARRES ET JAUGES (4.10)
   .bx-bar           barre de progression 6 px (> i = remplissage) ; --warn
   .bx-hp            points de vie (BM.hpBar) : __txt (chiffre au-dessus, à droite) puis __bar (> i) ; .is-low sous 30 %, --lg
   .bx-stock         réserve de paquets, un segment par paquet (> i.is-full / .is-charging + --fill)
   ÉTATS (4.11)
   .bx-empty         état vide dessiné : rendu de fruit 72 px, <strong>, <p>, un seul bouton (BM.emptyHtml)
   .bx-skel          bloc de chargement qui scintille ; --ava (rond 36 px), --line, --title, --card, --row
   .bx-spin          petit indicateur de chargement tournant (dans un bouton ou une ligne)
   CARTES EN GRILLE (5.3)
   .bx-grid          grille de cartes (156 px minimum, 18 px d'écart ; 2 colonnes sur téléphone)
   .bx-cardbtn       carte cliquable dans une grille de choix (aria-pressed="true" = cochée)
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Texte (cahier 3.3) ────────────────────────────────────────────────────── */
.bx-h1 { margin: 0; font: 900 clamp(1.75rem, 1.1rem + 2.4vw, 2.9rem)/.95 var(--display); letter-spacing: -.025em; text-transform: uppercase; color: #fff; text-wrap: balance; }
.bx-intro { max-width: 560px; font: 400 1.05rem/1.6 var(--font); color: var(--ink-2); }
.bx-small { font: 500 13px/1.45 var(--font); color: var(--ink-3); }
.bx-micro { display: block; font: 800 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.bx-kicker { display: inline-block; font: 800 12px/1 var(--font); letter-spacing: .22em; text-transform: uppercase; color: var(--accent); }
.bx-kicker::before { content: '// '; }
.hl { color: var(--accent); }
.stroke { color: transparent; -webkit-text-stroke: 2px var(--accent); }
.bx-num { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; }
.bx-time { font: 700 1em/1 var(--mono); font-variant-numeric: tabular-nums; }
/* En chasse fixe, l'espace insécable des milliers est aussi large qu'un chiffre (« 17  245 ») :
   on la ramène à une espace fine dans tous les chiffres en mono. */
.bx-num, .bx-time, .bx-coin, .bx-fact b, .bx-row__num, .bx-row__rank, .bx-row__time, .bx-hp__txt, .bx-count, .bx-table .is-num, .bx-table td.bx-num, .bx-stepper input { word-spacing: -.32em; }
.bx-amt { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; vertical-align: -.12em; }
.bx-amt .bx-coin__ic--beli { width: .5em; height: 1em; }
.bx-amt .bx-coin__ic--onyx { width: 1.1em; height: 1.1em; }
.bx-link { color: var(--accent-2); font-weight: 700; text-decoration: none; }
.bx-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.bx-link svg { width: 15px; height: 15px; vertical-align: -2px; margin-left: 4px; }
.bx-plink { color: var(--ink); font-weight: 700; text-decoration: none; }
.bx-plink:hover { color: var(--accent-2); }
.bx-back { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; margin: -10px 0 6px -8px; padding: 0 12px 0 6px;
  border-radius: 999px; color: var(--ink-3); font: 700 13px/1 var(--font); text-decoration: none; transition: color .15s, background-color .15s; }
.bx-back:hover { color: var(--ink); background: rgba(255, 255, 255, .04); }
.bx-back svg { width: 16px; height: 16px; }
.bx-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.bx-ic { width: 1.15em; height: 1.15em; flex-shrink: 0; vertical-align: -.2em; }

/* ── 4.1 Boutons ───────────────────────────────────────────────────────────── */
.bx-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 44px; padding: 0 20px; border-radius: 999px;
  border: 1px solid var(--line-2); background: rgba(255, 255, 255, .06); color: var(--ink);
  font: 700 .92rem/1 var(--font); text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: transform .2s var(--ease), background-color .15s, border-color .15s;
  -webkit-tap-highlight-color: transparent;
}
.bx-btn:hover { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .24); }
.bx-btn:active { transform: translateY(1px); }
.bx-btn[disabled], .bx-btn.is-disabled { opacity: .45; pointer-events: none; }
.bx-btn svg { width: 16px; height: 16px; flex: 0 0 16px; }
.bx-btn .bx-coin__ic--beli { width: 7px; height: 14px; }
.bx-btn .bx-coin__ic--onyx { width: 17px; height: 17px; }
.bx-btn .bx-num { font-size: 1em; }

.bx-btn--primary { background: var(--accent); border-color: transparent; color: var(--on-accent); font-weight: 800;
  box-shadow: 0 10px 26px -12px rgba(var(--accent-rgb), .7); }
.bx-btn--primary:hover { background: #b59cff; border-color: transparent; transform: translateY(-1px); }

.bx-btn--discord { border-radius: 14px; background: var(--discord); border-color: transparent; color: #fff; font-weight: 800;
  box-shadow: 0 14px 34px -14px rgba(var(--discord-rgb), .75), inset 0 1px 0 rgba(255, 255, 255, .25); }
.bx-btn--discord:hover { background: var(--discord); transform: translateY(-2px); }
.bx-btn--discord svg { width: 18px; height: 18px; flex-basis: 18px; }

.bx-btn--ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.bx-btn--ghost:hover { background: rgba(255, 255, 255, .05); border-color: transparent; color: var(--ink); }

.bx-btn--danger { background: transparent; border-color: var(--bad-line); color: var(--bad); }
.bx-btn--danger:hover { background: var(--bad-dim); border-color: var(--bad-line); }

.bx-btn--lg { min-height: 52px; padding: 0 26px; font-size: 1rem; }
.bx-btn--sm { min-height: 36px; padding: 0 14px; font-size: .84rem; }
.bx-btn--icon { width: 40px; min-height: 40px; padding: 0; }
.bx-btn--block { width: 100%; }
@media (max-width: 960px) { .bx-btn--sm { min-height: 40px; } }

.bx-iconbtn { position: relative; display: inline-grid; place-items: center; width: 40px; height: 40px; flex: 0 0 40px; padding: 0;
  border-radius: 999px; border: 1px solid var(--line); background: rgba(255, 255, 255, .04); color: var(--ink-2);
  text-decoration: none; cursor: pointer; transition: color .15s, border-color .15s, background-color .15s; -webkit-tap-highlight-color: transparent; }
.bx-iconbtn:hover, .bx-iconbtn[aria-expanded="true"] { color: var(--ink); border-color: var(--line-2); background: rgba(255, 255, 255, .07); }
.bx-iconbtn svg { width: 18px; height: 18px; }
.bx-avabtn { position: relative; display: inline-block; width: 36px; height: 36px; flex: 0 0 36px; padding: 0; border: 0; border-radius: 50%;
  background: var(--card-2); box-shadow: 0 0 0 1px var(--line-2); cursor: pointer; transition: box-shadow .15s; -webkit-tap-highlight-color: transparent; }
.bx-avabtn img { display: block; width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.bx-avabtn:hover, .bx-avabtn[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--accent-line); }

/* ── 4.2 Pastilles, badges, monnaies, puces de chiffres ────────────────────── */
.bx-pill { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: 999px;
  border: 1px solid var(--line-2); background: rgba(255, 255, 255, .04); color: var(--ink-2);
  font: 800 11px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.bx-pill--ok { color: var(--ok); background: var(--ok-dim); border-color: var(--ok-line); }
.bx-pill--warn { color: var(--warn); background: var(--warn-dim); border-color: var(--warn-line); }
.bx-pill--bad { color: var(--bad); background: var(--bad-dim); border-color: var(--bad-line); }
.bx-pill--accent { color: var(--accent-2); background: var(--accent-dim); border-color: var(--accent-line); }
.bx-pill--chroma { color: var(--ink); }
.bx-pill--chroma > i { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--chroma-ring); }

/* Pastille de rareté hors carte : point + nom complet (« Peu commun », jamais « PC ») */
.bx-rar { --rc: var(--r1); --rc-rgb: var(--r1-rgb); color: var(--rc); background: rgba(var(--rc-rgb), .08); border-color: rgba(var(--rc-rgb), .5); }
.bx-rar::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.bx-rar[data-r="2"] { --rc: var(--r2); --rc-rgb: var(--r2-rgb); }
.bx-rar[data-r="3"] { --rc: var(--r3); --rc-rgb: var(--r3-rgb); }
.bx-rar[data-r="4"] { --rc: var(--r4); --rc-rgb: var(--r4-rgb); }
.bx-rar[data-r="5"] { --rc: var(--r5); --rc-rgb: var(--r5-rgb); }
.bx-rar[data-r="6"] { --rc: var(--r6); --rc-rgb: var(--r6-rgb); }

/* Compteur (navigation, onglets, cloche) */
.bx-badge { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--accent); color: var(--on-accent); font: 800 11px/1 var(--font); }
.bx-iconbtn .bx-badge, .bx-avabtn .bx-badge { position: absolute; top: -3px; right: -3px; }

/* Monnaie */
.bx-coin { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 12px; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .04); color: var(--ink);
  font: 700 14px/1 var(--mono); font-variant-numeric: tabular-nums; text-decoration: none; white-space: nowrap; }
.bx-coin__ic { flex: 0 0 auto; object-fit: contain; }
.bx-coin__ic--beli { width: 8px; height: 16px; }      /* /wiki/assets/ui/beli.webp, 20x40 : le « $ » vert du jeu */
.bx-coin__ic--onyx { width: 18px; height: 18px; }     /* /onyx/assets/onyx_96.png */
/* « + » de recharge (pastille Onyx de l'en-tête et du menu du compte) : une commande, pas une illustration. */
.bx-coin .bx-coin__plus { width: 14px; height: 14px; flex: 0 0 14px; margin: 0 -2px 0 -1px; color: var(--accent-2); }
a.bx-coin.has-plus:hover .bx-coin__plus { color: var(--ink); }
.bx-coin.is-bump { animation: bx-bump .5s var(--ease-out); }
@keyframes bx-bump { 30% { transform: scale(1.08); border-color: var(--accent-line); } }

/* Puce de chiffre (remplace les tuiles de tableau de bord) : modèle .tc-herometa de /cartes et crosstrade d'Onyx */
.bx-fact { display: inline-flex; align-items: baseline; gap: 8px; height: 34px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(9, 9, 14, .72); color: var(--ink-3); font: 600 13px/34px var(--font); white-space: nowrap; }
.bx-fact b { font: 700 13px/1 var(--mono); color: #fff; }
.bx-fact b.is-text { font-family: var(--font); word-spacing: normal; }
.bx-facts { display: flex; flex-wrap: wrap; gap: 8px; }

/* Étiquettes du joueur : les huit couleurs pointent sur des jetons existants (aucune teinte de plus) */
.bx-tagc { --tg: var(--r1); }
.bx-tagc[data-c="sea"] { --tg: var(--r2); }
.bx-tagc[data-c="leaf"] { --tg: var(--ok); }
.bx-tagc[data-c="sun"] { --tg: var(--r6); }
.bx-tagc[data-c="coral"] { --tg: var(--bad); }
.bx-tagc[data-c="rose"] { --tg: var(--r4); }
.bx-tagc[data-c="sand"] { --tg: var(--medal-br); }
.bx-tagc[data-c="ink"] { --tg: var(--accent); }
.bx-tagdot { display: inline-block; width: 9px; height: 9px; flex: 0 0 9px; border-radius: 50%; background: var(--tg, var(--r1)); }

/* ── 4.3 Panneaux et sections ──────────────────────────────────────────────── */
.bx-panel { position: relative; background: var(--panel-grad); border: 1px solid var(--line); border-radius: 20px; box-shadow: var(--hl); }
.bx-panel--flat { background: var(--card); }
.bx-panel--feature { overflow: hidden; }
.bx-panel--feature::before { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(64% 46% at 82% -6%, rgba(var(--accent-rgb), .12), transparent 70%); }   /* .pack d'Onyx */
.bx-panel > * { position: relative; }
.bx-pad { padding: 22px; }
.bx-panel__head { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.bx-panel__head h3 { margin: 0; }
.bx-panel__head > :last-child:not(:first-child) { margin-left: auto; }
@media (max-width: 600px) { .bx-pad { padding: 16px; } }

/* Titre de section : filet qui s'efface vers la droite (ds.css:272-276) */
.bx-sec { display: flex; align-items: center; gap: 14px; margin: 40px 0 16px; }
.bx-sec h2 { margin: 0; font: 800 clamp(1.15rem, 1rem + .8vw, 1.5rem)/1.1 var(--display); letter-spacing: -.02em; }
.bx-sec::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line-2), transparent); }
.bx-sec .bx-sec__more { order: 3; display: inline-flex; align-items: center; min-height: 40px; color: var(--accent-2); font: 700 13px/1 var(--font); text-decoration: none; }
.bx-sec .bx-sec__more:hover { text-decoration: underline; text-underline-offset: 3px; }

/* En-tête de page de jeu */
.bx-ph { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 6px 0 22px; }
.bx-ph__sub { margin: 10px 0 0; }                     /* une .bx-facts ou une phrase de fait, jamais une règle */
.bx-ph__sub:empty { display: none; }
.bx-ph__act { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bx-how { display: inline-flex; align-items: center; min-height: 40px; padding: 0 4px; border: 0; background: none; color: var(--accent-2); font: 700 13px/1 var(--font); text-decoration: none; cursor: pointer; }
.bx-how:hover { text-decoration: underline; text-underline-offset: 3px; }
/* Aide « ? » d'un mot du jeu (BM.helpBtn) : rond visible de 22 px dans une zone de 40 x 40 px. Les marges
   négatives gardent la ligne à sa hauteur et collent le rond à 4 px du mot qui le précède. */
.bx-help { position: relative; isolation: isolate; display: inline-grid; place-items: center; flex: 0 0 auto; width: 40px; height: 40px; margin: -9px -9px -9px -5px; padding: 0;
  border: 0; border-radius: 50%; background: none; color: var(--ink-2); font: 700 13px/1 var(--font); vertical-align: middle; cursor: pointer;
  transition: color .15s; -webkit-tap-highlight-color: transparent; }
.bx-help::before { content: ''; position: absolute; z-index: -1; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%;
  border: 1px solid var(--line-2); background: rgba(255, 255, 255, .04); transition: border-color .15s, background-color .15s; }
.bx-help:hover { color: var(--ink); }
.bx-help:hover::before { border-color: rgba(255, 255, 255, .3); background: rgba(255, 255, 255, .08); }
body.bx .bx-help:focus-visible { outline: none; }   /* l'anneau du focus se pose sur le rond, pas sur la zone de 40 px */
.bx-help:focus-visible::before { border-color: var(--accent-2); box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .35); }
/* Téléphone : même disposition sur toutes les pages. Les boutons sur une ligne (le principal prend la place
   restante, toute la largeur s'il est seul), « Comment ça marche » toujours dessous, aligné à gauche. */
@media (max-width: 600px) {
  .bx-ph__act { width: 100%; }
  .bx-ph__act > .bx-btn--primary { flex: 1 1 auto; }
  .bx-ph__act > .bx-how { order: 9; flex: 0 0 100%; justify-content: flex-start; padding-left: 0; }
}

/* Panneau de scène (Raid, Guilde, Profil) : modèle .vt-scene / .rghero, sans image étirée */
.bx-scene { position: relative; overflow: hidden; display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 28px;
  padding: 26px 28px; border-radius: 22px; border: 1px solid var(--line); box-shadow: var(--hl);
  background: radial-gradient(70% 90% at 0% 50%, rgba(var(--rc-rgb, var(--accent-rgb)), .12), transparent 70%), var(--panel-grad); }
@media (max-width: 760px) { .bx-scene { grid-template-columns: 1fr; justify-items: center; text-align: center; padding: 20px 16px; gap: 16px; } }

/* Mise en page (rythme du cahier 3.4 : 14 px entre panneaux d'une grille) */
.bx-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 760px) { .bx-cols { grid-template-columns: minmax(0, 1fr); } }
.bx-stack { display: flex; flex-direction: column; gap: 12px; }
.bx-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bx-grow { flex: 1 1 auto; min-width: 0; }

/* ── 4.4 Onglets et filtres ────────────────────────────────────────────────── */
.bx-tabs { display: inline-flex; gap: 4px; max-width: 100%; padding: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, .04); border: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.bx-tabs::-webkit-scrollbar { display: none; }
.bx-tabs > a, .bx-tabs > button { display: inline-flex; align-items: center; height: 36px; padding: 0 16px; border: 0; border-radius: 999px;
  background: none; color: var(--ink-3); font: 700 .86rem/1 var(--font); white-space: nowrap; text-decoration: none; cursor: pointer; }
.bx-tabs > :hover { color: var(--ink); }
.bx-tabs > [aria-selected="true"], .bx-tabs > [aria-current="page"] { color: var(--ink); background: var(--accent-dim); box-shadow: inset 0 0 0 1px var(--accent-line); }
.bx-tabs .bx-count { margin-left: 7px; font: 700 12px/1 var(--mono); color: var(--accent-2); }
.bx-tabs .bx-badge { margin-left: 7px; }
@media (max-width: 960px) { .bx-tabs > a, .bx-tabs > button { min-height: 40px; } }
@media (max-width: 600px) {
  .bx-tabs--grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 88px), 1fr)); width: 100%; border-radius: 16px; }
  .bx-tabs--grid > * { justify-content: center; min-height: 40px; height: auto; padding: 6px 8px; border-radius: 12px; white-space: normal; text-align: center; line-height: 1.15; }
}

/* Rangée de puces de filtre qui défile : le bord droit s'estompe tant qu'il reste à voir */
.bx-chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.bx-chips::-webkit-scrollbar { display: none; }
.bx-chips.is-overflow { -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
.bx-chips.is-wrap { flex-wrap: wrap; overflow: visible; }
.bx-chip { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 13px; border-radius: 999px; flex: 0 0 auto;
  border: 1px solid var(--line-2); background: transparent; color: var(--ink-2); font: 650 13px/1 var(--font); white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: color .15s, border-color .15s, background-color .15s; }
.bx-chip:hover { color: var(--ink); border-color: rgba(255, 255, 255, .24); }
.bx-chip[aria-pressed="true"] { color: var(--ink); background: var(--accent-dim); border-color: var(--accent-line); }
.bx-chip .bx-count { font: 700 12px/1 var(--mono); color: var(--ink-3); }
/* Puce de filtre par rareté : point de la couleur de rareté, texte neutre tant qu'elle n'est pas active */
.bx-chip.bx-rar { color: var(--ink-2); background: transparent; border-color: var(--line-2); }
.bx-chip.bx-rar::before { flex: 0 0 6px; background: var(--rc); }
.bx-chip.bx-rar[aria-pressed="true"] { color: var(--ink); background: rgba(var(--rc-rgb), .1); border-color: rgba(var(--rc-rgb), .5); }
@media (max-width: 960px) { .bx-chip { height: 40px; } }

/* ── 4.5 Listes ────────────────────────────────────────────────────────────── */
.bx-list { display: flex; flex-direction: column; }
.bx-row { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 10px 16px; border-bottom: 1px solid var(--line); color: inherit; text-decoration: none; }
.bx-row:last-child { border-bottom: 0; }
a.bx-row:hover, button.bx-row:hover { background: rgba(255, 255, 255, .025); }
button.bx-row { width: 100%; border: 0; border-bottom: 1px solid var(--line); background: none; text-align: left; font: inherit; color: inherit; cursor: pointer; }
.bx-row__rank { width: 32px; flex: 0 0 32px; text-align: center; font: 700 14px/1 var(--mono); color: var(--ink-3); }
.bx-row__main { flex: 1; min-width: 0; }
.bx-row__title { display: block; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-row__meta { display: block; font-size: 13px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-row__num { margin-left: auto; font: 700 14px/1 var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bx-row__time { margin-left: auto; flex: 0 0 auto; align-self: flex-start; padding-top: 3px; font: 500 11px/1 var(--mono); color: var(--ink-3); white-space: nowrap; }
.bx-row__vis { width: 36px; height: 36px; flex: 0 0 36px; display: grid; place-items: center; border-radius: 10px; overflow: hidden; background: #1c1c26; }
.bx-row__vis img { width: 100%; height: 100%; object-fit: cover; }
.bx-row__vis .bx-coin__ic--beli { width: 10px; height: 20px; }
.bx-row__vis .bx-coin__ic--onyx { width: 22px; height: 22px; }
.bx-row__vis.is-ava { border-radius: 50%; }           /* avatar Discord du joueur concerné */
.bx-row__vis.is-empty { background: none; }           /* place gardée : les titres de la liste restent alignés */
.bx-row.is-me { background: var(--accent-dim); }
.bx-row.is-read { opacity: .62; }
.bx-row__label { padding: 12px 16px 6px; }
.bx-ava { width: 32px; height: 32px; flex: 0 0 32px; border-radius: 50%; object-fit: cover; background: var(--card-2); }
.bx-ava--sm { width: 24px; height: 24px; flex-basis: 24px; }
.bx-ava--md { width: 44px; height: 44px; flex-basis: 44px; }
.bx-ava--lg { width: 96px; height: 96px; flex-basis: 96px; box-shadow: 0 0 0 2px var(--line-2); }
.bx-online { color: var(--ok); font-weight: 700; }
.bx-presence { position: relative; display: inline-flex; flex: 0 0 auto; }
.bx-presence > .bx-ava { display: block; }
.bx-presence.is-on::after { content: ''; position: absolute; right: -1px; bottom: -1px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--ok); box-shadow: 0 0 0 2px var(--card); }

/* Miniature de carte dans une liste (remplace .mini) */
.bx-mini { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bx-mini__vis { --rc-rgb: var(--r1-rgb); width: 40px; height: 40px; flex: 0 0 40px; border-radius: 10px; overflow: hidden;
  background: radial-gradient(80% 80% at 50% 40%, rgba(var(--rc-rgb), .3), transparent 75%), #15161d;
  box-shadow: inset 0 0 0 1px rgba(var(--rc-rgb), .55); }
.bx-mini__vis img { width: 100%; height: 100%; object-fit: cover; }
.bx-mini__vis.is-contain img { object-fit: contain; padding: 4px; }
/* La teinte par rareté (data-r) et le contenu de la vignette sont posés par card.css (BM.miniVisHtml). */

/* Liste d'actions d'un menu : des .bx-row compactes */
.bx-menu { display: flex; flex-direction: column; gap: 2px; }
.bx-menu > .bx-row { min-height: 44px; padding: 0 12px; gap: 10px; border: 0; border-radius: 12px; color: var(--ink-2); font: 600 14px/1.2 var(--font); }
.bx-menu > .bx-row:hover, .bx-menu > .bx-row:focus-visible { background: var(--card-2); color: var(--ink); }
.bx-menu > .bx-row[aria-current="page"] { background: var(--accent-dim); color: var(--accent-2); }
.bx-menu > .bx-row > svg { width: 18px; height: 18px; flex: 0 0 18px; color: var(--ink-3); }
.bx-menu > .bx-row .bx-badge { margin-left: auto; }
.bx-menu > .bx-row.is-danger { color: var(--ink-3); }
.bx-menu > .bx-row.is-danger:hover, .bx-menu > .bx-row.is-danger:focus-visible { color: var(--bad); background: var(--bad-dim); }
.bx-menu > .bx-row[disabled] { opacity: .45; cursor: default; pointer-events: none; }
.bx-menu__sep { height: 1px; margin: 6px 4px; background: var(--line); }

/* Tableau d'administration (cahier 7.16) */
.bx-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.bx-table th { position: sticky; top: 0; z-index: 1; height: 36px; padding: 0 12px; background: var(--card); border-bottom: 1px solid var(--line-2);
  font: 800 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); text-align: left; white-space: nowrap; }
.bx-table td { height: 40px; padding: 0 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.bx-table tr:last-child td { border-bottom: 0; }
.bx-table .is-num, .bx-table td.bx-num { text-align: right; font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; }
.bx-table th.is-num { text-align: right; }
.bx-tablewrap { overflow-x: auto; }

/* ── 4.6 Champs ────────────────────────────────────────────────────────────── */
.bx-field { display: flex; flex-direction: column; gap: 6px; }
.bx-field > span:first-child { font: 800 11px/1 var(--font); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.bx-input, .bx-select, .bx-textarea { width: 100%; min-height: 44px; padding: 0 14px; border-radius: 14px;
  border: 1px solid var(--line-2); background: #0d0d13; color: var(--ink); font: 500 15px/1.4 var(--font); outline: none;
  transition: border-color .15s, box-shadow .15s; }
.bx-textarea { min-height: 88px; padding: 11px 14px; resize: vertical; }
.bx-input::placeholder, .bx-textarea::placeholder { color: var(--ink-4); }
.bx-input:focus, .bx-select:focus, .bx-textarea:focus { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-dim); }
.bx-select { appearance: none; padding-right: 38px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%239c9cab'%3E%3Cpath d='M5.5 7.5 10 12l4.5-4.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 18px; cursor: pointer; }
.bx-select--auto { width: auto; }
.bx-search { position: relative; } .bx-search svg { position: absolute; left: 13px; top: 50%; width: 16px; height: 16px; transform: translateY(-50%); color: var(--ink-3); pointer-events: none; }
.bx-search .bx-input { padding-left: 38px; }
.bx-search .bx-input::-webkit-search-cancel-button { filter: invert(.6); }
@media (max-width: 960px) { .bx-input, .bx-select, .bx-textarea { font-size: 16px; } }   /* Safari iOS zoome sous 16 px */

/* Saisie d'un montant : moins, valeur, plus */
.bx-stepper { display: flex; align-items: stretch; height: 48px; border: 1px solid var(--line-2); border-radius: 14px; overflow: hidden; background: #0d0d13; }
.bx-stepper button { width: 48px; border: 0; background: rgba(255, 255, 255, .04); color: var(--ink); font: 700 18px/1 var(--font); cursor: pointer; }
.bx-stepper button:hover { background: rgba(255, 255, 255, .09); }
.bx-stepper input { flex: 1; min-width: 0; border: 0; background: transparent; color: #fff; text-align: center; font: 700 16px/1 var(--mono); outline: none; -moz-appearance: textfield; }
.bx-stepper input::-webkit-outer-spin-button, .bx-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.bx-stepper:focus-within { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-dim); }

/* Interrupteur */
.bx-switch { display: inline-flex; align-items: center; gap: 12px; min-height: 40px; cursor: pointer; font: 600 14px/1.3 var(--font); color: var(--ink-2); }
.bx-switch input { appearance: none; -webkit-appearance: none; position: relative; width: 42px; height: 24px; flex: 0 0 42px; margin: 0; border-radius: 999px; background: rgba(255, 255, 255, .12); transition: background .2s; cursor: pointer; }
.bx-switch input::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .2s var(--ease); }
.bx-switch input:checked { background: var(--accent); }
.bx-switch input:checked::after { transform: translateX(18px); background: var(--on-accent); }
.bx-switch input:disabled { opacity: .45; cursor: default; }

/* ── 4.7 Icônes au trait : commandes seulement (BM.icon) ───────────────────── */

/* ── 4.8 Fenêtres ──────────────────────────────────────────────────────────── */
.bx-modal { position: fixed; inset: 0; z-index: 150; display: grid; place-items: center; padding: 20px; background: var(--scrim); animation: bx-fade .18s ease-out; }
.bx-modal__box { width: min(560px, 100%); max-height: calc(100dvh - 40px); overflow: auto; overscroll-behavior: contain; background: #101019; border: 1px solid var(--line-2);
  border-radius: 24px; box-shadow: var(--shadow-pop), var(--hl); animation: bx-rise .24s var(--ease-out); }
.bx-modal__box:focus { outline: none; }
.bx-modal__box.is-wide { width: min(980px, 100%); }
.bx-modal__head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 22px; background: #101019; border-bottom: 1px solid var(--line); }
.bx-modal__head h3 { margin: 0; font: 800 1.1rem/1.2 var(--display); letter-spacing: -.015em; }
.bx-modal__head .bx-btn--icon { margin: -6px -10px -6px 0; }
.bx-modal__body { padding: 22px; }
.bx-modal__foot { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 8px; padding: 16px 22px; border-top: 1px solid var(--line); }
.bx-modal__btns { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; width: 100%; }
.bx-modal__text { font-size: 15px; line-height: 1.6; color: var(--ink-2); }
.bx-modal__text + .bx-modal__text { margin-top: 10px; }
/* Lien seul sur sa ligne (« Toutes les règles du jeu » de BM.how) : cible de 40 px de haut (cahier 9.2). */
.bx-modal__text > .bx-link:only-child { display: inline-flex; align-items: center; min-height: 40px; }
@keyframes bx-fade { from { opacity: 0; } }
@keyframes bx-rise { from { opacity: 0; transform: translateY(14px); } }
@media (max-width: 600px) {
  .bx-modal { padding: 0; align-items: end; }
  .bx-modal__box { width: 100%; max-width: none; border-radius: 22px 22px 0 0; max-height: 92dvh; padding-bottom: env(safe-area-inset-bottom); }
  .bx-modal__box::before { content: ''; display: block; width: 44px; height: 5px; margin: 8px auto 0; border-radius: 99px; background: rgba(255, 255, 255, .18); }
  .bx-modal__head { padding: 12px 16px 14px; }
  .bx-modal__body { padding: 18px 16px; }
  .bx-modal__foot { padding: 14px 16px; }
  .bx-modal__btns > .bx-btn { flex: 1 1 0; }
}

/* Panneau ancré sous un bouton (menu du compte 300 px, notifications 360 px, menus « ... ») */
.bx-pop { position: fixed; z-index: 75; width: 300px; max-width: calc(100vw - 24px); max-height: min(72vh, 600px); overflow: auto; overscroll-behavior: contain;
  padding: 8px; background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-l);
  box-shadow: var(--shadow-pop), var(--hl); animation: bx-pop .16s var(--ease); }
.bx-pop:focus { outline: none; }
body.bx:has(.bx-modal) > .bx-pop { z-index: 155; }   /* menu « ... » ouvert dans une fenêtre (fiche de carte) */
.bx-pop.is-up { animation-name: bx-pop-up; }
@keyframes bx-pop-up { from { opacity: 0; transform: translateY(6px); } }
.bx-pop__head { display: flex; align-items: center; gap: 12px; padding: 10px 10px 12px; }
.bx-pop__name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-pop__coins { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 10px 12px; }
@media (max-width: 960px) { .bx-pop__coins .bx-coin { height: 40px; } }   /* liens vers la boutique : 40 px tactiles (cahier 9.2), comme dans l'en-tête */
.bx-pop__title { padding: 8px 10px 10px; font: 800 1rem/1.2 var(--display); letter-spacing: -.01em; }
.bx-pop .bx-list .bx-row { padding: 10px; border-radius: 12px; border-bottom: 0; }

/* ── 4.9 Notifications (toasts) ────────────────────────────────────────────── */
.bx-toasts { position: fixed; z-index: 160; right: 18px; bottom: 18px; width: min(380px, calc(100vw - 36px)); display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.bx-toast { position: relative; overflow: hidden; pointer-events: auto; display: flex; align-items: center; gap: 12px;
  padding: 12px 14px 12px 15px; border-radius: 16px; background: var(--card-2); border: 1px solid var(--line-2);
  box-shadow: var(--shadow-pop); font-size: 14px; animation: bx-rise .25s var(--ease-out); cursor: default; }
.bx-toast.is-link { cursor: pointer; }
.bx-toast::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--tc, var(--accent)); }
.bx-toast.is-ok { --tc: var(--ok); } .bx-toast.is-err { --tc: var(--bad); }
.bx-toast__vis { width: 36px; height: 36px; flex: 0 0 36px; display: grid; place-items: center; border-radius: 10px; overflow: hidden; background: #1c1c26; }
.bx-toast__vis img { width: 100%; height: 100%; object-fit: cover; }
.bx-toast__vis .bx-coin__ic--beli { width: 10px; height: 20px; }
.bx-toast__vis .bx-coin__ic--onyx { width: 22px; height: 22px; }
.bx-toast__txt { min-width: 0; }
.bx-toast__t { font-weight: 700; } .bx-toast__d { font-size: 13px; color: var(--ink-3); }
.bx-toast.is-out { animation: bx-out .25s ease-in forwards; } @keyframes bx-out { to { opacity: 0; transform: translateY(8px); } }
@media (max-width: 960px) { .bx-toasts { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); width: auto; } }
body.bx:has(.bx-modal) .bx-toasts { top: 14px; bottom: auto; }   /* au-dessus d'une feuille ouverte, règle des raids */

/* ── 4.10 Barres, jauges, compteurs ────────────────────────────────────────── */
.bx-bar { height: 6px; border-radius: 999px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.bx-bar > i { display: block; height: 100%; border-radius: inherit; background: var(--accent); transition: width .6s var(--ease-out); }
.bx-bar--warn > i { background: var(--warn); }

/* Points de vie (duel, raid) : BM.hpBar. Le chiffre est écrit au-dessus de la barre, jamais dedans : en
   blanc sur le vert --ok, il tombait à 1,7:1 de contraste. Il ne passe à la ligne qu'aux espaces ordinaires
   (« / », « PV ») : les milliers sont séparés par des insécables. */
.bx-hp { display: grid; gap: 6px; min-width: 0; }
.bx-hp__txt { font: 700 12px/1.25 var(--mono); font-variant-numeric: tabular-nums; color: var(--ink-2); text-align: right; }
.bx-hp__bar { position: relative; height: 8px; border-radius: 999px; background: rgba(255, 255, 255, .07); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.bx-hp__bar > i { position: absolute; inset: 0 auto 0 0; background: var(--ok); border-radius: inherit; transition: width .5s var(--ease-out); }
.bx-hp.is-low .bx-hp__bar > i { background: var(--bad); }      /* moins de 30 % */
.bx-hp--lg { gap: 8px; } .bx-hp--lg .bx-hp__bar { height: 12px; } .bx-hp--lg .bx-hp__txt { font-size: 13px; }

/* Réserve de paquets : un segment par paquet */
.bx-stock { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; height: 8px; }
.bx-stock > i { border-radius: 3px; background: rgba(255, 255, 255, .08); }
.bx-stock > i.is-full { background: var(--accent); }
.bx-stock > i.is-charging { background: linear-gradient(90deg, var(--accent) calc(var(--fill, 0) * 100%), rgba(255, 255, 255, .08) 0); }

/* Gros chiffre et minuterie */
.bx-big { font: 900 clamp(2.2rem, 4vw, 3.4rem)/1 var(--display); letter-spacing: -.03em; color: #fff; }
.bx-big small { margin-left: 8px; font: 600 1rem/1 var(--font); letter-spacing: 0; color: var(--ink-3); }

/* ── 4.11 États vides et squelettes ────────────────────────────────────────── */
.bx-empty { display: grid; justify-items: center; gap: 10px; padding: 40px 20px; border: 1px dashed var(--line-2); border-radius: 18px; text-align: center; }
.bx-empty img { width: 72px; height: 72px; object-fit: contain; }
.bx-empty strong { font: 700 1.05rem/1.3 var(--font); color: var(--ink); }
.bx-empty p { margin: 0; max-width: 420px; color: var(--ink-3); font-size: 14px; }
.bx-empty .bx-btn { margin-top: 6px; }
.bx-empty--flat { border: 0; }
.bx-skel { display: block; border-radius: 12px; background: linear-gradient(90deg, rgba(255,255,255,.04), rgba(255,255,255,.08), rgba(255,255,255,.04)); background-size: 200% 100%; animation: bx-skel 1.3s linear infinite; }
.bx-skel--ava { width: 36px; height: 36px; border-radius: 50%; }
.bx-skel--line { height: 13px; border-radius: 6px; }
.bx-skel--title { width: min(320px, 70%); height: clamp(1.75rem, 1.1rem + 2.4vw, 2.9rem); border-radius: 10px; }
.bx-skel--fact { width: 132px; height: 34px; border-radius: 999px; }
.bx-skel--card { width: 100%; aspect-ratio: 5 / 7; }
.bx-skel--row { height: 56px; border-radius: 0; border-bottom: 1px solid var(--line); }
@keyframes bx-skel { to { background-position: -200% 0; } }

/* Indicateur de chargement (dans un bouton, une ligne, un panneau) */
.bx-spin { display: inline-block; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--line-2); border-top-color: var(--accent); animation: bx-rot .8s linear infinite; vertical-align: -4px; }
.bx-spin--lg { width: 26px; height: 26px; border-width: 2.5px; }
@keyframes bx-rot { to { transform: rotate(360deg); } }

/* ── Cartes en grille (cahier 5.3) ─────────────────────────────────────────── */
.bx-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(156px, 1fr)); gap: 18px; }
@media (max-width: 600px) { .bx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } }
.bx-cardbtn { position: relative; display: block; width: 100%; padding: 0; border: 0; border-radius: 12px; background: none; color: inherit; text-align: inherit; cursor: pointer;
  transition: transform .2s var(--ease); -webkit-tap-highlight-color: transparent; }
.bx-cardbtn:hover { transform: translateY(-4px); }
.bx-cardbtn[aria-pressed="true"] { outline: 2px solid var(--accent); outline-offset: 3px; }
.bx-cardbtn[aria-pressed="true"]::after { content: ''; position: absolute; z-index: 6; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230b0b10' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 4.5 4.5L19 7'/%3E%3C/svg%3E") center / 14px no-repeat;
  box-shadow: 0 0 0 2px var(--bg); }
.bx-cardbtn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; }

/* ── Écran tactile : pas de soulèvement au survol ──────────────────────────────
   Sur un téléphone, le survol reste « collé » à l'élément touché : une carte de la grille restait soulevée
   après la fermeture de sa fiche. Les soulèvements des pages (feuilles chargées après celle-ci) sont
   annulés ici par une spécificité plus forte (body.bx). Les ombres et les couleurs du survol restent. */
@media (hover: none) {
  body.bx .bx-cardbtn:hover, body.bx .bx-offer:hover, body.bx .bx-mode:hover, body.bx .bx-also__item:hover,
  body.bx .bx-achset__card:hover, body.bx .bx-mk-visbtn:hover, body.bx .bx-btn--primary:hover, body.bx .bx-btn--discord:hover,
  body.bx .bx-also__item:hover .bx-also__go, body.bx .bx-backs__item:hover .bx-backs__vis { transform: none; }
  body.bx .bx-btn:active { transform: translateY(1px); }   /* l'appui reste visible sous le doigt */
}


/* ===== css/card.css ===== */
/* BloxMasters : la carte (cahier de design §5).
   Corps sombre commun à toutes les raretés, fenêtre teintée par la rareté (60 % de la hauteur),
   pastille de rareté en toutes lettres à cheval sur le bord de la fenêtre, plaque dessous.
   Tout se mesure en cqw (largeur de la carte) : la même carte se lit de 90 px à 360 px.
   Paliers : XS sous 100 px (fenêtre seule), S sous 180 px, M de 180 à 299 px, L à partir de 300 px.
   Le cahier (§5.3) posait la limite S / M à 200 px : elle est à 180 pour que les rangées de six de la
   vitrine et des grands tirages (cartes de 181 à 189 px) soient en M, comme le demande le §7.1.
   Jetons (--r1 à --r6, --ink, --line, polices) : src/css/tokens.css. */

/* ---------- Raretés : une seule table pour tout ce qui se teinte ---------- */

.bxc, .bx-mini__vis, .bx-mini__rar, .bx-ability { --rc: var(--r1); --rc2: var(--r1-2); --rc-rgb: var(--r1-rgb); }
.bxc[data-r="2"], .bx-mini__vis[data-r="2"], .bx-mini__rar[data-r="2"], .bx-ability[data-r="2"] { --rc: var(--r2); --rc2: var(--r2-2); --rc-rgb: var(--r2-rgb); }
.bxc[data-r="3"], .bx-mini__vis[data-r="3"], .bx-mini__rar[data-r="3"], .bx-ability[data-r="3"] { --rc: var(--r3); --rc2: var(--r3-2); --rc-rgb: var(--r3-rgb); }
.bxc[data-r="4"], .bx-mini__vis[data-r="4"], .bx-mini__rar[data-r="4"], .bx-ability[data-r="4"] { --rc: var(--r4); --rc2: var(--r4-2); --rc-rgb: var(--r4-rgb); }
.bxc[data-r="5"], .bx-mini__vis[data-r="5"], .bx-mini__rar[data-r="5"], .bx-ability[data-r="5"] { --rc: var(--r5); --rc2: var(--r5-2); --rc-rgb: var(--r5-rgb); }
.bxc[data-r="6"], .bx-mini__vis[data-r="6"], .bx-mini__rar[data-r="6"], .bx-ability[data-r="6"] { --rc: var(--r6); --rc2: var(--r6-2); --rc-rgb: var(--r6-rgb); }

/* ---------- Corps ---------- */

.bxc {
  --rar-h: max(16px, 6.8cqw);                 /* hauteur de la pastille, lue par les enfants */
  /* Badges du bas de la fenêtre (chromatique, « Nouvelle ») : leur bas, posé au-dessus de la pastille de
     rareté, et la hauteur d'une pastille de badge. Le nuancier d'une couleur de titre s'en sert pour
     s'arrêter au-dessus d'eux. */
  --bdg-b: calc(var(--rar-h) / 2 + max(5px, 2.2cqw));
  --bdg-h: calc(2.8cqw + max(9px, 3.4cqw) + 2px);
  --bm: max(2px, 1cqw);                       /* écart minimal entre un badge et le nom écrit dans la fenêtre */
  --bxc-drop: var(--shadow-card);
  container: bxc / inline-size;
  position: relative; display: block; width: 100%; aspect-ratio: 5 / 7;
  border-radius: 12px; overflow: hidden; isolation: isolate;
  background: linear-gradient(180deg, #14151c 0%, #0b0c11 100%);
  box-shadow: inset 0 0 0 1px rgba(var(--rc-rgb), .45), var(--bxc-drop);
  color: var(--ink); font-family: var(--font); text-align: center;
  user-select: none; -webkit-user-select: none;
  transition: box-shadow .2s var(--ease);
}
.bxc__in { position: absolute; inset: 0; display: flex; flex-direction: column; padding: 3.2cqw; }

/* ---------- Fenêtre ---------- */

.bxc__win {
  position: relative; flex: 0 0 60%; min-height: 0; border-radius: 8px; overflow: hidden;
  background:
    radial-gradient(85% 70% at 50% 40%, rgba(var(--rc-rgb), .28), rgba(var(--rc-rgb), .07) 60%, transparent 78%),
    linear-gradient(180deg, #1b1d26, #101118);
}
/* Filet intérieur, posé au-dessus de l'illustration pour rester net sur une capture. */
.bxc__win::before { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06); }
.bxc[data-r="6"]:not([data-missing]) .bxc__win::before { box-shadow: inset 0 0 0 1px rgba(242, 193, 78, .55); }

.bxc__win img { position: absolute; inset: 0; display: block; box-sizing: border-box; width: 100%; height: 100%; }
.bxc[data-fit="contain"] .bxc__win img { object-fit: contain; padding: 8cqw 9cqw 9cqw; filter: drop-shadow(0 2.4cqw 2.6cqw rgba(0, 0, 0, .5)); }
.bxc[data-fit="cover"] .bxc__win img { object-fit: cover; object-position: center 35%; }
/* Capture d'origine recadrée (quelques ennemis et boss : table CROP de card.js ; les PNJ arrivent déjà
   coupés sous leur étiquette, assets/cadre/) : l'image est posée dans une boîte plus haute que la fenêtre
   et remontée, pour que l'étiquette du jeu (« Nom [Lv. 2600] », « ? MISC. ») reste hors champ. */
.bxc[data-crop] .bxc__win img { top: calc(var(--crop-top) * 100%); bottom: auto; height: calc(var(--crop-h) * 100%); object-position: center var(--crop-y); }
.bxc[data-fit="cover"] .bxc__win::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(8, 8, 12, 0) 55%, rgba(8, 8, 12, .6) 100%); }
.bxc[data-small] .bxc__win img { object-fit: scale-down; padding: 0; }   /* jamais agrandie au-delà de sa taille réelle */
/* Petite capture (moins de 200 px à la source) : posée à sa taille réelle au milieu de la fenêtre et encadrée
   comme une photo, au lieu d'un rectangle nu qui se lit comme une image manquante. Un objet détouré
   (data-fit="contain", fond transparent) garde la règle du dessus : il flotte sans cadre. */
.bxc[data-small][data-fit="cover"] .bxc__win img { inset: auto; left: 50%; top: 50%; width: auto; height: auto; max-width: 78%; max-height: 78%;
  translate: -50% -50%; border-radius: 8px; box-shadow: 0 0 0 1px rgba(255, 255, 255, .14); }
.bxc[data-small][data-fit="cover"] .bxc__win::after { content: none; }
/* Petite capture qui porte une étiquette du jeu (« Ancient Zombie [Lv. 2000] », table CROP de card.js) : la
   bande de l'étiquette est retirée par une découpe (coins arrondis compris), et la partie gardée reste au
   milieu de la fenêtre. La découpe emporte le liseré : la photo garde ses coins arrondis. */
.bxc[data-small][data-fit="cover"][data-crop] .bxc__win img { max-height: 90%; box-shadow: none;
  clip-path: inset(calc(var(--crop-t) * 100%) 0 calc(var(--crop-b) * 100%) round 8px);
  translate: -50% calc((1 + var(--crop-t) - var(--crop-b)) * -50%); }
/* Pas de filtre sur un élément répété (cahier §9.1) : aucune ombre portée dans une grille de cartes ni
   sur une carte cliquable (.bx-cardbtn : récapitulatif, échange, combat, équipes, tirages, vitrine du profil).
   L'ombre reste sur les cartes seules : fiche, révélation, héros de la vitrine, enchère, raid. */
.bx-grid .bxc .bxc__win img, .vgrid .bxc .bxc__win img, .bx-cardbtn .bxc .bxc__win img { filter: none; }

/* ---------- Badges : aux quatre coins de la fenêtre, jamais au milieu ni sur la plaque ---------- */

/* 70 % : « Style de combat », le plus long, tient entier dès 180 px sans toucher les badges de droite. */
.bxc__fam { position: absolute; z-index: 2; top: 3cqw; left: 3cqw; max-width: 70%; box-sizing: border-box;
  padding: 1.4cqw calc(2.6cqw - .12em) 1.4cqw 2.6cqw; border-radius: 999px; background: rgba(7, 7, 9, .66); color: rgba(255, 255, 255, .82);
  font: 700 max(9px, 3.6cqw)/1 var(--font); letter-spacing: .12em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bxc__lock { position: absolute; z-index: 2; top: 3cqw; left: 3cqw; width: max(18px, 8cqw); height: max(18px, 8cqw); border-radius: 50%;
  display: grid; place-items: center; background: rgba(7, 7, 9, .72); color: #fff; }
.bxc__lock svg { width: 60%; height: 60%; vertical-align: 0; }
.bxc__tr { position: absolute; z-index: 2; top: 3cqw; right: 3cqw; display: flex; align-items: center; gap: 1.6cqw; }
.bxc__count { display: grid; place-items: center; box-sizing: border-box; height: max(16px, 7cqw); padding: 0 2.4cqw; border-radius: 999px;
  background: rgba(7, 7, 9, .72); border: 1px solid var(--line-2); color: #fff; font: 700 max(9px, 3.8cqw)/1 var(--mono); font-variant-numeric: tabular-nums; word-spacing: -.32em; }
.bxc__fav { display: block; width: max(14px, 6cqw); height: max(14px, 6cqw); color: #f5c451; }
.bxc__fav svg { display: block; width: 100%; height: 100%; }
/* Pastille « Chromatique » : fond sombre cerné d'un filet arc-en-ciel (même dégradé que le liseré), point irisé. */
.bxc__chroma { position: absolute; z-index: 2; left: 3cqw; bottom: var(--bdg-b); display: inline-flex; align-items: center; gap: 1.4cqw;
  padding: calc(1.4cqw - 1px) calc(2.6cqw - .1em - 1px) calc(1.4cqw - 1px) calc(2.6cqw - 1px); border: 1px solid transparent; border-radius: 999px;
  background: linear-gradient(rgba(7, 7, 9, .82), rgba(7, 7, 9, .82)) padding-box, var(--chroma) border-box; color: #fff;
  font: 700 max(9px, 3.4cqw)/1 var(--font); letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; }
.bxc__chroma i { flex: 0 0 auto; width: max(8px, 2.2cqw); height: max(8px, 2.2cqw); border-radius: 50%; background: var(--chroma-ring); }
.bxc__new { position: absolute; z-index: 2; right: 3cqw; bottom: var(--bdg-b);
  padding: 1.4cqw calc(2.6cqw - .1em) 1.4cqw 2.6cqw; border-radius: 999px; background: rgba(7, 7, 9, .72); border: 1px solid var(--ok-line); color: var(--ok);
  font: 800 max(9px, 3.4cqw)/1 var(--font); letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; }
/* « V2 » (BM.cardHtml) : carte qui reprend l'image de sa carte de base (Saber V2, Bisento V2...). Même pastille
   que la famille, en bas à droite ; elle reste en petite taille, où la famille n'est plus écrite. Au-dessus de
   « Nouvelle » quand les deux s'y posent (récapitulatif, révélation en moyenne et grande taille). */
.bxc__v2 { position: absolute; z-index: 2; right: 3cqw; bottom: var(--bdg-b);
  padding: 1.4cqw calc(2.6cqw - .12em) 1.4cqw 2.6cqw; border-radius: 999px; background: rgba(7, 7, 9, .66); color: rgba(255, 255, 255, .82);
  font: 700 max(9px, 3.6cqw)/1 var(--font); letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; }
.bxc__new ~ .bxc__v2 { bottom: calc(var(--bdg-b) + var(--bdg-h) + 1.4cqw); }

/* ---------- Plaque ---------- */

.bxc__plate { position: relative; z-index: 2; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; align-items: center; padding: 0 2cqw .6cqw; }
.bxc__rar { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 1.6cqw; box-sizing: border-box; height: var(--rar-h); margin-top: calc(var(--rar-h) / -2);
  padding: 0 calc(3cqw - .13em) 0 3cqw; border-radius: 999px; background: #0d0e13; border: 1px solid rgba(var(--rc-rgb), .6); color: var(--rc);
  font: 800 max(9px, 3.9cqw)/1 var(--font); letter-spacing: .13em; text-transform: uppercase; white-space: nowrap; }
.bxc__rar::before { content: ''; flex: 0 0 auto; width: max(4px, 1.6cqw); height: max(4px, 1.6cqw); border-radius: 50%; background: currentColor; }
/* Taille : 6,6 cqw (12 px au moins), baissée pour un nom au mot très large (--nw posé par card.js, en em) afin
   que ce mot tienne sur sa ligne au lieu de se couper au milieu (« AboveTheKloud », puis « z » dessous) ;
   9 px au plus bas. */
.bxc__name { max-width: 100%; margin: 2.6cqw 0 0; font: 800 max(9px, min(max(12px, 6.6cqw), calc(86cqw / var(--nw, 1))))/1.12 var(--font); letter-spacing: -.01em; color: #fff; text-wrap: balance; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.bxc__ab { display: flex; align-items: center; justify-content: center; gap: 1.4cqw; max-width: 100%; margin: 1.4cqw 0 0;
  font: 600 max(10px, 4.2cqw)/1.25 var(--font); color: var(--ink-2); }
.bxc__ab::before { content: ''; flex: 0 0 auto; width: 1.6cqw; height: 1.6cqw; min-width: 4px; min-height: 4px; background: var(--rc); transform: rotate(45deg); }
.bxc__ab span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bxc__abt { display: none; max-width: 100%; margin: 1.6cqw 0 0; font: 400 max(11px, 3.7cqw)/1.4 var(--font); color: var(--ink-3);
  -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.bxc__stats { flex: 0 0 auto; margin-top: auto; box-sizing: border-box; width: 100%; display: flex; justify-content: space-between; align-items: baseline;
  padding: 2cqw 1cqw 0; border-top: 1px solid rgba(255, 255, 255, .08);
  font: 700 max(10px, 5cqw)/1 var(--mono); font-variant-numeric: tabular-nums; word-spacing: -.32em; white-space: nowrap; }
.bxc__stats i { margin-right: 1.4cqw; font: 800 max(9px, 3.3cqw)/1 var(--font); font-style: normal; letter-spacing: .12em; color: var(--ink-3); }
.bxc__stats .atk { color: #ffb4a8; }
.bxc__stats .def { color: #a8c8ff; }

/* ---------- Petite, moyenne, grande, très petite ---------- */

@container bxc (max-width: 179px) {
  .bxc__fam, .bxc__ab, .bxc__abt, .bxc__chroma span { display: none; }
  .bxc__chroma { padding: max(3px, 1.4cqw); }
  /* Sans capacité, le nom se pose au milieu de la plaque au lieu de laisser un vide au-dessus d'ATQ / DÉF.
     La respiration du bas est une bordure transparente, pas une marge intérieure : overflow coupe au bord
     de la marge intérieure, qui laissait voir le haut d'une 3e ligne sous les points de suspension. */
  .bxc__name { margin: auto 0; padding: 1.6cqw 0 0; border-bottom: 1.6cqw solid transparent; }
  .bxc__stats { margin-top: 0; }
  /* « Nouvelle » prend le coin haut gauche, libre en petite taille (pas de famille) : en bas à droite,
     elle s'empilait sur la pastille de rareté, 4 px plus bas et aussi large qu'elle. « V2 » garde alors
     le coin bas droit pour elle seule. */
  .bxc__new { top: 3cqw; right: auto; bottom: auto; left: 3cqw; }
  .bxc__new ~ .bxc__v2 { bottom: var(--bdg-b); }
}
/* Moyenne et grande : le bloc nom et capacité se centre entre la pastille et ATQ / DÉF (une marge
   automatique au-dessus du nom, l'autre au-dessus des chiffres) au lieu de laisser tout le vide en bas.
   Moyenne : sans nom de capacité (il répète celui de la carte), son texte prend la place sur deux lignes. */
@container bxc (min-width: 180px) {
  .bxc__name { margin-top: auto; padding-top: 2.6cqw; }
  .bxc__abt.is-solo { display: -webkit-box; -webkit-line-clamp: 2; }
}
/* Chromatique et nouvelle à la fois (récapitulatif) : sous 220 px, les deux pastilles ne tiennent plus
   côte à côte en bas de la fenêtre, la chromatique se réduit à son point irisé. */
@container bxc (min-width: 180px) and (max-width: 219px) {
  .bxc__chroma:has(~ .bxc__new) { padding: max(3px, 1.4cqw); }
  .bxc__chroma:has(~ .bxc__new) span { display: none; }
}
@container bxc (min-width: 300px) { .bxc__abt, .bxc__abt.is-solo { display: -webkit-box; -webkit-line-clamp: 3; } .bxc__name { -webkit-line-clamp: 3; } }
/* Sous 130 px, ATQ et DÉF ne tiennent plus avec leurs libellés : la couleur suffit. */
@container bxc (max-width: 129px) { .bxc__stats i { display: none; } .bxc__stats { justify-content: space-around; } }
/* Très petite (« Et aussi » de la vitrine, sachets, grille d'échange sur téléphone) : l'illustration
   seule dans sa fenêtre teintée.
   Les dessins en petite taille sont réglés après leurs règles de base (fin de la section des dessins). */
@container bxc (max-width: 99px) {
  .bxc__in { padding: 4cqw; }
  .bxc__win { flex: 1 1 auto; border-radius: 6px; }
  .bxc__plate, .bxc__tr, .bxc__new, .bxc__v2, .bxc__chroma, .bxc__lock, .bxc__title .k, .bxc__update .k, .bxc__update .d,
  .bxc__swatch b, .bxc__swatch small { display: none; }
  .bxc[data-fit="contain"] .bxc__win img { padding: 10cqw; filter: none; }
}

/* ---------- Raretés hautes : cadre dégradé, reflet ---------- */

.bxc[data-r="4"]::before, .bxc[data-r="5"]::before, .bxc[data-r="6"]::before, .bxc[data-chroma]::before {
  content: ''; position: absolute; inset: 0; z-index: 3; border-radius: inherit; padding: 1.5px; pointer-events: none;
  background: linear-gradient(150deg, var(--rc2), var(--rc) 40%, rgba(255, 255, 255, .7) 50%, var(--rc) 60%, var(--rc2));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
/* Reflet au survol : carte vivante seulement (fiche, révélation, vitrine), une seule traversée. */
.bxc.is-live[data-r="5"]:hover::after, .bxc.is-live[data-r="6"]:hover::after, .bxc.is-live[data-chroma]:hover::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 60%; z-index: 4; pointer-events: none;
  background: linear-gradient(115deg, transparent 20%, rgba(255, 255, 255, .32) 50%, transparent 80%);
  mix-blend-mode: soft-light; animation: bxc-sheen .75s ease-out 1 forwards; }
@keyframes bxc-sheen { to { transform: translateX(270%); } }

/* ---------- Chromatique : liseré arc-en-ciel, fines lignes sur la plaque ---------- */

/* Le liseré fait le tour de la carte dans tout le spectre (--chroma-ring, tokens.css), plus épais que celui
   des raretés pour se lire au premier coup d'oeil, dans une grille comme en grand ; la rareté reste écrite sur
   sa pastille et teinte la fenêtre. Fixe : rien ne tourne en boucle sur une carte (§5.4). */
.bxc[data-chroma]::before { padding: max(2px, 1.1cqw); background: var(--chroma-ring); }
.bxc[data-chroma] .bxc__plate::before { content: ''; position: absolute; inset: 0 -3.2cqw -3.2cqw; z-index: -1; pointer-events: none;
  background: repeating-linear-gradient(115deg, rgba(255, 255, 255, .05) 0 1px, transparent 1px 7px),
              linear-gradient(115deg, rgba(255, 77, 77, .10), rgba(255, 224, 74, .08), rgba(63, 224, 138, .08), rgba(41, 200, 242, .10), rgba(180, 92, 255, .10)); }
/* Reflet au survol d'un chromatique vivant (fiche, révélation, vitrine) : une seule traversée, irisée. */
.bxc.is-live[data-chroma]:hover::after {
  background: linear-gradient(115deg, transparent 18%, rgba(255, 77, 77, .5) 30%, rgba(255, 224, 74, .5) 40%, rgba(63, 224, 138, .5) 50%, rgba(41, 200, 242, .5) 60%, rgba(180, 92, 255, .5) 70%, transparent 82%);
  mix-blend-mode: overlay; }

/* ---------- Silhouette (carte manquante) ---------- */

.bxc[data-missing] { background: #0d0e12; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07); }
.bxc[data-missing]::before, .bxc[data-missing]::after { content: none; }
.bxc[data-missing] .bxc__win { background: #121319; }
.bxc[data-missing][data-fit="contain"] .bxc__win img { filter: brightness(0) invert(1); opacity: .09; }
.bxc[data-missing][data-fit="cover"] .bxc__win img, .bxc[data-missing] .bxc__win > div { display: none; }
.bxc__q { position: absolute; inset: 0; display: grid; place-items: center; font: 900 22cqw/1 var(--display); color: rgba(255, 255, 255, .07); }
.bxc[data-missing] .bxc__rar { color: rgba(var(--rc-rgb), .75); border-color: rgba(var(--rc-rgb), .3); }
.bxc[data-missing] .bxc__name { color: var(--ink-3); }
.bxc[data-missing] .bxc__ab { color: var(--ink-4); }
.bxc[data-missing] .bxc__ab::before { opacity: .5; }
.bxc[data-missing] .bxc__stats, .bxc[data-missing] .bxc__stats .atk, .bxc[data-missing] .bxc__stats .def { color: var(--ink-4); }

/* ---------- Illustrations dessinées (dans la fenêtre, à la place de l'image) ---------- */

/* Titres : le texte du titre, comme au-dessus de la tête d'un joueur, sans surtitre (.is-nok) : la plaque
   écrit son type (« Titre n° 065 », décision D8 de ratox, écart au cahier §5.6). Même composition pour une
   carte sans image, avec en surtitre son type tiré du catalogue ou sa famille (BM.cardHtml, nameArtHtml).
   Une grille : surtitre, nom, deux traits (très petite taille) et filet, entre deux rangées souples de même
   part qui gardent le bloc au milieu de la fenêtre. Une rangée souple ne passe jamais sous son minimum
   (--tpt en haut, --tpb en bas) : la marge de la fenêtre (--tp), le haut de la pastille de rareté, et la
   place d'un badge posé à ce coin (--ct-* et --cb-*, fin de la section des dessins). Un nom haut descend
   alors sous le favori ou le cadenas, ou monte au-dessus du point chromatique, au lieu de passer dessous ;
   un nom court reste au milieu. */
.bxc__title { --tp: 8cqw; --tg: 2.4cqw;
  --tpt: max(var(--tp), var(--ct-tr, 0px), var(--ct-lock, 0px), var(--ct-new, 0px));
  --tpb: max(var(--tp), calc(var(--rar-h) / 2 + var(--bm)), var(--cb-chroma, 0px), var(--cb-new, 0px), calc(var(--cb-dot, 0px) - var(--tg) - 1px));
  /* Hauteur du surtitre et de son écart (0 quand il est masqué), puis taille maximale du nom pour que le bloc
     tienne entre les deux minimums : hauteur de la fenêtre (60 % de 133,6 cqw) moins les minimums, le surtitre,
     l'écart et le filet, partagée entre les --tn lignes que card.js a comptées. Sans badge, elle reste au-dessus
     de --tf : elle ne joue que quand un badge réserve sa place. */
  --kh: calc(max(9px, 3.4cqw) + var(--tg));
  --th: calc((80.16cqw - var(--tpt) - var(--tpb) - var(--kh) - var(--tg) - 1px) / (var(--tn, 1) * 1.02));
  position: absolute; inset: 0; display: grid; justify-items: center;
  /* Une colonne de la largeur exacte de la zone de texte : un surtitre plus large (cartes de 100 px) déborde
     des deux côtés à parts égales au lieu d'élargir la colonne et de pousser le bloc d'un pixel. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(var(--tpt), 1fr) auto auto auto auto minmax(var(--tpb), 1fr);
  padding: 0 var(--tpx, var(--tp));
  background: radial-gradient(80% 60% at 50% 45%, rgba(var(--rc-rgb), .16), transparent 75%), #121319; }
.bxc__title .k { grid-row: 2; margin: 0 -.3em var(--tg) 0; font: 800 max(9px, 3.4cqw)/1 var(--font); letter-spacing: .3em; text-transform: uppercase; color: rgba(255, 255, 255, .45); white-space: nowrap; }
.bxc__title.is-nok { --kh: 0px; }   /* pas de surtitre (titre) : sa hauteur ne se retranche pas de la place du nom */
/* Le nom remplit la fenêtre : 11 cqw, moins quand son mot le plus large ou son nombre de lignes l'exige.
   Taille (--tf, en cqw) et lignes permises (--tl) sont calculées par card.js (nameFit) sur la largeur des
   lettres : aucun nom n'est coupé par des points de suspension ni au milieu d'un mot, de 100 à 360 px.
   --th ne la baisse que pour laisser sa place à un badge. */
.bxc__title b { grid-row: 3; max-width: 100%; font: 900 max(9px, min(calc(var(--tf, 11) * 1cqw), var(--th)))/1.02 var(--display); letter-spacing: -.02em; color: var(--tc, #fff); text-wrap: balance; overflow-wrap: normal;
  display: -webkit-box; -webkit-line-clamp: var(--tl, 4); -webkit-box-orient: vertical; overflow: hidden; }
/* Deux traits à la place du nom, quand la carte est trop petite pour l'écrire (fin de la section des dessins) :
   un titre au-dessus d'un nom, dans la couleur du titre, au-dessus du filet de rareté. */
.bxc__lines { grid-row: 4; display: none; width: 50cqw; height: 11cqw; margin-bottom: 2cqw;
  background: linear-gradient(var(--tc, #fff) 0 0) top / 100% 4.4cqw no-repeat, linear-gradient(var(--tc, #fff) 0 0) bottom / 64% 4.4cqw no-repeat; }
.bxc__title.is-unique .bxc__lines { --tc: #f2c14e; }
.bxc__title::after { content: ''; grid-row: 5; width: 12cqw; height: 1px; margin-top: var(--tg); background: rgba(var(--rc-rgb), .7); }
.bxc__title.is-unique { background: #120f07; }
.bxc__title.is-unique b { color: #f2c14e; }
.bxc__title.is-unique::after { background: rgba(242, 193, 78, .7); }
.bxc__title.is-unique::before { content: ''; position: absolute; inset: 3cqw; border: 1px solid rgba(242, 193, 78, .4); border-radius: 6px; pointer-events: none; }

/* Couleurs de titre : un nuancier de peintre. Il s'arrête au-dessus des badges de la fenêtre au lieu de
   passer dessous (cahier §5.5) : en bas quand la carte porte « Nouvelle » ou la chromatique, en haut
   quand elle porte le favori ou le nombre d'exemplaires (et « Nouvelle » en petite taille). */
.bxc__win:has(> .bxc__chroma, > .bxc__new) { --sw-b: calc(var(--bdg-b) + var(--bdg-h) + 1.6cqw); }
.bxc__win:has(> .bxc__tr) { --sw-t: calc(4.6cqw + max(16px, 7cqw)); }
.bxc__swatch { position: absolute; inset: var(--sw-t, 9cqw) 13cqw var(--sw-b, 9cqw); display: flex; flex-direction: column; border-radius: 3cqw; overflow: hidden; background: #f4f1ea;
  box-shadow: 0 2cqw 4cqw rgba(0, 0, 0, .45); text-align: left; }
.bxc__swatch i { flex: 1 1 auto; min-height: 0; background: var(--sc); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .08); }
.bxc__swatch.is-rainbow i { background: linear-gradient(120deg, #ff5f6d, #ffc371, #7cf29b, #5fb3ff, #b28cff); }
.bxc__swatch b { padding: 2.4cqw 3cqw 0; font: 800 max(9px, 3.8cqw)/1.1 var(--font); color: #1a1a1f; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bxc__swatch small { padding: .6cqw 3cqw 2.4cqw; font: 500 max(9px, 3.2cqw)/1 var(--mono); color: #55555f; }

/* Auras : les flammes, formes pleines sans flou. */
.bxc__aura { position: absolute; inset: 0; display: grid; place-items: center; background: #10111a; }
.bxc__aura svg { width: 62%; height: 82%; }

/* Mises à jour : composition typographique (numéro et date). Même grille que les titres : le bloc reste au
   milieu, et les rangées souples ne passent jamais sous la place d'un badge (--ct-*, --cb-*) ; la date, large,
   reste au-dessus du point chromatique. */
.bxc__update { position: absolute; inset: 0; display: grid; justify-items: center; padding: 0 4cqw; text-align: center;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(max(var(--ct-tr, 0px), var(--ct-lock, 0px), var(--ct-new, 0px)), 1fr) auto auto auto minmax(max(var(--cb-chroma, 0px), var(--cb-new, 0px), var(--cb-dot, 0px)), 1fr);
  background: radial-gradient(80% 60% at 50% 45%, rgba(var(--rc-rgb), .14), transparent 75%), #121319; }
.bxc__update .k { grid-row: 2; margin: 0 -.3em 1.6cqw 0; font: 800 max(9px, 3.4cqw)/1 var(--font); letter-spacing: .3em; text-transform: uppercase; color: rgba(255, 255, 255, .45); white-space: nowrap; }
.bxc__update b { grid-row: 3; font: 900 max(28px, 26cqw)/.9 var(--display); letter-spacing: -.04em; color: #fff; white-space: nowrap; }
.bxc__update b.is-mid { font-size: max(22px, 19cqw); }
.bxc__update b.is-long { font-size: max(18px, 14cqw); }
.bxc__update .d { grid-row: 4; margin-top: 1.6cqw; font: 500 max(9px, 3.4cqw)/1 var(--mono); color: var(--ink-3); white-space: nowrap; }
/* Fiche d'une carte sans image (drawnHtml de card.js) : la composition d'une mise à jour, le fait marquant
   (« +15 % », « 167 500 ») à la taille que card.js a calculée sur sa largeur (--ff, en cqw), puis sa légende
   dans la police du texte, sur deux lignes au plus. */
.bxc__update.is-fact b { font-size: max(16px, calc(var(--ff, 14) * 1cqw)); }
.bxc__update.is-fact .d { max-width: 100%; margin-top: 2cqw; font: 600 max(9px, 3.6cqw)/1.2 var(--font); color: var(--ink-2); white-space: normal; text-wrap: balance; }

/* Dessins en petite taille. Ces règles suivent les règles de base : une requête de conteneur n'ajoute
   aucune priorité, placées plus haut elles seraient écrasées. */
/* Petite taille : « Nouvelle » est en haut à gauche, le nuancier descend sous elle ; en bas, seul le
   point de la chromatique reste à éviter. */
@container bxc (max-width: 179px) {
  .bxc__win:has(> .bxc__new) { --sw-t: calc(4.6cqw + max(16px, 7cqw)); --sw-b: 9cqw; }
  .bxc__win:has(> .bxc__chroma) { --sw-b: calc(var(--bdg-b) + var(--bdg-h) + 1.6cqw); }
}
/* Place des badges dans la fenêtre d'un titre ou d'une carte sans image (rangées souples de .bxc__title) :
   bas d'un badge du haut, haut d'un badge du bas, plus l'écart --bm. Mêmes mesures que les badges (section
   « Badges » plus haut) : elles changent avec eux. La très petite taille n'a pas de badge. */
@container bxc (min-width: 100px) {
  .bxc__win:has(> .bxc__tr) { --ct-tr: calc(3cqw + max(16px, 7cqw) + var(--bm)); }
  .bxc__win:has(> .bxc__lock) { --ct-lock: calc(3cqw + max(18px, 8cqw) + var(--bm)); }
  .bxc__win:has(> .bxc__chroma) { --cb-chroma: calc(var(--bdg-b) + var(--bdg-h) + var(--bm)); }
  .bxc__win:has(> .bxc__new) { --cb-new: calc(var(--bdg-b) + var(--bdg-h) + var(--bm)); }
}
/* Petite taille : « Nouvelle » passe en haut à gauche, et la chromatique n'est plus qu'un point au bord
   gauche. Le filet, étroit et centré, peut descendre à la hauteur du point : .bxc__title retranche l'écart
   et le filet de --cb-dot. Badge en haut et point en bas à la fois : il ne reste entre les deux que le nom
   d'un titre ou le numéro d'une mise à jour ; surtitre et date s'effacent, comme la famille, que les petites
   cartes n'écrivent pas. */
@container bxc (min-width: 100px) and (max-width: 179px) {
  .bxc__win:has(> .bxc__new) { --cb-new: 0px; --ct-new: calc(3cqw + var(--bdg-h) + var(--bm)); }
  .bxc__win:has(> .bxc__chroma) { --cb-chroma: 0px; --cb-dot: calc(var(--bdg-b) + 2 * max(3px, 1.4cqw) + max(8px, 2.2cqw) + var(--bm)); }
  .bxc__win:has(> .bxc__tr, > .bxc__lock, > .bxc__new):has(> .bxc__chroma) > .bxc__title { --kh: 0px; }
  .bxc__win:has(> .bxc__tr, > .bxc__lock, > .bxc__new):has(> .bxc__chroma) > :is(.bxc__title, .bxc__update) .k,
  .bxc__win:has(> .bxc__tr, > .bxc__lock, > .bxc__new):has(> .bxc__chroma) > .bxc__update .d { display: none; }
}
/* Surtitre long (classe is-longk posée par card.js : « Capacité d'admin », « Enchantement ») : sous 180 px il
   prend le lettrage serré des petites cartes ; sous 140 px il sortirait de la fenêtre, le nom reste seul
   (comme la famille, que les cartes de moins de 180 px n'écrivent pas). */
@container bxc (max-width: 179px) {
  .bxc__title.is-longk .k, .bxc__update.is-longk .k { margin-right: -.16em; letter-spacing: .16em; }
}
@container bxc (max-width: 139px) {
  .bxc__title.is-longk { --kh: 0px; }
  .bxc__title.is-longk .k, .bxc__update.is-longk .k { display: none; }
}
/* Sous 160 px : les surtitres (« Mise à jour », famille d'une carte sans image) se resserrent pour tenir, et
   le nom prend moins de marge (sa taille reste celle de nameFit, calculée pour la fenêtre la plus étroite). */
@container bxc (max-width: 159px) {
  .bxc__title .k, .bxc__update .k { margin-right: -.16em; letter-spacing: .16em; }
  .bxc__title { --tp: 6cqw; --tg: 1.6cqw; }
}
/* Très petite (« Et aussi » de la vitrine, grille d'échange, sachets) : le nom reste écrit, en 9 px et
   sans surtitre, tant que son plus long mot tient sur une ligne (« OFFICIAL » fait 46 px, la fenêtre
   d'une carte de 88 px en offre 75). Là où il serait coupé au milieu d'un mot (sous 80 px de large, et
   sous 100 px pour un mot de plus de 7,5 em, .is-longword), deux traits dans la couleur du titre (or pour
   un titre unique) prennent sa place au-dessus du filet : jamais une initiale, qui se lirait comme un
   monogramme sans rapport avec la carte. Le nuancier d'une couleur de titre se réduit à sa pastille. */
@container bxc (max-width: 99px) {
  .bxc__title { --tp: 5cqw; --tpx: 3.5cqw; --tg: 3cqw; --tpt: var(--tp); --tpb: var(--tp); }   /* ni plaque ni badge : la marge seule */
  .bxc__title b { font-size: 9px; letter-spacing: -.02em; -webkit-line-clamp: 8; }
  .bxc__title::after { width: 18cqw; }
  .bxc__title.is-longword b { display: none; }
  .bxc__title.is-longword .bxc__lines { display: block; }
  .bxc__title.is-longword::after { width: 20cqw; }
  .bxc__title.is-unique::before { inset: 2cqw; border-radius: 4px; }
  .bxc__swatch { inset: 12cqw; border-radius: 4cqw; }
}
@container bxc (max-width: 79px) {
  .bxc__title b { display: none; }
  .bxc__lines { display: block; }
  .bxc__title::after { width: 20cqw; }
}

/* ---------- Inclinaison (fiche, révélation, vitrine) ---------- */

.bxc.is-tilt { transform: perspective(800px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .45s var(--ease), box-shadow .2s var(--ease); }
.bxc.is-tilting { transition: transform .12s ease-out, box-shadow .2s var(--ease); }
.bxc__glare { position: absolute; inset: 0; z-index: 4; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity .3s var(--ease);
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, .22), transparent 55%); mix-blend-mode: soft-light; }
.bxc.is-tilting .bxc__glare { opacity: 1; }

/* ---------- Carte dans une grille ----------
   .bx-grid et .bx-cardbtn sont dans components.css. Ici : l'ombre qui se creuse au survol (seul effet
   en grille avec le soulèvement de 4 px) et la grille serrée des choix d'équipe. */

@media (hover: hover) {
  .bx-cardbtn:hover .bxc { --bxc-drop: 0 22px 40px -16px rgba(0, 0, 0, .85); }
}
.bx-grid--sm { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 12px; }
@media (max-width: 600px) { .bx-grid--sm { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; } }

/* ---------- Dos ---------- */

.bxb { --bk: #0e1520; --bk-line: rgba(217, 164, 65, .55); --bk-line2: rgba(217, 164, 65, .22); --bk-ink: #e6dbc3; --bk-drop: rgba(0, 0, 0, .5);
  container: bxb / inline-size; position: relative; display: block; width: 100%; aspect-ratio: 5 / 7; border-radius: 12px; overflow: hidden;
  background: var(--bk); background-image: var(--bk-pat, none); box-shadow: var(--shadow-card);
  user-select: none; -webkit-user-select: none; }
.bxb::before { content: ''; position: absolute; inset: 4cqw; border-radius: 8px; border: 1px solid var(--bk-line); pointer-events: none; }
.bxb::after { content: ''; position: absolute; inset: 5.8cqw; border-radius: 6px; border: 1px solid var(--bk-line2); pointer-events: none; }
.bxb__in { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7cqw; }
/* Le logo (44cqw) garde 7cqw de marge en haut et en bas : il occupe la même hauteur que l'emblème fruit
   (58cqw), et le mot reste à la même hauteur sur les sept dos d'une rangée. */
.bxb__emb { display: block; width: 44cqw; height: 44cqw; margin: 7cqw 0; object-fit: cover; border-radius: 24%; box-shadow: 0 0 0 1.2cqw var(--bk-line), 0 4cqw 8cqw var(--bk-drop); }
.bxb__emb.is-fruit { width: 58cqw; height: 58cqw; margin: 0; object-fit: contain; border-radius: 0; box-shadow: none; filter: drop-shadow(0 3cqw 4cqw var(--bk-drop)); }
.bxb__word { margin-right: -.14em; font: 900 max(9px, 5.6cqw)/1 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--bk-ink); white-space: nowrap; }
@container bxb (max-width: 119px) { .bxb__word { display: none; } .bxb__emb { width: 52cqw; height: 52cqw; } .bxb__emb.is-fruit { width: 66cqw; height: 66cqw; } }

.bxb[data-back="marine"] { --bk: #e6dbc3; --bk-line: rgba(23, 36, 58, .55); --bk-line2: rgba(23, 36, 58, .22); --bk-ink: #17243a; --bk-drop: rgba(23, 36, 58, .28);
  --bk-pat: repeating-linear-gradient(0deg, rgba(23, 36, 58, .08) 0 1px, transparent 1px 9px); }
.bxb[data-back="pirate"] { --bk: #0b0b0e; --bk-line: rgba(230, 219, 195, .55); --bk-line2: rgba(230, 219, 195, .22); --bk-ink: #e6dbc3; }
.bxb[data-back="kitsune"] { --bk: #0c1a3a; --bk-line: rgba(143, 196, 255, .55); --bk-line2: rgba(143, 196, 255, .22); --bk-ink: #cfe4ff; }
.bxb[data-back="dragon"] { --bk: #2a0d0d; --bk-line: rgba(217, 164, 65, .55); --bk-line2: rgba(217, 164, 65, .22); --bk-ink: #f2d9a8; }
.bxb[data-back="leviathan"] { --bk: #062b30; --bk-line: rgba(94, 127, 119, .75); --bk-line2: rgba(94, 127, 119, .32); --bk-ink: #bfe6e3;
  --bk-pat: repeating-linear-gradient(170deg, rgba(60, 196, 201, .1) 0 2px, transparent 2px 16px); }
.bxb[data-back="capitaine"] { --bk: #0d1b2e; --bk-line: rgba(242, 193, 78, .55); --bk-line2: rgba(242, 193, 78, .22); --bk-ink: #f2c14e;
  --bk-pat: repeating-linear-gradient(45deg, rgba(242, 193, 78, .07) 0 1px, transparent 1px 12px), repeating-linear-gradient(-45deg, rgba(242, 193, 78, .07) 0 1px, transparent 1px 12px); }
/* Annonce de la rareté avant le retournement (ouverture) : cadre de 3 px, couleur lue sur --rc-rgb d'un parent. */
.bxb.is-announce { box-shadow: inset 0 0 0 3px rgba(var(--rc-rgb, 255, 255, 255), .7), var(--shadow-card); }

/* ---------- Vignette de liste (BM.miniHtml, BM.miniVisHtml) ----------
   Le gabarit (.bx-mini, .bx-mini__vis de 40 px teintée) est dans components.css ; ici, ce que la carte
   y ajoute : image en retrait d'un pixel pour garder le filet de rareté visible, dessins, chromatique,
   silhouette, textes. Les sélecteurs [data-r] passent devant ceux du gabarit quel que soit l'ordre. */

.bx-mini { color: inherit; text-align: left; }
.bx-mini__vis[data-r] { position: relative; display: grid; place-items: center; box-sizing: border-box; }
.bx-mini__vis[data-r] img { position: absolute; inset: 1px; display: block; box-sizing: border-box; width: calc(100% - 2px); height: calc(100% - 2px); border-radius: 9px; object-fit: cover; }
.bx-mini__vis.is-contain[data-r] img { object-fit: contain; padding: 4px; }
/* Capture d'origine recadrée (quelques ennemis et boss) : même boîte haute que dans la carte ; le découpage
   remet le bord arrondi et le filet de rareté d'un pixel que l'image agrandie recouvrirait. */
.bx-mini__vis[data-crop] img { top: calc(1px + (100% - 2px) * var(--crop-top)); bottom: auto; height: calc((100% - 2px) * var(--crop-h));
  object-position: center var(--crop-y); border-radius: 0; clip-path: inset(calc(var(--crop-t) * 100%) 0 calc(var(--crop-b) * 100%) round 9px); }
.bx-mini__vis svg { width: 60%; height: 78%; }
.bx-mini__glyph { font: 900 15px/1 var(--display); letter-spacing: -.02em; color: #fff; }   /* numéro d'une mise à jour, « ? » */
/* Titre ou carte sans image : la fenêtre du titre en réduction, comme la carte en très petite taille.
   Deux traits dans la couleur du titre (blancs sans image), comme un titre au-dessus d'un nom, puis le filet
   de la rareté ; traits, filet et cadre or pour un titre unique. Les traits sont épais et serrés comme deux
   lignes de texte, le filet fin et plus bas souligne le bloc (comme dans la fenêtre de la carte) : on ne lit
   pas trois barres égales. Tout se mesure en % de la vignette (40 px d'une liste, 32 px d'une équipe,
   médaillon de guilde). Posée à 1 px du bord comme une image, pour garder le filet de rareté de la vignette.
   Au-delà de 40 px (emblème de guilde de 56 à 112 px), traits, écart et filet sont plafonnés : deux lignes
   fines et un filet serré dessous, jamais deux pavés qu'on lirait comme une icône de menu. */
.bx-mini__title { position: absolute; inset: 1px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: min(15%, 7px);
  border-radius: inherit; background: radial-gradient(80% 60% at 50% 45%, rgba(var(--rc-rgb), .16), transparent 75%), #121319; }
.bx-mini__lines { display: block; flex: 0 0 auto; width: 60%; height: min(28%, 12px);
  background: linear-gradient(var(--tc, #fff) 0 0) top / 100% 40% no-repeat, linear-gradient(var(--tc, #fff) 0 0) bottom / 62% 40% no-repeat; }
.bx-mini__title::after { content: ''; flex: 0 0 auto; width: 24%; height: max(1px, min(3%, 2px)); background: rgba(var(--rc-rgb), .9); }
.bx-mini__title.is-unique { background: #120f07; }
.bx-mini__title.is-unique::before { content: ''; position: absolute; inset: 9%; border: 1px solid rgba(242, 193, 78, .45); border-radius: inherit; pointer-events: none; }
.bx-mini__title.is-unique .bx-mini__lines { --tc: #f2c14e; }
.bx-mini__title.is-unique::after { background: #f2c14e; }
.bx-mini__sw { width: 22px; height: 22px; border-radius: 6px; background: var(--sc); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
.bx-mini__sw.is-rainbow { background: linear-gradient(120deg, #ff5f6d, #ffc371, #7cf29b, #5fb3ff, #b28cff); }
.bx-mini__vis[data-chroma] { box-shadow: none; }
.bx-mini__vis[data-chroma]::after { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: inherit; padding: 2px; pointer-events: none;
  background: var(--chroma-ring);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; }
.bx-mini__vis[data-missing] { background: #121319; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07); }
.bx-mini__vis[data-missing] img { filter: brightness(0) invert(1); opacity: .12; }
.bx-mini__vis[data-missing] .bx-mini__glyph { color: rgba(255, 255, 255, .16); }

.bx-mini__txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bx-mini__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 700 15px/1.25 var(--font); color: var(--ink); }
.bx-mini__serial { margin-left: 2px; font: 500 13px/1 var(--font); color: var(--ink-3); }
.bx-mini__serial b { font: 500 13px/1 var(--mono); font-variant-numeric: tabular-nums; word-spacing: -.32em; }
.bx-mini__meta { display: flex; align-items: center; min-width: 0; overflow: hidden; white-space: nowrap; font: 500 13px/1.3 var(--font); color: var(--ink-3); }
.bx-mini__meta > span { flex: 0 0 auto; }
.bx-mini__meta > span + span::before { content: '·'; margin: 0 6px; color: var(--ink-4); }
.bx-mini__rar { color: var(--rc); font-weight: 700; }
.bx-mini__chroma { color: var(--ink-2); }
.bx-mini__chroma i { display: inline-block; width: 7px; height: 7px; margin-right: 5px; border-radius: 50%; vertical-align: 1px;
  background: var(--chroma-ring); }
.bx-mini__meta > .bx-mini__sub { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ---------- Capacité en entier (BM.abilityHtml : fiche, duel, raid) ---------- */

.bx-ability { padding: 14px 16px; border-radius: 14px; background: rgba(var(--rc-rgb), .06); border-left: 3px solid var(--rc); text-align: left; }
.bx-ability__n { display: block; font: 700 15px/1.35 var(--font); color: var(--ink); }
.bx-ability__t { margin: 0; font: 400 14px/1.5 var(--font); color: var(--ink-2); }
.bx-ability__n + .bx-ability__t { margin-top: 4px; }

/* ---------- Mouvement réduit : ni inclinaison, ni reflet, ni transition ---------- */

@media (prefers-reduced-motion: reduce) {
  .bxc.is-tilt { transform: none; }
  .bxc.is-live:hover::after, .bxc__glare { display: none; }
  .bx-cardbtn { transition: none; }
}
body.reduce-motion .bxc.is-tilt { transform: none; }
body.reduce-motion .bxc.is-live:hover::after, body.reduce-motion .bxc__glare { display: none; }
body.reduce-motion .bx-cardbtn { transition: none; }


/* ===== css/opening.css ===== */
/* BloxMasters : le paquet (objet) et la scène d'ouverture (cahier de design §6).
   Le sachet sert aussi hors de la scène (page Paquets, boutique) : BM.packHtml(kind) dans
   src/js/opening.js ; sa largeur se pose sur le conteneur, la hauteur suit (25 / 36).
   La carte révélée et le dos viennent de BM.cardHtml / BM.backHtml (style dans card.css). */

/* ---------- Le paquet ---------- */

.bx-pack {
  --pk: #17243a; --pk2: #0e1520; --pk-accent: #d9a441;
  container: bx-pack / inline-size;
  box-sizing: border-box; position: relative; display: block; width: 100%; aspect-ratio: 25 / 36;
  border-radius: 12px; overflow: hidden; isolation: isolate;
  background:
    linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .07) 45%, transparent 55%),
    linear-gradient(170deg, var(--pk), var(--pk2));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08), var(--shadow-card);
  color: #fff; text-align: center;
  user-select: none; -webkit-user-select: none;
}
/* Sertissage haut et bas : fines dents et un filet de la couleur du paquet. */
.bx-pack::before, .bx-pack::after { content: ''; position: absolute; z-index: 1; left: 0; right: 0; height: 6%; pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, .1) 0 2px, transparent 2px 6px); }
.bx-pack::before { top: 0; border-bottom: 1px solid var(--pk-accent); }
.bx-pack::after { bottom: 0; border-top: 1px solid var(--pk-accent); }

.bx-pack__band { position: absolute; z-index: 2; top: 10%; left: 5%; right: 5%; }
.bx-pack__band span { display: block; margin-right: -.3em; font: 800 max(11px, 4cqw)/1 var(--font); letter-spacing: .3em; text-transform: uppercase; color: rgba(255, 255, 255, .7); }
/* overflow: hidden (pour l'ellipse) rognait l'accent du « É » (« DOUBLE LÉGENDE ») qui dépasse le haut de la
   ligne : un quart de hauteur de lettre est ajouté au-dessus (padding-top), et la marge du haut le rend, le nom
   ne bouge pas. */
.bx-pack__band b { display: block; margin-top: calc(2.4cqw - .25em); padding-top: .25em; font: 900 max(13px, 8.6cqw)/1 var(--display); letter-spacing: -.01em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Nom long (« Double Légende ») : plus petit, pour tenir en entier sur la bande. */
.bx-pack__band b.is-long { margin-top: calc(3.2cqw - .25em); font-size: max(11px, 6.4cqw); }

.bx-pack__art { position: absolute; z-index: 2; left: 17%; top: 28%; width: 66%; height: 40%; max-width: none; object-fit: contain;
  filter: drop-shadow(0 4cqw 5cqw rgba(0, 0, 0, .5)); pointer-events: none; }
.bx-pack__art.is-small { object-fit: scale-down; }                 /* image du wiki en 152 px : jamais agrandie */
/* Carte posée en biais : la vraie carte du jeu, rendue à sa taille (palier XS ou S de card.css).
   Centrée entre le nom (bas vers 20 % de la hauteur) et le sceau (haut à 72 %), sans toucher ni l'un
   ni l'autre : 42 % de large, soit 43 % de la hauteur une fois tournée. */
.bx-pack__art.is-card { left: 29%; top: 25.5%; width: 42%; height: auto; transform: rotate(-5deg); filter: none; }
.bx-pack__art.is-card .bxc { --bxc-drop: 0 3cqw 6cqw rgba(0, 0, 0, .45); }

.bx-pack__seal { position: absolute; z-index: 3; left: 39%; bottom: 13%; width: 22%; aspect-ratio: 1; border-radius: 50%; overflow: hidden;
  background: #0b0b10; box-shadow: 0 0 0 2px var(--pk-accent), 0 2cqw 4cqw rgba(0, 0, 0, .45); }
.bx-pack__seal img { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.bx-pack__seal.is-gem img { box-sizing: border-box; padding: 15%; object-fit: contain; }

.bx-pack__count { position: absolute; z-index: 2; left: 0; right: 0; bottom: 7.5%; margin-right: -.14em;
  font: 700 max(11px, 4cqw)/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: rgba(255, 255, 255, .6); }

/* Variantes (cahier §6.1) */
.bx-pack[data-kind="onyx"], .bx-pack[data-kind="onyx_legende"], .bx-pack[data-kind="onyx_mythique"] { --pk: #15151c; --pk2: #08080b; }
.bx-pack[data-kind="onyx"] { --pk-accent: #c9cbd6; }
.bx-pack[data-kind="onyx_legende"], .bx-pack[data-kind="legende"] { --pk-accent: #d52be4; }
.bx-pack[data-kind="onyx_mythique"] { --pk-accent: #ee2f32; }
.bx-pack[data-kind="combat"] { --pk: #1a1d24; --pk2: #0c0d11; }
.bx-pack[data-kind="boss"] { --pk: #2a0f12; --pk2: #120708; }
.bx-pack[data-kind="monde"] { --pk: #0f2a2c; --pk2: #081516; }
.bx-pack[data-kind="titres"] { --pk: #1d1608; --pk2: #0c0a05; --pk-accent: #f2c14e; }
.bx-pack[data-kind="mer1"] { --pk-accent: #4fc8df; }
.bx-pack[data-kind="mer2"] { --pk-accent: #8f63ff; }
.bx-pack[data-kind="mer3"] { --pk-accent: #ee2f32; }
/* Paquet de bienvenue (tout premier paquet du joueur, garanti) : bande « Bienvenue » et liseré Légendaire.
   Avant le doré : un premier paquet doré garde la couleur du doré. */
.bx-pack.is-welcome { --pk-accent: #d52be4; box-shadow: inset 0 0 0 1.5px #d52be4, var(--shadow-card); }
/* Paquet doré et paquet chromatique (result.special), posés à l'arrivée de la réponse. */
.bx-pack.is-gold { --pk: #2a2108; --pk2: #120e04; --pk-accent: #f2c14e; }
.bx-pack.is-chroma { border: 2px solid transparent;
  background:
    linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .07) 45%, transparent 55%) padding-box,
    linear-gradient(170deg, var(--pk), var(--pk2)) padding-box,
    var(--chroma) border-box; }

/* Petits sachets (rangée de paquets premium, boutique) : on garde l'objet, on retire le texte qui ne tient plus. */
@container bx-pack (max-width: 159px) {
  .bx-pack__art { filter: none; }
  .bx-pack__band span, .bx-pack__count { display: none; }
  .bx-pack__band { top: 11%; }
  .bx-pack__band b { font-size: max(11px, 8.6cqw); }
  .bx-pack__band b.is-long { white-space: normal; line-height: 1.05; text-wrap: balance; }   /* « Double / Légende » sous 135 px */
  .bx-pack__art.is-card { top: 23.5%; }            /* le nom, seul, s'arrête vers 17 % */
}
@container bx-pack (max-width: 109px) {
  .bx-pack__band { display: none; }
  .bx-pack__art { top: 19%; height: 48%; }
  .bx-pack__art.is-card { left: 27%; top: 17%; width: 46%; }   /* sans nom : centrée entre le sertissage et le sceau */
  .bx-pack__seal { box-shadow: 0 0 0 1.5px var(--pk-accent); }
}

/* Paquet posé sur sa page (page Paquets, scène) : léger flottement et ombre de sol.
   Utilisation : <div class="bx-packfloat" style="width:240px">BM.packHtml(...)</div> */
.bx-packfloat { position: relative; }
.bx-packfloat > .bx-pack { animation: bx-pack-float 4s ease-in-out infinite; }
.bx-packfloat::after { content: ''; position: absolute; left: 50%; top: calc(100% + 12px); width: min(220px, 92%); height: 26px; translate: -50% 0; pointer-events: none;
  background: radial-gradient(closest-side, rgba(0, 0, 0, .55), transparent); animation: bx-pack-ground 4s ease-in-out infinite; }
@keyframes bx-pack-float { 50% { translate: 0 -12px; } }
@keyframes bx-pack-ground { 50% { scale: .86 1; opacity: .7; } }

/* ---------- La scène ---------- */

.bx-op {
  --ts: 1;
  --chrome: 312px;                                   /* barre du haut (64) + informations (168) + pied (65) + 15 */
  --cw: min(360px, 78vw, max(170px, calc((100dvh - var(--chrome)) * 5 / 7)));    /* carte révélée, rendue à sa taille */
  --pw: min(260px, 62vw, max(150px, calc((100dvh - var(--chrome)) * 25 / 36)));  /* paquet */
  position: fixed; inset: 0; z-index: var(--z-scene, 140);
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto; overflow: hidden;
  background: #070709; color: #fff; font-family: var(--font);
  touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
  outline: none; animation: bx-op-fade .3s ease-out;
}
@supports not (height: 100dvh) {
  .bx-op { --cw: min(360px, 78vw, max(170px, calc((100vh - var(--chrome)) * 5 / 7)));
    --pw: min(260px, 62vw, max(150px, calc((100vh - var(--chrome)) * 25 / 36))); }
}
/* Grand écran : le sachet passe à 320 px au plus (à 260 px, il paraissait petit sur un écran de PC). Même
   objet, aucun effet ajouté. */
@media (min-width: 1200px) and (min-height: 820px) {
  .bx-op { --pw: min(320px, 62vw, max(150px, calc((100dvh - var(--chrome)) * 25 / 36))); }
  @supports not (height: 100dvh) { .bx-op { --pw: min(320px, 62vw, max(150px, calc((100vh - var(--chrome)) * 25 / 36))); } }
}
.bx-op.is-closing { opacity: 0; transition: opacity .25s ease; pointer-events: none; }
.bx-op [hidden] { display: none !important; }
/* Notifications pendant la scène : en haut, juste sous sa barre, à toutes les largeurs. En bas, elles couvraient
   la barre d'actions collée et son bouton principal (« Succès débloqué » au récapitulatif des premiers paquets).
   Une fenêtre ouverte par-dessus la scène les remonte tout en haut (components.css). Un toucher sur l'une
   d'elles : opening.js (onToastClick). */
body.bx:has(> .bx-op):not(:has(.bx-modal)) .bx-toasts { top: calc(max(14px, env(safe-area-inset-top, 0px)) + 62px); bottom: auto; }

/* Fond : la bannière officielle floutée et assombrie d'avance (assets/scene*.webp). Si le fichier
   manque, il reste le dégradé neutre de la dernière couche. */
.bx-op__bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .55;
  background-color: #070709;
  background-image: url('/bloxmasters/assets/scene.webp'), radial-gradient(70% 60% at 50% 42%, #191922, #070709 72%);
  background-position: center; background-size: cover; background-repeat: no-repeat; }
html[data-theme="halloween"] .bx-op__bg { background-image: url('/bloxmasters/assets/scene-halloween.webp'), url('/bloxmasters/assets/scene.webp'), radial-gradient(70% 60% at 50% 42%, #191922, #070709 72%); }
html[data-theme="noel"] .bx-op__bg { background-image: url('/bloxmasters/assets/scene-noel.webp'), url('/bloxmasters/assets/scene.webp'), radial-gradient(70% 60% at 50% 42%, #191922, #070709 72%); }
.bx-op__bg::after { content: ''; position: absolute; inset: 0; background: radial-gradient(60% 55% at 50% 45%, rgba(7, 7, 9, .2), rgba(7, 7, 9, .88)); }
.bx-op__veil { position: absolute; inset: 0; z-index: 1; background: #000; opacity: 0; pointer-events: none; transition: opacity calc(.45s * var(--ts)) ease; }
.bx-op__fx { position: absolute; inset: 0; z-index: 6; width: 100%; height: 100%; pointer-events: none; }
/* Bandes noires du Divin */
.bx-op__bars { position: absolute; inset: 0; z-index: 7; pointer-events: none; }
.bx-op__bars::before, .bx-op__bars::after { content: ''; position: absolute; left: 0; right: 0; height: 0; background: #000; transition: height calc(.6s * var(--ts)) var(--ease-out); }
.bx-op__bars::before { top: 0; } .bx-op__bars::after { bottom: 0; }
.bx-op.is-cinema .bx-op__bars::before, .bx-op.is-cinema .bx-op__bars::after { height: 11vh; }

/* Barre du haut */
.bx-op__top { position: relative; z-index: 9; display: flex; align-items: center; gap: 8px;
  padding: max(14px, env(safe-area-inset-top, 0px)) 16px 14px; }
/* Interligne 1.35 et non 1 : overflow: hidden (pour l'ellipse) rognait l'accent du « É » de RÉCAPITULATIF. */
.bx-op__count { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 800 13px/1.35 var(--display); letter-spacing: .08em; text-transform: uppercase; color: rgba(255, 255, 255, .7); }
.bx-op__spacer { flex: 1 1 auto; }
.bx-op__top .bx-btn { min-height: 36px; background: rgba(255, 255, 255, .06); }
.bx-op__top .bx-btn:hover { background: rgba(255, 255, 255, .1); }
.bx-op__top .bx-btn--icon { width: 36px; padding: 0; }
/* « Vitesse x1 » : le mot en Archivo, la valeur en mono (largeur fixe d'une vitesse à l'autre). */
.bx-op__speed { gap: .32em; min-width: 46px; }
.bx-op__speedv { font-family: var(--mono); font-variant-numeric: tabular-nums; }
@media (max-width: 960px) {
  .bx-op__top .bx-btn { min-height: 40px; }
  .bx-op__top .bx-btn--icon { width: 40px; }
}
/* Très petit écran : la valeur seule, le compteur de cartes garde sa place. */
@media (max-width: 359px) {
  .bx-op__speedw { display: none; }
}

/* Scène : tout s'empile dans la même case, centré. */
.bx-op__stage { position: relative; z-index: 4; display: grid; place-items: center; min-height: 0; perspective: 1400px; }
.bx-op__stage > * { grid-area: 1 / 1; }
.bx-op.is-quake .bx-op__stage { animation: bx-op-quake .4s linear; }

/* ---------- Le paquet dans la scène, et sa déchirure ---------- */

.bx-op__packwrap { position: relative; transition: opacity calc(.4s * var(--ts)) ease; }
.bx-op__pack { --tl: 8%; --tear: 0; --cut: 0; --fdir: 1;
  position: relative; width: var(--pw); cursor: pointer; touch-action: none;
  animation: bx-op-drop calc(.6s * var(--ts)) var(--ease-out) backwards, bx-pack-float 4s ease-in-out calc(.6s * var(--ts)) infinite; }
.bx-op__ground { position: absolute; left: 50%; top: calc(100% + 14px); width: min(220px, 85%); height: 26px; translate: -50% 0; pointer-events: none;
  background: radial-gradient(closest-side, rgba(0, 0, 0, .55), transparent);
  animation: bx-op-groundin calc(.6s * var(--ts)) var(--ease-out) backwards, bx-pack-ground 4s ease-in-out calc(.6s * var(--ts)) infinite; }
/* Le flottement continue pendant la sortie (même nom dans la liste) : pas de saut. */
.bx-op__packwrap.is-gone .bx-op__pack { animation: bx-op-packout calc(.5s * var(--ts)) ease-in forwards, bx-pack-float 4s ease-in-out calc(.6s * var(--ts)) infinite; pointer-events: none; }
.bx-op__packwrap.is-gone .bx-op__ground { opacity: 0; transition: opacity calc(.3s * var(--ts)) ease; }

/* Perforation : là où le sachet se déchire, juste sous le sertissage. */
.bx-op__perf { position: absolute; z-index: 4; left: 7%; right: 7%; top: var(--tl); height: 1px; pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, .34) 0 4px, transparent 4px 8px); transition: opacity .2s ease; }
.bx-op__pack.is-tearing .bx-op__perf { opacity: 0; }
/* La bande à déchirer se signale : un trait de pointillés plus clair parcourt la perforation de gauche à
   droite, trois fois, puis s'arrête (aucune boucle ; coupé en mouvement réduit, voir la fin du fichier). */
.bx-op__perf::after { content: ''; position: absolute; left: 0; top: -1px; width: 28%; height: 3px; opacity: 0;
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, .95) 0 4px, transparent 4px 8px); }
.bx-op.is-pack .bx-op__perf::after { animation: bx-op-perfhint calc(1.3s * var(--ts)) var(--ease) calc(.9s * var(--ts)) 3; }
@keyframes bx-op-perfhint { 0% { transform: translateX(0); opacity: 0; } 15%, 80% { opacity: 1; } 100% { transform: translateX(257%); opacity: 0; } }
/* Rabat : copie vide du sachet, découpée au-dessus de la dentelure ; le sachet garde le reste. */
.bx-op__flap { position: absolute; inset: 0; z-index: 3; width: auto; aspect-ratio: auto; visibility: hidden; pointer-events: none;
  clip-path: var(--clip-t);
  transform-origin: 100% var(--tl);
  transform: rotate(calc(var(--tear) * var(--fdir) * 7deg)) translateY(calc(var(--tear) * -4px));
  transition: transform .22s var(--ease-out); }
.bx-op__pack.from-right .bx-op__flap { transform-origin: 0% var(--tl); }
.bx-op__pack.is-grab .bx-op__flap { transition: none; }
.bx-op__pack.is-tearing .bx-op__flap { visibility: visible; }
.bx-op__pack.is-tearing .bx-op__main { clip-path: var(--clip-b); }
.bx-op__flap.is-off { animation: bx-op-flapoff calc(.7s * var(--ts)) cubic-bezier(.3, 0, .7, 1) forwards; }
/* Fente qui suit le doigt */
.bx-op__cut { position: absolute; z-index: 5; left: 0; top: calc(var(--tl) - 1px); width: calc(var(--cut) * 100%); height: 2px; border-radius: 1px;
  background: rgba(255, 255, 255, .92); pointer-events: none; transition: width .22s var(--ease-out); }
.bx-op__pack.is-grab .bx-op__cut { transition: none; }
.bx-op__pack.from-right .bx-op__cut { left: auto; right: 0; }
.bx-op__pack.is-open .bx-op__cut { opacity: 0; transition: opacity .2s ease; }
/* Fuite de lumière : une bande plate de 6 px à la couleur de la meilleure carte (blanche en anti-spoil). */
.bx-op__leak { position: absolute; z-index: 2; left: 4%; right: 4%; top: calc(var(--tl) - 3px); height: 6px; pointer-events: none; opacity: 0;
  background: linear-gradient(90deg, transparent, var(--leak, #fff), transparent); transition: opacity calc(.35s * var(--ts)) ease; }
.bx-op.is-leaking .bx-op__leak { opacity: .85; }
/* Zone de prise : le haut du sachet, un peu plus large que lui pour le pouce. */
.bx-op__strip { position: absolute; z-index: 6; left: -14px; right: -14px; top: -18px; height: calc(var(--pw) * 36 / 25 * .08 + 40px); cursor: ew-resize; touch-action: none; }

/* ---------- Pile et carte révélée ---------- */

.bx-op__deck { position: relative; width: var(--cw); aspect-ratio: 5 / 7; animation: bx-op-deckin calc(.4s * var(--ts)) var(--ease-out) backwards; }
.bx-op__deck > div { position: absolute; inset: 0; }

.bx-op__focus { position: relative; z-index: 5; width: var(--cw); aspect-ratio: 5 / 7; transform-style: preserve-3d; }
.bx-op__flip { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform calc(.3s * var(--ts)) cubic-bezier(.3, .7, .3, 1); }
.bx-op__flip.is-slow { transition-duration: calc(.7s * var(--ts)); }
.bx-op__flip.is-up { transform: rotateY(180deg); }
.bx-op__back, .bx-op__face { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.bx-op__face { transform: rotateY(180deg); }
.bx-op__back .bxb { transition: box-shadow calc(.25s * var(--ts)) ease; }

.bx-op__focus.is-enter { animation: bx-op-enter calc(.32s * var(--ts)) var(--ease-out) backwards; }
.bx-op__focus.is-tense { animation: bx-op-tremble calc(.14s * var(--ts)) linear 6; }
.bx-op__focus.is-beat { animation: bx-op-beat calc(.46s * var(--ts)) ease-out; }
.bx-op__focus.is-pop { animation: bx-op-pop calc(.24s * var(--ts)) ease-out; }
.bx-op__focus.is-out { animation: bx-op-out calc(.34s * var(--ts)) ease-in forwards; pointer-events: none; }
/* Lumière au sol sous la carte révélée (Rare et au-dessus) : la seule lumière colorée de la scène. */
.bx-op__floor { position: absolute; left: 15%; right: 15%; top: calc(100% + 8px); height: 28px; pointer-events: none; opacity: 0;
  background: radial-gradient(closest-side, rgba(var(--rc-rgb), .35), transparent); transition: opacity calc(.5s * var(--ts)) ease; }
.bx-op__focus.is-lit .bx-op__floor { opacity: 1; }

/* Calque des tampons et de l'onde de choc, à la taille de la carte. */
.bx-op__marks { position: relative; z-index: 8; width: var(--cw); aspect-ratio: 5 / 7; pointer-events: none; }
.bx-op__shock { position: absolute; left: 50%; top: 50%; width: 40%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%;
  border: 2px solid rgba(var(--rc-rgb, 255, 255, 255), .9); pointer-events: none; animation: bx-op-shock calc(.8s * var(--ts)) var(--ease-out) forwards; }

/* Tampons : allure de tampon encreur, entrée d'un coup, sans flou. */
.bx-op__stamp { position: absolute; z-index: 2; left: 50%; top: 9%; translate: -50% 0; rotate: -4deg;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; box-sizing: border-box;
  width: max-content; max-width: min(calc(100vw - 32px), calc(var(--cw) + 48px));
  padding: 9px 16px 8px; border: 2px solid currentColor; border-radius: 8px; background: rgba(7, 7, 9, .78); color: #fff;
  font: 900 clamp(14px, 1.6vw, 17px)/1.15 var(--display); letter-spacing: .06em; text-transform: uppercase; text-align: center;
  animation: bx-op-stamp calc(.38s * var(--ts)) cubic-bezier(.2, .9, .3, 1.04) backwards; }
.bx-op__stamp.is-out { opacity: 0; transition: opacity calc(.4s * var(--ts)) ease; }
.bx-op__stamp.is-divin { top: 8%; padding: 10px 22px 9px; color: #f2c14e; font-size: clamp(26px, 4.4vw, 42px); }
/* Premier exemplaire et boussole : posés en coin, à cheval sur le bord de la carte, jamais sur le
   nom ni au milieu de l'illustration (cahier §5.5). Le premier en haut à droite, sur le bord haut :
   assez haut pour que son extrémité gauche, relevée, passe au-dessus de la pastille de famille sans
   la toucher ; la boussole en bas à gauche, sous les chiffres ATQ / DÉF. Les deux peuvent tomber sur
   la même carte sans se gêner. */
.bx-op__stamp.is-first { top: -22px; right: -18px; left: auto; translate: none; rotate: 4deg; color: #fff; font-size: clamp(13px, 1.4vw, 15px); }
.bx-op__stamp.is-compass { top: auto; bottom: -30px; left: -18px; translate: none; rotate: -3deg; color: var(--accent-2); font-size: clamp(13px, 1.4vw, 15px); }
.bx-op__stamp.is-gold { color: #f2c14e; }
.bx-op__stamp.is-chroma { color: #fff; }
.bx-op__stamp.is-chroma i { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
  background: var(--chroma-ring); }
.bx-op__stamp.is-onpack { top: 38%; }
.bx-op__packwrap .bx-op__stamp { z-index: 8; }
/* Téléphone : la carte ne fait plus que 300 px environ et le tampon en 13 px en prenait toute la
   largeur. En 12 px, plus serré et rentré dans le coin, il laisse la famille libre. */
@media (max-width: 600px) {
  .bx-op__stamp.is-first, .bx-op__stamp.is-compass { padding: 7px 12px 6px; font-size: 12px; }
  .bx-op__stamp.is-first { right: -6px; }
  .bx-op__stamp.is-compass { left: -6px; }
}

/* ---------- Informations sous la carte ---------- */

/* Hauteur minimale : un nom sur deux lignes, les pastilles, le numéro et la ligne du favori. La carte ne
   bouge donc pas d'une carte à l'autre ; seul le texte d'une capacité écrit ici (petit écran) l'agrandit. */
.bx-op__info { position: relative; z-index: 9; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; gap: 7px;
  width: min(560px, 100%); min-height: 168px; margin: 0 auto; padding: 6px 16px 0; text-align: center; }
.bx-op.is-pack .bx-op__info { min-height: 0; padding: 0; }   /* le paquet se centre dans toute la hauteur */
.bx-op__info.is-in > * { animation: bx-op-rise calc(.3s * var(--ts)) var(--ease-out) backwards; }
.bx-op__info.is-in > :nth-child(2) { animation-delay: calc(.04s * var(--ts)); }
.bx-op__info.is-in > :nth-child(3) { animation-delay: calc(.08s * var(--ts)); }
.bx-op__info.is-in > :nth-child(n + 4) { animation-delay: calc(.12s * var(--ts)); }
.bx-op__name { margin: 0; max-width: 100%; font: 800 1.5rem/1.15 var(--font); letter-spacing: -.01em; color: #fff; text-wrap: balance; overflow-wrap: anywhere; }
.bx-op__pills { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.bx-op__serial { margin: 0; font: 500 13px/1.3 var(--mono); color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* Texte de la capacité, seulement quand la carte ne peut pas l'écrire en entier (opening.js). */
.bx-op__ab { margin: 0; max-width: 520px; font: 400 14px/1.45 var(--font); color: var(--ink-2); text-wrap: pretty; }
.bx-op__ab b { font-weight: 700; color: var(--ink); }
/* Explication sous la carte (une carte que la boussole a changée). */
.bx-op__note { margin: 0; max-width: 520px; font: 500 13px/1.45 var(--font); color: var(--ink-2); text-wrap: balance; }
.bx-op__tag { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; margin-top: 2px; }
.bx-op__fav[aria-pressed="true"] { color: var(--ink); border-color: rgba(245, 196, 81, .5); }
.bx-op__fav[aria-pressed="true"] svg { color: #f5c451; }

/* Pied : points de progression et indication */
.bx-op__foot { position: relative; z-index: 9; display: grid; justify-items: center; gap: 12px;
  padding: 10px 16px calc(16px + env(safe-area-inset-bottom, 0px)); }
.bx-op__dots { display: flex; justify-content: center; gap: 8px; }
.bx-op__dots i { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, .18); transition: background-color .3s ease, scale .3s var(--ease); }
.bx-op__dots i.is-done { background: var(--rc, #fff); }
.bx-op__dots i.is-cur { background: #fff; scale: 1.375; }
.bx-op__hint { margin: 0; min-height: 19px; font: 500 13px/1.45 var(--font); color: var(--ink-3); text-align: center; text-wrap: balance; }
.bx-op__hint .bx-spin { width: 16px; height: 16px; vertical-align: -3px; }
/* Phase du paquet : la consigne du geste, plus grande et plus claire. Sur un écran assez haut, elle se pose
   juste sous l'ombre de sol du sachet au lieu du bas de l'écran (le sachet reste centré dans la scène : son
   centre est à mi-hauteur plus la moitié de la barre du haut). */
.bx-op.is-pack .bx-op__hint { max-width: 460px; margin: 0 auto; font-size: 15px; color: var(--ink-2); }
@media (min-height: 600px) {
  .bx-op.is-pack .bx-op__foot { position: absolute; left: 0; right: 0; padding-top: 0;
    top: calc(50% + 34px + env(safe-area-inset-top, 0px) / 2 + var(--pw) * .72 + 50px); }
}

/* ---------- Plusieurs paquets : la pile et sa pastille ---------- */

/* Deux sachets décalés derrière le premier ; ils tombent, flottent et sortent avec lui. Le nombre de
   paquets du lot est sur une pastille en coin du premier sachet. */
.bx-op__stack { position: absolute; left: 0; top: 0; width: var(--pw); aspect-ratio: 25 / 36; pointer-events: none;
  animation: bx-op-drop calc(.6s * var(--ts)) var(--ease-out) backwards, bx-pack-float 4s ease-in-out calc(.6s * var(--ts)) infinite; }
.bx-op__stack .bx-pack { position: absolute; inset: 0; width: 100%; }
.bx-op__stack .bx-pack:first-child { transform: translate(-16px, 12px) rotate(-6deg); opacity: .45; }
.bx-op__stack .bx-pack:last-child { transform: translate(14px, 7px) rotate(4deg); opacity: .62; }
.bx-op__packwrap.is-gone .bx-op__stack { animation: bx-op-packout calc(.5s * var(--ts)) ease-in forwards; }
.bx-op__mult { position: absolute; z-index: 7; right: -14px; top: 17%; display: grid; place-items: center; min-width: 52px; height: 52px; padding: 0 12px;
  box-sizing: border-box; border-radius: 99px; background: var(--accent); color: var(--on-accent); pointer-events: none;
  font: 900 1.3rem/1 var(--display); letter-spacing: -.01em; font-variant-numeric: tabular-nums;
  box-shadow: 0 10px 22px -10px rgba(0, 0, 0, .8); animation: bx-op-stamp calc(.38s * var(--ts)) cubic-bezier(.2, .9, .3, 1.04) calc(.5s * var(--ts)) backwards; }
.bx-op__pack.is-tearing .bx-op__mult { opacity: 0; transition: opacity .2s ease; }

/* ---------- La rafale : toutes les cartes face cachée, retournées en vague ---------- */

/* La taille des cartes (--bw) et le nombre de colonnes viennent d'opening.js (fit) : la plus grande taille
   qui fait tenir la grille dans la scène. Sur un très petit écran, la grille défile. */
.bx-op.is-burst .bx-op__info { min-height: 0; padding-top: 4px; }
.bx-op__burst { position: relative; z-index: 4; display: grid; grid-template-columns: repeat(var(--cols, 5), var(--bw, 120px)); gap: var(--gap, 10px);
  justify-content: center; align-content: safe center; max-width: 100%; max-height: 100%; overflow-y: auto; overscroll-behavior: contain;
  padding: 6px 8px 14px; box-sizing: border-box; perspective: 1400px; transition: opacity calc(.3s * var(--ts)) ease; }
.bx-op__burst.is-dim { opacity: .18; }
.bx-op__bcell { position: relative; width: var(--bw, 120px); aspect-ratio: 5 / 7; transform-style: preserve-3d;
  animation: bx-op-rise calc(.3s * var(--ts)) var(--ease-out) backwards; }
.bx-op__bcell .bx-op__flip { transition-duration: calc(.26s * var(--ts)); }
/* Rare et mieux : le bord du dos annonce la rareté avant le retournement (pas en anti-spoil). */
.bx-op__bcell.is-announce:not(.is-up) .bxb { box-shadow: inset 0 0 0 3px rgba(var(--rc-rgb), .75), var(--shadow-card); }
.bx-op__bcell.is-pop { animation: bx-op-pop calc(.24s * var(--ts)) ease-out; }
/* Lumière au sol sous les cartes Rare et mieux, comme sous la carte révélée. */
.bx-op__bcell::after { content: ''; position: absolute; left: 12%; right: 12%; top: calc(100% + 1px); height: 10px; pointer-events: none; opacity: 0;
  background: radial-gradient(closest-side, rgba(var(--rc-rgb), .4), transparent); transition: opacity calc(.4s * var(--ts)) ease; }
.bx-op__bcell.is-lit::after { opacity: 1; }
.bx-op__tally { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }

/* ---------- Récapitulatif ---------- */

/* Ordre, pour un paquet comme pour un lot (opening.js, showSummary) : les chiffres, la ligne de l'album, les
   collections qui avancent (sous les cartes sur téléphone), puis les cartes, la meilleure d'abord, et les
   actions. Sur téléphone, la barre d'actions collée ne couvre donc que les cartes les moins rares ; si elle
   couvrait la meilleure (écran bas, barre haute), elle reprend sa place sous les cartes (.is-flow, posé par
   opening.js). */
.bx-op.is-summary .bx-op__stage, .bx-op.is-summary .bx-op__info, .bx-op.is-summary .bx-op__foot { display: none; }
.bx-op__sum { position: relative; z-index: 8; grid-row: 2 / -1; grid-column: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; padding: 8px 16px calc(28px + env(safe-area-inset-bottom, 0px)); }
/* Cartes de 207,2 px (+ 16 px d'écart = 223,2) : taille M sur PC (cahier §5.3), avec le libellé de
   famille et le nom de la capacité. Sur un écran plus étroit, les cartes rétrécissent et repassent en S
   sous 200 px. Toutes les cartes ont la même taille (cahier §6.5). */
.bx-op__suminner { width: 100%; max-width: min(1100px, calc(var(--cols, 5) * 223.2px - 16px)); margin: auto; }
.bx-op__fan { display: grid; grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr)); gap: 16px; align-items: start; margin-top: 26px; }
/* Une case : la carte, et sous elle la pastille « Nouvelle » et le bouton « Partager » s'il y a lieu. */
.bx-op__cell { display: flex; flex-direction: column; align-items: center; gap: 10px; min-width: 0;
  animation: bx-op-rise calc(.36s * var(--ts)) var(--ease-out) backwards; }
.bx-op__share { max-width: 100%; }
@media (max-width: 700px) {
  .bx-op__fan { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 12px; }
  .bx-op__sum:not(.is-many) .bx-op__cell:last-child:nth-child(odd) { grid-column: 1 / -1; justify-self: center; width: calc(50% - 6px); }
  .bx-op__sum.is-many .bx-op__fan { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 8px; }
}

.bx-op__facts { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; row-gap: 16px; margin-top: 6px; }
.bx-op__fact { position: relative; display: grid; justify-items: center; gap: 9px; padding: 0 clamp(16px, 3vw, 30px); }
.bx-op__fact + .bx-op__fact::before { content: ''; position: absolute; left: 0; top: 0; width: 1px; height: 32px; background: rgba(255, 255, 255, .14); }
.bx-op__fact b { font: 900 clamp(1.35rem, 1rem + 1.6vw, 2rem)/1 var(--display); letter-spacing: -.02em; color: #fff; font-variant-numeric: tabular-nums; white-space: nowrap; }
.bx-op__fact span { font: 800 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
.bx-op__pity { display: flex; justify-content: center; margin-top: 16px; }
.bx-op__pity .bx-pill { height: auto; min-height: 26px; padding-block: 5px; white-space: normal; text-align: center; line-height: 1.3; }
/* Progression de l'album (« Album : 424 cartes sur 2 179 (19,5 %), dont +5 avec ce paquet. Voir l'album ») :
   toute la ligne mène à l'album, la scène se ferme d'abord. */
.bx-op__album { display: block; max-width: 100%; min-height: 40px; margin: 12px auto 0; padding: 8px 14px; box-sizing: border-box;
  border: 0; border-radius: 12px; background: none; cursor: pointer;
  font: 500 14px/1.45 var(--font); color: var(--ink-2); text-align: center; text-wrap: balance; transition: background-color .15s ease; }
.bx-op__album:hover { background: rgba(255, 255, 255, .05); }
.bx-op__album b { color: #fff; font-weight: 800; }
.bx-op__albumgo { display: inline-flex; align-items: center; gap: 5px; color: var(--accent-2); font-weight: 700; white-space: nowrap; }
.bx-op__albumgo svg { width: 15px; height: 15px; }
/* Collections que l'ouverture fait avancer : nom, compte, barre ; terminée en vert, avec un lien vers Succès. */
.bx-op__sets { display: grid; gap: 8px; width: min(520px, 100%); margin: 14px auto 0; }
.bx-op__set { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px 12px; width: 100%; padding: 11px 14px; box-sizing: border-box;
  border-radius: 12px; background: rgba(255, 255, 255, .04); border: 1px solid var(--line); color: var(--ink-2); text-align: left; cursor: pointer;
  font: 600 13px/1.35 var(--font); transition: border-color .2s ease, background-color .2s ease; }
.bx-op__set:hover { border-color: var(--accent-line); background: rgba(255, 255, 255, .06); }
.bx-op__setname { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.bx-op__setname svg { flex: 0 0 auto; width: 14px; height: 14px; }
.bx-op__set .bx-num { color: #fff; font-weight: 700; }
.bx-op__set .bx-bar { grid-column: 1 / -1; }
.bx-op__set.is-done { border-color: var(--ok-line); background: var(--ok-dim); color: var(--ok); }

/* Récapitulatif d'un lot : cartes plus petites en grille libre, actions collées en bas. */
.bx-op__sum.is-many .bx-op__suminner { max-width: 1240px; margin: 0 auto; }
.bx-op__sum.is-many .bx-op__fan { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px 12px; }
.bx-op__sum.is-many .bx-op__actions { position: sticky; bottom: 0; z-index: 2; margin: 18px -16px 0; padding: 26px 16px calc(16px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(180deg, rgba(4, 4, 5, 0), #040405 26px); }
/* « Et maintenant ? » en tête de la barre collée : le fondu s'arrête plus tôt, le libellé se lit sur un fond plein
   au lieu de s'écrire sur le titre de la carte du dessous (toutes les largeurs ; téléphone plus bas). */
.bx-op__sum.is-many .bx-op__actions.is-next { padding-top: 24px; background: linear-gradient(180deg, rgba(4, 4, 5, 0), #040405 12px); }
.bx-op__sum.is-many { padding-bottom: 0; }
@media (max-width: 700px) {
  /* Téléphone : trois cartes par rangée (taille S) ; cette règle vient après la grille libre ci-dessus. */
  .bx-op__sum.is-many .bx-op__fan { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 8px; }
}
/* Actions. Le conteneur reste vide le temps de lire la boutique (bloc « Et maintenant ? ») : rien ne s'affiche. */
.bx-op__actions { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px; margin-top: 28px; }
.bx-op__actions:empty { display: none; }
.bx-op__actions .bx-btn.is-done { color: var(--ok); background: var(--ok-dim); border-color: var(--ok-line); pointer-events: none; }
/* « Et maintenant ? » (plus rien du même type à ouvrir) : micro-libellé, puis la minuterie du prochain paquet
   gratuit quand la réserve est vide (sauf coffre à ouvrir), sur leur propre ligne au-dessus des boutons. */
.bx-op__nexthead { flex: 0 0 100%; margin: 0; font: 800 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); text-align: center; }
.bx-op__wait { flex: 0 0 100%; margin: 0; font: 500 14px/1.45 var(--font); color: var(--ink-2); text-align: center; }
.bx-op__wait .bx-time { color: #fff; }
/* Sur deux colonnes (cahier §6.5), les cartes dépassent l'écran et les actions passaient sous le pli : elles
   restent collées au bas de l'écran pendant le défilement, sur un fondu de la couleur du fond de la scène
   (#040405 : --bg sous le voile noir à .5 du récapitulatif, mesuré sur les captures), puis reprennent leur
   place sous les cartes. La marge du bas passe du conteneur à la barre : sinon elle resterait vide sous
   la barre collée, avec les cartes visibles dessous. */
@media (max-width: 700px) {
  .bx-op__sum { padding-bottom: 0; }
  .bx-op__actions { position: sticky; bottom: 0; z-index: 2; margin: 0 -16px; padding: 26px 16px calc(14px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(180deg, rgba(4, 4, 5, 0), #040405 26px); gap: 8px; }
  .bx-op__fan ~ .bx-op__actions { margin-top: 12px; }
  /* « Et maintenant ? » en tête de la barre : le fondu s'arrête plus tôt, le libellé se lit sur un fond plein. */
  .bx-op__actions.is-next, .bx-op__sum.is-many .bx-op__actions.is-next { padding-top: 24px; background: linear-gradient(180deg, rgba(4, 4, 5, 0), #040405 12px); }
  /* Collections sous les cartes (opening.js) : au-dessus, elles repoussaient la meilleure carte hors du premier écran. */
  .bx-op__fan + .bx-op__sets { margin-top: 22px; }
}
@media (max-width: 600px) {
  /* Le bouton principal sur toute la largeur, les autres côte à côte dessous, un peu moins hauts : la barre
     collée garde peu de hauteur. Le gain de la défausse s'affiche sur le bouton une fois la défausse faite,
     comme dans la barre de sélection de l'album. */
  .bx-op__actions .bx-btn { flex: 1 1 auto; padding: 0 16px; white-space: normal; text-align: center; }
  .bx-op__actions .bx-btn:not(.bx-btn--primary) { min-height: 46px; }
  .bx-op__actions .bx-btn--primary, .bx-op__actions .is-refill { flex-basis: 100%; }
  .bx-op__amt { display: none; }
  /* Les trois chiffres restent sur une ligne : chaque colonne prend la largeur de son chiffre et c'est
     le libellé qui passe à la ligne. Le filet garde la hauteur du chiffre, comme sur grand écran. */
  .bx-op__facts { display: grid; grid-template-columns: repeat(3, auto); justify-content: center; }
  /* Quatre chiffres (lot de paquets) : deux par ligne. */
  .bx-op__facts.is-four { grid-template-columns: repeat(2, auto); row-gap: 18px; }
  .bx-op__facts.is-four .bx-op__fact:nth-child(3)::before { display: none; }
  .bx-op__fact { --fact: clamp(1.05rem, 5.4vw, 1.5rem); padding: 0 clamp(6px, 2.4vw, 14px); }
  .bx-op__fact + .bx-op__fact::before { height: var(--fact); }
  .bx-op__fact b { font-size: var(--fact); }
  .bx-op__fact span { line-height: 1.3; white-space: normal; text-align: center; text-wrap: balance; }
  .bx-op__album { font-size: 13px; }
}
/* Très petit écran : la rareté peut à son tour passer sur deux lignes (« Peu / commun »). Les boutons
   secondaires, plus serrés, tiennent sur une seule rangée sous le bouton principal (42 px de haut). */
@media (max-width: 359px) {
  .bx-op__fact { --fact: 1rem; padding: 0 6px; }
  .bx-op__fact b { line-height: 1.1; white-space: normal; text-align: center; }
  .bx-op__actions .bx-btn:not(.bx-btn--primary) { min-height: 42px; padding: 0 10px; font-size: .84rem; }
}
/* Barre collée qui couvrirait la meilleure carte (opening.js, fitBar) : d'abord sans « Fermer » (.is-tight, la
   croix de la barre du haut ferme aussi la scène), sinon à sa place sous les cartes, sans fondu (.is-flow). */
.bx-op__actions.is-tight > [data-done] { display: none; }
.bx-op__sum .bx-op__actions.is-flow, .bx-op__sum.is-many .bx-op__actions.is-flow { position: static; background: none; }

/* ---------- Animations ---------- */

@keyframes bx-op-fade { from { opacity: 0; } }
@keyframes bx-op-rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes bx-op-drop { from { transform: translateY(-62vh) rotate(-6deg); } 72% { transform: translateY(8px) rotate(.6deg); } to { transform: none; } }
@keyframes bx-op-groundin { from { opacity: 0; scale: .4 1; } }
@keyframes bx-op-packout { to { transform: translateY(42vh) rotate(5deg); opacity: 0; } }
@keyframes bx-op-flapoff { to { transform: translate(calc(var(--fdir) * 32vw), -46vh) rotate(calc(var(--fdir) * 34deg)); opacity: 0; } }
@keyframes bx-op-deckin { from { opacity: 0; transform: translateY(40px) scale(.94); } }
@keyframes bx-op-enter { from { opacity: 0; transform: scale(.92); } }
@keyframes bx-op-tremble { 25% { transform: translate(-1.5px, .5px) rotate(-.4deg); } 75% { transform: translate(1.5px, -.5px) rotate(.4deg); } }
@keyframes bx-op-beat { 18% { transform: scale(1.03); } 36% { transform: scale(.995); } 54% { transform: scale(1.018); } }
@keyframes bx-op-pop { 50% { transform: scale(1.03); } }
@keyframes bx-op-out { to { transform: translate(-46vw, 5vh) rotate(-9deg); opacity: 0; } }
@keyframes bx-op-quake { 12% { transform: translate(-6px, 3px); } 30% { transform: translate(5px, -4px); } 50% { transform: translate(-4px, 2px); } 70% { transform: translate(2px, -2px); } 88% { transform: translate(-1px, 1px); } }
@keyframes bx-op-shock { from { width: 40%; opacity: 1; } to { width: 250%; opacity: 0; } }
@keyframes bx-op-stamp { from { scale: 1.6; opacity: 0; } }

/* Mouvement réduit (réglage du système ou du jeu) : plus rien ne bouge, tout reste lisible. */
@media (prefers-reduced-motion: reduce) {
  .bx-op, .bx-op *, .bx-op *::before, .bx-op *::after, .bx-packfloat > .bx-pack, .bx-packfloat::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-duration: .01ms !important; }
}
body.reduce-motion .bx-op, body.reduce-motion .bx-op *, body.reduce-motion .bx-op *::before, body.reduce-motion .bx-op *::after,
body.reduce-motion .bx-packfloat > .bx-pack, body.reduce-motion .bx-packfloat::after {
  animation-duration: .01ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-duration: .01ms !important; }


/* ===== css/pages/accueil.css ===== */
/* BloxMasters - pages d'accueil (src/js/views/home.js) : vitrine du visiteur (cahier 7.1), page Paquets
   du joueur connecté (7.2), règles du jeu (7.17). Les composants communs (boutons, panneaux, pastilles,
   listes...) viennent de components.css, la carte de card.css, le sachet et son flottement d'opening.css :
   cette feuille ne fait que la mise en page propre à ces trois vues. */

/* ═══════════════════════════════════════════════════════════════════════════
   VITRINE DU VISITEUR (cahier 7.1)
   ═══════════════════════════════════════════════════════════════════════════ */

.bx-vt { position: relative; overflow-x: clip; }
/* Pas d'ombre portée filtrée sur une carte répétée (cahier 3.5) : seul l'éventail du héros la garde. */
.bx-rars .bxc .bxc__win img, .bx-play .bxc .bxc__win img, .bx-also .bxc .bxc__win img, .bx-pullrow .bxc .bxc__win img { filter: none; }

/* ── Héros ─────────────────────────────────────────────────────────────────
   Valeurs copiées de l'accueil (bffr/style.css:136-158) ; l'image de saison est posée par shell.css. */
.bx-hero { position: relative; isolation: isolate; display: flex; align-items: center; min-height: min(88vh, 820px); overflow: hidden; }
.bx-hero__bg { position: absolute; inset: -4% -2%; z-index: 0; background-position: center 32%; background-size: cover; background-repeat: no-repeat; }
.bx-hero__veil { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.bx-hero__veil.a { background: linear-gradient(180deg, rgba(7, 7, 9, .35) 0%, rgba(7, 7, 9, .12) 32%, rgba(7, 7, 9, .55) 72%, rgba(7, 7, 9, .92) 92%, var(--bg) 100%); }
.bx-hero__veil.b { background: linear-gradient(100deg, rgba(7, 7, 9, .9) 0%, rgba(7, 7, 9, .72) 26%, rgba(7, 7, 9, .32) 48%, rgba(7, 7, 9, 0) 68%); }

/* Texte à gauche, éventail de trois vraies cartes à droite (une colonne sous 1024 px).
   --fan-c : largeur d'une carte ; --fan-o : écart horizontal des cartes de côté ; --fan-y : leur descente ;
   --fan-w : largeur de la colonne de l'éventail. */
.bx-hero__in {
  --fan-c: 210px; --fan-o: 188px; --fan-y: 36px; --fan-w: 622px;
  position: relative; z-index: 2; width: 100%;
  display: grid; grid-template-columns: minmax(0, 1fr) var(--fan-w); align-items: center; gap: 28px;
  padding-top: 56px; padding-bottom: 72px;
}
.bx-hero__text { min-width: 0; max-width: 620px; }

.bx-kick { display: inline-flex; align-items: center; gap: 11px; margin: 0 0 26px; padding: 8px 16px; border-radius: 99px;
  background: rgba(7, 7, 9, .5); border: 1px solid rgba(255, 255, 255, .16); }
.bx-kick i { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 50%; background: var(--accent); }
.bx-kick span { font: 700 12px/1.25 var(--font); letter-spacing: .14em; text-transform: uppercase; color: #d7d7e0; }

.bx-hero__t { margin: 0; font: 900 clamp(2.8rem, 8.6vw, 7rem)/.86 var(--display); letter-spacing: -.03em; text-transform: uppercase; color: #fff;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .65); }
.bx-hero__t span { display: block; }
.bx-hero__p { max-width: 520px; margin: 28px 0 0; font: 400 clamp(1.05rem, 1.5vw, 1.25rem)/1.6 var(--font); color: #d8d8e2; text-shadow: 0 1px 10px rgba(0, 0, 0, .7); }
.bx-hero__p strong { font-weight: 700; }
.bx-hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
/* « Les règles du jeu » reprend le .btn-ghost de l'accueil (bffr/style.css:127-128) : mêmes coins de 14 px
   que le bouton Discord posé à côté, pas la pilule des boutons secondaires du jeu. */
.bx-btn.bx-hero__rules { border-radius: 14px; background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .18); color: #fff; }
.bx-btn.bx-hero__rules:hover { background: rgba(255, 255, 255, .12); border-color: var(--accent); }
.bx-hero__note { margin: 14px 0 0; font: 500 13px/1.45 var(--font); color: var(--ink-3); text-shadow: 0 1px 8px rgba(0, 0, 0, .7); text-wrap: pretty; }

/* Chiffres (modèle .stats de l'accueil) : filets verticaux de 32 px entre eux. */
.bx-hstats { display: flex; align-items: center; gap: 26px; margin-top: 36px; }
.bx-hstats__sep { flex: 0 0 1px; width: 1px; height: 32px; background: rgba(255, 255, 255, .14); }
.bx-hstat { margin: 0; text-shadow: 0 1px 10px rgba(0, 0, 0, .7); }   /* même ombre que le paragraphe : au téléphone, les chiffres passent sur la bannière */
.bx-hstat b { display: block; font: 900 clamp(1.6rem, 3vw, 2.4rem)/1 var(--display); letter-spacing: -.03em; color: #fff; white-space: nowrap; }
.bx-hstat b small { font-size: .5em; letter-spacing: 0; }
.bx-hstat .bx-micro { margin-top: 8px; }

/* Éventail : la carte du centre devant, les deux autres en biais derrière. Aucune animation en boucle.
   La carte du centre ne doit couper aucun texte des cartes de côté : l'écart garde leur nom, leur famille
   et leur capacité entiers (« Cursed Dual Katana » est le plus long), et la descente fait passer leur
   ligne ATQ / DÉF sous le bas de la carte du centre au lieu de la trancher sur son bord. */
.bx-hero__fan { position: relative; width: var(--fan-w); height: calc(var(--fan-c) * 1.4 + var(--fan-y) + 20px); }
.bx-hero__fan > div { position: absolute; left: 50%; top: 4px; width: var(--fan-c); margin-left: calc(var(--fan-c) / -2); }
.bx-hero__fan > div:nth-child(1) { transform: translate(calc(var(--fan-o) * -1), var(--fan-y)) rotate(-7deg); }
.bx-hero__fan > div:nth-child(2) { z-index: 2; }
.bx-hero__fan > div:nth-child(3) { transform: translate(var(--fan-o), var(--fan-y)) rotate(7deg); }
.bx-hero__fan .bxc { --bxc-drop: 0 26px 48px -20px rgba(0, 0, 0, .9); }

/* Grand écran : « MASTERS » ne se colle pas à la carte de gauche de l'éventail (environ 70 px d'air). Le
   titre est plafonné à 6.25rem plutôt que les cartes resserrées : leur écart garde les noms lisibles. */
@media (min-width: 1280px) {
  .bx-hero__t { font-size: clamp(2.8rem, 7.4vw, 6.25rem); }
}
@media (max-width: 1279px) and (min-width: 1024px) {
  .bx-hero__in { --fan-c: 170px; --fan-o: 158px; --fan-y: 30px; --fan-w: 516px; }
  .bx-hero__t { font-size: clamp(2.8rem, 7vw, 7rem); }
}
/* Tablette et téléphone : l'éventail passe sous les chiffres, trois cartes qui se chevauchent légèrement.
   Entre 125 et 190 px de carte, le nom le plus long tient sur une ligne et occupe presque toute la
   largeur : l'écart monte jusqu'à une largeur de carte (le chevauchement ne vient plus que de la rotation).
   Sous 400 px d'écran, le nom passe sur deux lignes et les cartes peuvent se resserrer. */
@media (max-width: 1023px) {
  .bx-hero__in { --fan-c: min(30vw, 190px); --fan-o: min(var(--fan-c), var(--fan-c) / 2 + 70px); --fan-y: calc(var(--fan-c) * .18); --fan-w: 100%;
    grid-template-columns: minmax(0, 1fr); gap: 0; padding-top: 44px; padding-bottom: 40px; }
  .bx-hero__text { max-width: 640px; }
  .bx-hero__fan { height: calc(var(--fan-c) * 1.62 + 2px); margin-top: 40px; }
  .bx-hero__fan > div { top: 0; }
  .bx-hero__fan > div:nth-child(1) { transform: translate(calc(var(--fan-o) * -1), var(--fan-y)) rotate(-4deg); }
  .bx-hero__fan > div:nth-child(3) { transform: translate(var(--fan-o), var(--fan-y)) rotate(4deg); }
}
@media (max-width: 400px) {
  .bx-hero__in { --fan-o: calc(var(--fan-c) * .9); }
}
@media (max-width: 600px) {
  .bx-hero { min-height: 0; }
  /* Mêmes voiles que sur PC, comme l'accueil au même format : la bannière reste lumineuse, les ombres
     portées des textes du héros suffisent à leur lisibilité. */
  .bx-hero__bg { background-position: 60% 28%; }
  .bx-hero__in { padding-top: 32px; padding-bottom: 28px; }
  .bx-kick { margin-bottom: 22px; padding: 7px 14px; }
  .bx-kick span { font-size: 11px; letter-spacing: .12em; }
  .bx-hero__t { font-size: clamp(2.6rem, 16vw, 4.2rem); }
  .bx-hero__p { margin-top: 22px; }
  .bx-hero__cta { margin-top: 26px; }
  .bx-hero__cta .bx-btn { flex: 1 1 100%; }   /* empilés, de la même largeur (plus un bouton plus court que l'autre) */
  .bx-hstats { gap: 18px; margin-top: 30px; }
  .bx-hero__fan { margin-top: 34px; }
}

/* ── Bandeau défilant à plat (modèle .vt-marquee des raids, vitrine.css:168-173) ──
   Une marge après chaque mot (et non un gap) : les deux moitiés de la piste ont exactement la même
   largeur, la boucle à -50 % ne saute pas. */
.bx-marquee { overflow: hidden; padding: 16px 0; background: var(--bg-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.bx-marquee__track { display: flex; align-items: center; width: max-content; animation: bx-marquee 38s linear infinite; }
.bx-marquee.is-off .bx-marquee__track, .bx-marquee:hover .bx-marquee__track { animation-play-state: paused; }
.bx-marquee span { margin-right: 24px; font: 800 clamp(.95rem, .8rem + .6vw, 1.25rem)/1 var(--display); letter-spacing: -.01em; text-transform: uppercase; color: var(--ink); white-space: nowrap; }
.bx-marquee i { flex: 0 0 7px; width: 7px; height: 7px; margin-right: 24px; border-radius: 2px; background: var(--accent); transform: rotate(45deg); }
@keyframes bx-marquee { to { transform: translateX(-50%); } }

/* ── Sections de la vitrine ────────────────────────────────────────────────── */
.bx-vsec { padding-top: clamp(56px, 8vw, 96px); }
.bx-vsec__head { margin-bottom: 22px; }
.bx-vsec__head .bx-sec { margin: 0; }
.bx-vsec__lead { max-width: 600px; text-wrap: pretty; margin: 12px 0 0; font: 400 1.05rem/1.6 var(--font); color: var(--ink-2); }

/* Révélation au défilement (modèle .vt-rv, vitrine.css:58-64) : armée par home.js seulement hors
   mouvement réduit ; le script révèle tout au plus tard 4 s après, la feuille 6 s après sans script. */
.bx-vt.is-motion .bx-rv { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.bx-vt.is-motion .bx-rv.is-in { opacity: 1; transform: none; }
.bx-vt.is-motion .bx-rv:not(.is-in) { animation: bx-rv-safe .6s var(--ease) 6s forwards; }
@keyframes bx-rv-safe { to { opacity: 1; transform: none; } }

/* ── Six raretés : une vraie carte par rareté ──────────────────────────────── */
.bx-rars { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.bx-rars > li { min-width: 0; }
.bx-rars__meta { margin: 0; font: 500 13px/1.5 var(--mono); color: var(--ink-3); text-align: center; white-space: nowrap; }
.bx-rars__meta:first-of-type { margin-top: 12px; }
.bx-rars__meta b { font-weight: 700; color: var(--ink); word-spacing: -.32em; }

/* Rangées qui défilent (raretés sur téléphone, derniers grands tirages) : bord droit estompé tant qu'il reste à voir. */
.bx-pullrow { display: flex; gap: 14px; margin: 0 calc(var(--gutter) * -1); padding: 4px var(--gutter) 6px; list-style: none;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scroll-padding-inline: var(--gutter); scrollbar-width: none; }
.bx-pullrow::-webkit-scrollbar, .bx-rars::-webkit-scrollbar { display: none; }
.bx-pullrow > li { flex: 0 0 150px; min-width: 0; scroll-snap-align: start; }
.bx-pullrow > li > p { margin: 8px 0 0; font: 500 12px/1.35 var(--font); color: var(--ink-3); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bx-pullrow.is-overflow, .bx-rars.is-overflow { -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
/* PC : la rangée ne défile pas à la souris. Elle devient une grille d'une seule rangée, sans masque ni
   défilement : 8 cartes au-dessus de 1200 px, 6 de 961 à 1200 px (portable zoomé), 5 de 761 à 960 px
   quand on la tient à la souris. Les tirages suivants restent pour le téléphone et la tablette au doigt,
   où la rangée défile (home.js en envoie 12 au plus). */
@media (min-width: 1201px) {
  .bx-pullrow, .bx-pullrow.is-overflow { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); margin: 0; padding: 4px 0 6px;
    overflow: visible; scroll-snap-type: none; -webkit-mask-image: none; mask-image: none; }
  .bx-pullrow > li { flex: none; }
  .bx-pullrow > li:nth-child(n+9) { display: none; }
}
@media (min-width: 961px) and (max-width: 1200px), (min-width: 761px) and (max-width: 960px) and (hover: hover) and (pointer: fine) {
  .bx-pullrow, .bx-pullrow.is-overflow { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); margin: 0; padding: 4px 0 6px;
    overflow: visible; scroll-snap-type: none; -webkit-mask-image: none; mask-image: none; }
  .bx-pullrow > li { flex: none; }
  .bx-pullrow > li:nth-child(n+7) { display: none; }
}
@media (min-width: 761px) and (max-width: 960px) and (hover: hover) and (pointer: fine) {
  .bx-pullrow, .bx-pullrow.is-overflow { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .bx-pullrow > li:nth-child(n+6) { display: none; }
}

/* Tablette : deux rangées de trois, les cartes passent en taille M. */
@media (max-width: 1023px) and (min-width: 761px) {
  .bx-rars { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 26px; }
}
@media (max-width: 760px) {
  .bx-rars { display: flex; gap: 12px; margin: 0 calc(var(--gutter) * -1); padding: 2px var(--gutter) 6px;
    overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: none; }
  .bx-rars > li { flex: 0 0 min(40vw, 176px); scroll-snap-align: start; }   /* la troisième carte dépasse : on voit que ça défile */
}

/* ── Comment on joue : quatre panneaux, trois cartes qui dépassent du bas ─── */
.bx-play { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.bx-play__panel { display: flex; flex-direction: column; padding: 26px 26px 0; }
.bx-play__n { font: 700 13px/1 var(--mono); color: var(--accent-2); }
.bx-play__panel h3 { margin: 12px 0 0; font: 800 1.3rem/1.15 var(--display); letter-spacing: -.015em; color: #fff; }
.bx-play__panel p { max-width: 460px; margin: 10px 0 0; font-size: 15px; line-height: 1.55; color: var(--ink-2); }
/* Paquet d'essai (panneau 01) : bouton secondaire, à sa propre taille (le panneau est en colonne,
   sans lui il s'étirerait sur toute la largeur). Devenu lien de connexion, son texte est plus long
   qu'un bouton n'en tient en une ligne sur téléphone : il passe à la ligne au lieu de dépasser. */
.bx-play__demo { align-self: flex-start; margin-top: 16px; }
.bx-play__demo.bx-btn--discord { max-width: 100%; height: auto; min-height: 44px; padding: 10px 18px; white-space: normal; text-align: center; line-height: 1.3; }
/* Le panneau coupe le tiers inférieur des cartes (overflow: hidden de .bx-panel--feature), dans le vide
   entre la pastille de rareté et le nom : la fenêtre et la rareté restent entières, le nom et ATQ / DÉF
   passent sous le bord, aucune ligne de texte n'est tranchée. Les cartes de côté restent à la hauteur de
   celle du centre, inclinées seulement : plus bas, leur pastille tomberait sur la coupe. */
.bx-play__cards { --pc: 140px; position: relative; flex: 0 0 auto; height: calc(var(--pc) * .965); margin-top: auto; padding-top: 26px; box-sizing: content-box; }
.bx-play__cards > div { position: absolute; top: 26px; left: 50%; width: var(--pc); margin-left: calc(var(--pc) / -2); }
.bx-play__cards > div:nth-child(1) { transform: translateX(calc(var(--pc) * -.84)) rotate(-4deg); }
.bx-play__cards > div:nth-child(2) { z-index: 2; }
.bx-play__cards > div:nth-child(3) { transform: translateX(calc(var(--pc) * .84)) rotate(4deg); }
.bx-play__cards.is-vs > div:nth-child(1) { transform: translate(calc(var(--pc) * -.72), 0) rotate(-3deg); }
.bx-play__cards.is-vs > div:nth-child(3) { z-index: 1; transform: translate(calc(var(--pc) * .72), 0) rotate(3deg); }
.bx-play__vs { position: absolute; z-index: 3; left: 50%; top: calc(26px + var(--pc) * .42); transform: translate(-50%, -50%);
  font: 900 1.5rem/1 var(--display); letter-spacing: -.02em; color: var(--ink-3); }
@media (max-width: 900px) { .bx-play { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 760px) {
  .bx-play__panel { padding: 22px 20px 0; }
  /* Cartes de 120 px : « Cursed Dual Katana » passe sur deux lignes et remonte, la coupe et l'inclinaison
     se resserrent d'autant. */
  .bx-play__cards { --pc: 120px; height: calc(var(--pc) * .945); padding-top: 22px; }
  .bx-play__cards > div { top: 22px; }
  .bx-play__cards > div:nth-child(1) { transform: translateX(calc(var(--pc) * -.84)) rotate(-3deg); }
  .bx-play__cards > div:nth-child(3) { transform: translateX(calc(var(--pc) * .84)) rotate(3deg); }
  .bx-play__vs { top: calc(22px + var(--pc) * .42); font-size: 1.3rem; }
}

/* ── Et aussi : trois panneaux compacts (modèle .also__card de l'accueil) ─── */
.bx-also { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.bx-also__item { position: relative; display: flex; align-items: center; gap: 18px; min-width: 0; padding: 22px; border-radius: 22px;
  background: linear-gradient(165deg, #131320, #0c0c12); border: 1px solid var(--line); box-shadow: var(--hl); color: inherit; text-decoration: none;
  transition: transform .45s var(--ease), border-color .3s; }
.bx-also__item:hover { transform: translateY(-4px); border-color: var(--accent-line); }
/* Carte S (cahier 5.3) de 108 px à toutes les tailles d'écran, et non 88 : sous 100 px, card.css passe en
   très petite taille (fenêtre seule) et un titre n'y garde que son nom en 9 px, sans surtitre (deux traits à
   sa place sous 80 px ou pour un mot trop long). À 108 px, les trois cartes ont leur plaque et « BOSS BLOX
   FRUITS OFFICIAL » s'écrit en entier dans la fenêtre ; la plaque d'un titre écrit son type (« Titre unique »). */
.bx-also__card { flex: 0 0 108px; width: 108px; }
.bx-also__txt { flex: 1 1 auto; min-width: 0; }
.bx-also__txt p { margin: 6px 0 0; font: 400 13px/1.45 var(--font); color: var(--ink-2); }
.bx-also__go { flex: 0 0 auto; display: grid; place-items: center; color: var(--accent); transition: transform .2s var(--ease); }
.bx-also__go svg { width: 18px; height: 18px; }
.bx-also__item:hover .bx-also__go { transform: translateX(3px); }
/* Tablette : la carte au-dessus, la flèche au bout de la ligne du titre (jamais posée sur la phrase). */
@media (max-width: 1023px) and (min-width: 761px) {
  .bx-also__item { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "card card" "t go" "p p"; align-items: center; gap: 0 12px; }
  .bx-also__card { grid-area: card; margin-bottom: 14px; }
  .bx-also__txt { display: contents; }
  .bx-also__txt h3 { grid-area: t; min-width: 0; }
  .bx-also__txt p { grid-area: p; }
  .bx-also__go { grid-area: go; }
}
@media (max-width: 760px) {
  .bx-also { grid-template-columns: minmax(0, 1fr); }
  .bx-also__item { gap: 16px; padding: 16px 18px; border-radius: 20px; }
}

/* ── Appel final (modèle .cta de l'accueil) ────────────────────────────────── */
.bx-final { position: relative; isolation: isolate; display: grid; place-items: center; min-height: clamp(440px, 74vh, 680px);
  margin-top: clamp(56px, 8vw, 96px); padding: 72px var(--gutter); overflow: hidden; text-align: center; }
/* Les fondus haut et bas du modèle (var(--bg) aux deux bords) passent par un masque : la bannière se fond
   dans le fond réel de la page, y compris la nuit violette du thème d'Halloween (sinon une marche nette). */
.bx-final__art { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 22%, #000 78%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 22%, #000 78%, transparent 100%); }
.bx-final__bg { position: absolute; inset: -8%; z-index: 0; background-position: center 40%; background-size: cover; background-repeat: no-repeat; }
.bx-final__veil { position: absolute; inset: 0; z-index: 1; }
.bx-final__veil.a { background: linear-gradient(180deg, rgba(7, 7, 9, .5) 0%, rgba(7, 7, 9, .5) 50%, rgba(7, 7, 9, .6) 100%); }
.bx-final__veil.b { background: radial-gradient(58% 56% at 50% 50%, rgba(7, 7, 9, .72), rgba(7, 7, 9, .3) 55%, rgba(7, 7, 9, 0) 80%); }
.bx-final__in { position: relative; z-index: 2; max-width: 820px; }
.bx-final h2 { margin: 0; font: 900 clamp(2.2rem, 6vw, 4.6rem)/.92 var(--display); letter-spacing: -.03em; text-transform: uppercase; color: #fff;
  text-shadow: 0 3px 22px rgba(0, 0, 0, .55); }
.bx-final h2 span { display: block; }
.bx-final p { max-width: 520px; margin: 24px auto 0; font: 400 1.15rem/1.6 var(--font); color: #c8c8d4; text-shadow: 0 1px 10px rgba(0, 0, 0, .7); }
.bx-final .bx-btn { margin-top: 30px; }
@media (max-width: 600px) {
  .bx-final { min-height: 0; padding: 88px var(--gutter) 80px; }
  .bx-final p { font-size: 1.05rem; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PAGE PAQUETS (cahier 7.2)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── La baie : le sachet qui flotte à gauche, la réserve à droite ──────────── */
/* Le sachet et la réserve forment un bloc centré dans la baie (la réserve ne dépasse pas 600 px de large). */
.bx-packbay { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 600px); justify-content: center; align-items: center; gap: 40px; padding: 32px; border-radius: 22px;
  background: radial-gradient(70% 60% at 22% 30%, rgba(var(--accent-rgb), .10), transparent 70%), var(--panel-grad); }
.bx-packbay__pack { display: grid; place-items: center; padding: 0 0 34px; }   /* 34 px : l'ombre de sol du sachet */
.bx-packbay__obj { width: 240px; max-width: 100%; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bx-packbay__obj.is-empty { cursor: default; }
.bx-packbay__obj.is-empty > .bx-pack { filter: saturate(.55) brightness(.8); }
.bx-packbay__info { min-width: 0; }
.bx-packbay__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: -10px 0 0; }
.bx-packbay__top .bx-how { margin-right: -4px; }
.bx-packbay__count { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 6px; }
.bx-packbay__count .bx-big { white-space: nowrap; }
.bx-packbay .bx-stock { margin-top: 18px; }
.bx-packbay__next { margin: 12px 0 0; font: 500 13px/1.45 var(--font); color: var(--ink-3); }
.bx-packbay__next .bx-time { color: var(--ink); }
.bx-packbay__info > .bx-small { margin-top: 4px; }
.bx-packbay__act { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
/* Jauges de malchance (Mythique, Divine) : le libellé et son « ? » sur une ligne, puis une ligne par jauge
   (pastille de rareté, compte, barre à la couleur de la rareté), alignées en colonnes. Leur définition s'ouvre
   par le « ? » (aucune infobulle : elle ne se voit pas au doigt). */
.bx-pity { display: grid; grid-template-columns: auto auto minmax(60px, 1fr); align-items: center; gap: 10px 14px; margin-top: 26px; padding-top: 14px;
  border-top: 1px solid var(--line); }
.bx-pity__head { grid-column: 1 / -1; display: flex; align-items: center; min-height: 22px; }
.bx-pity__head > .bx-help { margin-left: -2px; }
.bx-pity__k { display: flex; }
.bx-pity__k .bx-pill { min-width: 92px; justify-content: flex-start; }
.bx-pity .bx-num { font-size: 13px; color: var(--ink); white-space: nowrap; word-spacing: -.32em; text-align: right; }
.bx-bar--r5 > i { background: var(--r5); }
.bx-bar--r6 > i { background: var(--r6); }

/* Grand écran assez haut : le sachet prend la place de sa colonne (300 px au plus). */
@media (min-width: 1201px) and (min-height: 821px) {
  .bx-packbay__obj { width: 280px; }
}
@media (max-width: 1023px) and (min-width: 701px) {
  .bx-packbay { grid-template-columns: 220px minmax(0, 1fr); gap: 32px; padding: 28px; }
  .bx-packbay__obj { width: 200px; }
  /* Tablette : « Ouvrir un paquet » sur toute la largeur, les deux autres côte à côte dessous (plus de
     « Boutique » seul sur sa ligne). Un bouton resté seul dessous prend toute la largeur. */
  .bx-packbay__act .bx-btn { flex: 1 1 0; min-width: 0; padding-left: 14px; padding-right: 14px; white-space: normal; text-align: center; line-height: 1.2; }
  .bx-packbay__act .bx-btn--primary { flex-basis: 100%; }
}
@media (max-width: 700px) {
  .bx-packbay { grid-template-columns: minmax(0, 1fr); justify-content: stretch; gap: 4px; padding: 22px 18px 20px; }
  /* Sachet de 144 px, ligne d'aide et boutons resserrés : « Ouvrir un paquet » remonte dans le premier écran
     du téléphone (haut sous 600 px à 390 px de large), même à la première visite, réserve pleine et sa
     phrase sur deux lignes. */
  .bx-packbay__pack { padding: 2px 0 26px; }
  .bx-packbay__obj { width: 144px; }
  .bx-packbay__obj::after { top: calc(100% + 6px); height: 16px; }   /* ombre de sol à l'échelle du sachet */
  .bx-packbay__top { margin-top: 0; }
  .bx-packbay__act { margin-top: 18px; }
  .bx-packbay__act .bx-btn { flex: 1 1 auto; }
  /* Trois boutons (ouvrir, ouvrir plusieurs, boutique) : le principal sur toute la largeur, les deux autres dessous. */
  .bx-packbay__act .bx-btn--primary { flex-basis: 100%; }
  .bx-pity { gap: 10px; }
}
/* Petit téléphone (375 px, iPhone SE) : « 10 / 10 paquets » et la pastille des bonus tiennent sur une
   ligne, et « Ouvrir un paquet » garde sa place dans le premier écran. */
@media (max-width: 400px) {
  .bx-packbay__count { column-gap: 10px; }
  .bx-packbay__count .bx-pill { padding: 0 8px; letter-spacing: .05em; }
}

/* Ligne d'aide sous le sachet, téléphone seulement : « Touche le paquet pour l'ouvrir » (home.js, dans
   .bx-packbay__pack juste après le sachet). Elle passe sous l'ombre de sol et disparaît quand la réserve
   est vide (le sachet ne s'ouvre plus). */
.bx-packbay__tap { display: none; margin: 0; font: 500 13px/1.45 var(--font); color: var(--ink-3); text-align: center; }
@media (max-width: 700px) {
  .bx-packbay__tap { display: block; margin-top: 16px; }
  .bx-packbay__pack:has(> .bx-packbay__tap) { padding-bottom: 4px; }
  .bx-packbay__obj.is-empty ~ .bx-packbay__tap { display: none; }
  .bx-packbay__pack:has(> .bx-packbay__obj.is-empty) { padding-bottom: 26px; }
}

/* Réserve vide (home.js) : à la place du bouton grisé, ce que le joueur peut faire en attendant le prochain
   paquet. Une ligne par action, 44 px au moins, dans l'ordre du code ; un seul bouton principal (le premier),
   les autres en .bx-btn, la recharge en Onyx en lien (.bx-link). Liste <ul> ou boutons posés directement. */
.bx-bay-next { display: grid; gap: 8px; max-width: 460px; margin: 24px 0 0; padding: 0; border-radius: 16px; list-style: none; }   /* rayon : le repère d'une bulle d'aide suit les coins */
.bx-bay-next > li { display: flex; min-width: 0; margin: 0; }
.bx-bay-next .bx-btn { flex: 1 1 auto; width: 100%; min-height: 44px; height: auto; padding: 11px 18px;
  white-space: normal; text-align: center; line-height: 1.25; }
.bx-bay-next .bx-btn--lg { min-height: 52px; }   /* même hauteur que « Ouvrir un paquet », une ligne ou deux */
.bx-bay-next .bx-link { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; }
.bx-bay-next .bx-link:only-child, .bx-bay-next > .bx-link { margin: 0 auto; justify-self: center; }
@media (max-width: 700px) { .bx-bay-next { max-width: none; margin-top: 20px; } }

/* ── Panneaux du dessous : deux colonnes. Avec un nombre impair de panneaux, le coffre (toujours
   premier) prend toute la largeur et le raid et le concours gardent leur ligne à deux. ── */
.bx-pk-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 14px; }
.bx-pk-grid > :first-child:nth-last-child(odd) { grid-column: 1 / -1; }
@media (max-width: 860px) { .bx-pk-grid { grid-template-columns: minmax(0, 1fr); } }

/* Coffre du jour */
.bx-chest { display: flex; flex-direction: column; gap: 18px; padding: 22px; }
.bx-chest__head { display: flex; align-items: center; gap: 14px; }
.bx-chest__head img { flex: 0 0 56px; width: 56px; height: 56px; margin: -6px 0; object-fit: contain; }
.bx-chest__head h3 { flex: 1 1 auto; min-width: 0; }
.bx-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }
.bx-days > li { position: relative; display: flex; flex-direction: column; align-items: center; gap: 7px; min-width: 0; padding: 10px 2px 10px;
  border-radius: 12px; background: var(--bg-2); border: 1px solid var(--line); text-align: center; }
.bx-days b { font: 800 1.2rem/1 var(--display); color: #fff; }
.bx-days em { display: inline-flex; align-items: center; gap: 3px; font: 700 12px/1 var(--mono); font-style: normal; color: var(--ink-3); word-spacing: -.32em; }
.bx-days em .bx-coin__ic--beli { width: 6px; height: 12px; }
.bx-days > li.is-done { opacity: .5; }
.bx-days .bx-days__ok { position: absolute; top: 5px; right: 5px; width: 12px; height: 12px; color: var(--ink-2); }
.bx-days > li.is-today { background: var(--accent-dim); border-color: var(--accent-line); }
.bx-days > li.is-today em { color: var(--ink-2); }
/* Unité sous le nombre de paquets du jour (home.js) : « paquet » ou « paquets », collée au chiffre. */
.bx-days .bx-days__u { margin-top: -4px; font: 600 11px/1 var(--font); color: var(--ink-3); white-space: nowrap; }
.bx-days > li.is-today .bx-days__u { color: var(--ink-2); }
/* Aucune série en cours : une phrase courte à droite du titre, à la place de la puce « Série ». */
.bx-chest__nostreak { flex: 0 1 auto; min-width: 0; text-align: right; }
/* margin-top: auto : à côté d'un panneau plus haut, le bouton descend en pied au lieu de laisser un trou dessous. */
.bx-chest__btn { margin-top: auto; white-space: normal; text-align: center; line-height: 1.25; padding-top: 8px; padding-bottom: 8px; }
/* Coffre disponible : bouton secondaire bordé d'accent, pour ne garder qu'un bouton principal dans le premier
   écran (« Ouvrir un paquet », réserve pleine). Toujours secondaire : réserve vide, la baie propose le coffre en
   principal. */
.bx-chest__btn.is-soft { background: transparent; border-color: var(--accent-line); color: var(--accent-2); box-shadow: none; }
.bx-chest__btn.is-soft:hover { background: var(--accent-dim); border-color: var(--accent); color: var(--ink); }
.bx-chest > .bx-small { margin-top: -8px; }
/* Après l'ouverture du coffre : ce que donnera celui de demain. */
.bx-chest__tomorrow { margin: -8px 0 0; font: 500 13px/1.45 var(--font); color: var(--ink-3); text-wrap: pretty; }
/* Coffre en pleine largeur (deux colonnes de grille) : l'en-tête et le bouton à gauche, la frise des
   7 paliers à droite, plutôt qu'un bouton étiré sur toute la page. */
@media (min-width: 861px) {
  .bx-pk-grid > .bx-chest:first-child:nth-last-child(odd) { display: grid; grid-template-columns: minmax(280px, 340px) minmax(0, 1fr); grid-template-areas: "head days" "btn days";
    align-items: center; gap: 18px 32px; }
  .bx-pk-grid > .bx-chest:first-child:nth-last-child(odd) .bx-chest__head { grid-area: head; }
  .bx-pk-grid > .bx-chest:first-child:nth-last-child(odd) .bx-days { grid-area: days; }
  .bx-pk-grid > .bx-chest:first-child:nth-last-child(odd) .bx-chest__btn { grid-area: btn; margin-top: 0; }
  .bx-pk-grid > .bx-chest:first-child:nth-last-child(odd) > .bx-small,
  .bx-pk-grid > .bx-chest:first-child:nth-last-child(odd) > .bx-chest__tomorrow { grid-column: 1; margin-top: -8px; }
}
@media (max-width: 600px) {
  .bx-chest { padding: 18px 16px; }
  .bx-days { gap: 4px; }
  .bx-days > li { padding: 9px 0; border-radius: 10px; }
  .bx-days b { font-size: 1.06rem; }
  .bx-days em { font-size: 11px; }
  .bx-days .bx-days__u { letter-spacing: -.02em; }   /* « paquets » tient dans une case de 43 px à 390 px */
  .bx-days .bx-days__ok { top: 4px; right: 3px; width: 10px; height: 10px; }
}

/* Paquets premium : un petit sachet par ligne. À côté du coffre, plus haut qu'eux, les lignes se centrent
   dans la hauteur restante au lieu de laisser tout le vide en bas. */
.bx-prem { display: flex; flex-direction: column; }
.bx-prem > .bx-list { flex: 1 1 auto; justify-content: center; }
.bx-prem .bx-panel__head .bx-link { min-height: 40px; display: inline-flex; align-items: center; font-size: 13px; }
.bx-prem .bx-panel__head { padding-top: 10px; padding-bottom: 10px; }
.bx-prem__row { gap: 16px; padding: 14px 20px; }
.bx-prem__pack { flex: 0 0 64px; width: 64px; }
.bx-prem__n { margin-left: 4px; font-size: 13px; color: var(--accent-2); }
.bx-prem__promise { display: block; margin-top: 3px; font: 500 13px/1.4 var(--font); color: var(--ink-3); }
.bx-prem .bx-row__main .bx-row__title { white-space: normal; }
/* « Tout ouvrir » (deux paquets ou plus) puis « Ouvrir ». */
.bx-prem__act { display: flex; flex: 0 0 auto; align-items: center; gap: 6px; }
@media (max-width: 600px) { .bx-prem__row { gap: 12px; padding: 12px 16px; } .bx-prem__pack { flex-basis: 52px; width: 52px; } }
/* Téléphone : les boutons passent sous le texte, qui prend toute la largeur (la ligne des chances tenait sur
   8 lignes dans 85 px). */
@media (max-width: 600px) {
  .bx-prem__row { flex-wrap: wrap; }
  .bx-prem__row .bx-row__main { flex: 1 1 calc(100% - 64px); }
  .bx-prem__act { flex: 1 1 100%; justify-content: flex-end; }
}

/* Raid du jour : la carte du boss en S à gauche */
.bx-raidday { display: grid; grid-template-columns: 150px minmax(0, 1fr); align-items: center; gap: 24px; padding: 22px; }
.bx-raidday__body { min-width: 0; max-width: 560px; }
.bx-raidday__body h3 { margin: 8px 0 14px; }
.bx-raidday__line { margin-top: 10px; }
.bx-raidday__line .bx-time { color: var(--ink-2); }
.bx-raidday__body .bx-btn { margin-top: 16px; }
.bx-raidday__card .bxc { cursor: pointer; }
@media (max-width: 480px) { .bx-raidday { grid-template-columns: 112px minmax(0, 1fr); gap: 16px; padding: 16px; } }

/* Concours de la semaine */
.bx-contest { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 22px; }
.bx-contest h3 { margin-top: 2px; }
.bx-contest__desc { max-width: 520px; }
.bx-contest .bx-facts { margin-top: 8px; }
.bx-contest__act { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin-top: auto; padding-top: 14px; }

/* Derniers grands tirages : liste, deux colonnes sur grand écran */
.bx-feed .bx-row { min-height: 60px; }
.bx-feed .bx-row__time { align-self: center; padding-top: 0; }
@media (min-width: 900px) {
  .bx-feed { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bx-feed > .bx-row:nth-child(odd) { border-right: 1px solid var(--line); }
  .bx-feed > .bx-row:nth-last-child(2):nth-child(odd) { border-bottom: 0; }
  /* Nombre impair de tirages : la dernière ligne prend toute la largeur, sans case vide à droite ni filet
     vertical qui descend dans le vide. */
  .bx-feed > .bx-row:last-child:nth-child(odd) { grid-column: 1 / -1; border-right: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RÈGLES DU JEU (cahier 7.17)
   ═══════════════════════════════════════════════════════════════════════════ */

.bx-rules { max-width: 760px; margin: 0 auto; }
.bx-rules > .bx-ph { margin-bottom: 0; }
.bx-rules section > .bx-sec { margin: 40px 0 14px; }
.bx-rules p { font-size: 15px; line-height: 1.65; color: var(--ink-2); }
.bx-rules p + p, .bx-rules p + .bx-panel, .bx-rules .bx-panel + p { margin-top: 14px; }
/* Liens dans le texte : la zone de clic déborde de 10 px en hauteur sans toucher à l'interligne. */
.bx-rules p a { padding: 12px 0; color: var(--accent-2); font-weight: 700; text-decoration: none; }
.bx-rules p a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* « Les mots du jeu » (BM.HELP) : le mot en blanc, sa définition à la suite. */
.bx-rules__word b { color: var(--ink); }
.bx-rules .bx-row { gap: 14px; }
/* Colonne fixe pour la pastille de rareté : les chiffres s'alignent d'une ligne à l'autre. */
.bx-rules__rar { flex: 0 0 128px; display: flex; }
.bx-rules__rates .bx-row__num { font-size: 15px; }
.bx-rules__craft .bx-row { align-items: flex-start; padding-top: 14px; padding-bottom: 14px; }
.bx-rules__craft .bx-rules__rar { margin-top: 1px; }
.bx-rules__line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; font: 500 14px/1.6 var(--font); color: var(--ink-2); }
.bx-rules__line + .bx-rules__line { margin-top: 2px; }
.bx-rules__k { width: 96px; flex: 0 0 96px; font: 800 11px/1.6 var(--font); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.bx-rules__line .bx-num { color: var(--ink); word-spacing: -.32em; }
@media (max-width: 600px) {
  .bx-rules__craft .bx-row { flex-direction: column; gap: 10px; }
  .bx-rules__craft .bx-rules__rar { flex-basis: auto; }
  .bx-rules__k { width: 92px; flex-basis: 92px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOUVEMENT RÉDUIT (réglage système ET réglage du jeu) : bandeau figé sur plusieurs lignes,
   chaque mot porte son losange ; rien ne se soulève au survol.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .bx-marquee__track { flex-wrap: wrap; justify-content: center; width: auto; gap: 10px 22px; padding: 0 16px; animation: none; }
  .bx-marquee__track > .is-dup, .bx-marquee__track > i { display: none; }
  .bx-marquee span { display: inline-flex; align-items: center; gap: 10px; margin: 0; }
  .bx-marquee span::before { content: ''; flex: 0 0 7px; width: 7px; height: 7px; border-radius: 2px; background: var(--accent); transform: rotate(45deg); }
  .bx-also__item, .bx-also__go { transition: none; }
  .bx-also__item:hover, .bx-also__item:hover .bx-also__go { transform: none; }
}
body.reduce-motion .bx-marquee__track { flex-wrap: wrap; justify-content: center; width: auto; gap: 10px 22px; padding: 0 16px; animation: none; }
body.reduce-motion .bx-marquee__track > .is-dup, body.reduce-motion .bx-marquee__track > i { display: none; }
body.reduce-motion .bx-marquee span { display: inline-flex; align-items: center; gap: 10px; margin: 0; }
body.reduce-motion .bx-marquee span::before { content: ''; flex: 0 0 7px; width: 7px; height: 7px; border-radius: 2px; background: var(--accent); transform: rotate(45deg); }
body.reduce-motion .bx-also__item:hover, body.reduce-motion .bx-also__item:hover .bx-also__go { transform: none; }


/* ===== css/pages/album.css ===== */
/* BloxMasters - pages Album (#/album, cahier §7.3) et fiche d'une carte (BM.showCard, #/carte/:id,
   cahier §7.4), avec leurs fenêtres : défausse, étiquettes, vitrines.
   Composants communs (boutons, puces, panneaux, listes, fenêtres) : components.css ; la carte : card.css.
   Préfixes propres à ces vues : .bx-alb (album), .bx-selbar (sélection), .bx-cd (fiche), .bx-cdpage. */

/* ── Album : en-tête ───────────────────────────────────────────────────────── */
.bx-alb__ph { margin-bottom: 18px; }
.bx-alb__title { min-width: 0; }
.bx-alb__title .bx-h1 { overflow-wrap: anywhere; }
.bx-alb__prog { margin-bottom: 14px; }
.bx-alb__sentinel { display: block; height: 1px; margin-bottom: -1px; }
/* Actions de son album, en deux groupes : « Comment ça marche » et « Défausser les doublons », puis « Sélectionner »
   et « ... ». Sur PC, les groupes s'effacent et les quatre se suivent dans la rangée d'actions de l'en-tête. */
.bx-alb__actx, .bx-alb__actsel { display: contents; }
/* Fait « Éclats » suivi de son aide « ? » (BM.helpBtn) : la zone de toucher de 40 px déborde sans grandir la rangée. */
.bx-alb__fx { display: inline-flex; align-items: center; height: 34px; }
/* Téléphone, son album : « Sélectionner » et « ... » sur la ligne du titre, les faits dessous sur toute la largeur,
   puis « Comment ça marche » et « Défausser les doublons » sur une ligne (celle que les autres pages donnent à
   « Comment ça marche »). L'album d'un autre joueur garde ses deux liens en dessous. */
@media (max-width: 600px) {
  .bx-alb__ph.is-mine { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 12px; }
  .bx-alb__ph.is-mine .bx-alb__title { display: contents; }
  .bx-alb__ph.is-mine .bx-h1 { grid-area: 1 / 1; }
  .bx-alb__ph.is-mine .bx-ph__act { display: contents; }
  .bx-alb__ph.is-mine .bx-alb__actsel { grid-area: 1 / 2; display: flex; align-items: center; gap: 8px; }
  .bx-alb__ph.is-mine .bx-ph__sub { grid-area: 2 / 1 / 3 / 3; }
  .bx-alb__ph.is-mine .bx-alb__actx { grid-area: 3 / 1 / 4 / 3; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; margin-top: -6px; }
  .bx-alb__ph.is-mine .bx-alb__actx .bx-how { padding-left: 0; }
}

/* Pas d'ancrage du défilement dans l'album : la grille virtuelle change de hauteur d'un coup (filtres, cartes
   manquantes) ; un ancrage du navigateur sur « À découvrir » ou sur la barre ferait sauter la page. */
.bx-alb { overflow-anchor: none; }

/* ── Album : barre d'outils, collée sous l'en-tête sur PC, dans le flux sur téléphone ── */
.bx-alb__tools {
  position: sticky; top: var(--head-h); z-index: 20;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px;
  margin: 0 calc(var(--gutter) * -1) 20px; padding: 10px var(--gutter);
  border-bottom: 1px solid transparent; transition: border-color .2s, background-color .2s;
}
/* Fond posé seulement quand la barre est collée : au repos elle se fond dans la page (et dans le fond de saison).
   Opaque (le fond de la page, --bg) : à .92 le texte blanc des cartes qui défilent dessous transparaissait. */
.bx-alb__tools.is-stuck { background: var(--bg); border-bottom-color: var(--line); }
.bx-alb__row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.bx-alb__search { flex: 1 1 260px; max-width: 420px; }
.bx-alb__row .bx-select { flex: 0 0 auto; }
.bx-alb__row .bx-switch { flex: 0 0 auto; }
/* Compteur à droite de la ligne ; la puce « Filtres » de la barre réduite se pose à sa place (plus bas). */
.bx-alb__countbox { position: relative; display: inline-flex; align-items: center; margin-left: auto; }
.bx-alb__count { white-space: nowrap; transition: opacity .15s; }
.bx-alb__count .bx-num { font-size: 13px; line-height: 1; color: var(--ink); }
.bx-alb__famrow { display: flex; align-items: flex-start; min-width: 0; }
.bx-alb__famrow > .bx-chips { flex: 1 1 auto; min-width: 0; }
.bx-alb__fbtn, .bx-alb__fsep { display: none; }
.bx-alb__fbtn > [data-fn]:empty { display: none; }
.bx-alb__fbtn.is-on { color: var(--ink); background: var(--accent-dim); border-color: var(--accent-line); }
.bx-alb__fbtn.is-on .bx-count { color: var(--ink-2); }
/* Groupes de la rangée des filtres : transparents sur PC (les puces suivent dans la même rangée qui défile). */
.bx-alb__grp { display: contents; }
.bx-alb__sep { flex: 0 0 1px; align-self: center; width: 1px; height: 20px; margin: 0 4px; background: var(--line-2); }
.bx-alb__sep:has(+ .bx-alb__grp:empty) { display: none; }   /* pas d'étiquette, pas de filet */
.bx-alb .bx-chip .bx-count { word-spacing: -.32em; }
/* Puce « Filtres » : seulement avec la barre collée réduite (plus bas), dans la ligne collée ; elle ramène la
   barre entière en haut de l'écran. */
.bx-alb__fchip { display: none; }
.bx-alb__fchip > [data-fc]:empty { display: none; }
.bx-alb__fchip.is-on { color: var(--ink); background: var(--accent-dim); border-color: var(--accent-line); }
.bx-alb__fchip.is-on .bx-count { color: var(--ink-2); }
/* Au-dessus de 1 280 px : toutes les familles se voient, sur plusieurs lignes, sans défilement ni bord estompé. */
@media (min-width: 1281px) {
  .bx-alb__famrow > .bx-chips { flex-wrap: wrap; overflow: visible; -webkit-mask-image: none; mask-image: none; }
}
/* Barre collée réduite : seule la première ligne (recherche, tri, cartes manquantes) reste collée ; familles,
   raretés et filtres défilent avec la page, sous elle. Sur un portable (écran de 900 px de haut ou moins), pour
   garder plus de deux rangées de cartes visibles ; au-dessus de 1 280 px de large, quelle que soit la hauteur,
   parce que les familles y prennent plusieurs lignes (collée en entier, la barre y ferait 237 px).
   La barre perd sa boîte (display: contents) pour que sa première ligne se colle sur toute la hauteur de
   l'album ; marges, fond et filet passent sur les lignes. Collée, la ligne montre la puce « Filtres » à la place
   du compteur (posée par-dessus : la ligne garde sa taille, rien ne bouge). */
@media (min-width: 961px) and (max-height: 900px), (min-width: 1281px) {
  .bx-alb__tools { display: contents; }
  .bx-alb__tools > .bx-alb__row { position: sticky; top: var(--head-h); z-index: 20; margin: 0 calc(var(--gutter) * -1); padding: 10px var(--gutter);
    border-bottom: 1px solid transparent; transition: border-color .2s, background-color .2s; }
  .bx-alb__tools.is-stuck > .bx-alb__row { background: var(--bg); border-bottom-color: var(--line); }
  .bx-alb__tools > [data-filters] { margin: 10px 0 30px; }
  .bx-alb__fchip { display: inline-flex; position: absolute; top: 50%; right: 0; transform: translateY(-50%); visibility: hidden; }
  .bx-alb__tools.is-stuck .bx-alb__fchip { visibility: visible; }
  .bx-alb__tools.is-stuck .bx-alb__count { opacity: 0; }
}
@media (max-width: 960px) {
  .bx-alb__tools, .bx-alb__tools.is-stuck { position: static; margin: 0 0 16px; padding: 0; background: none; border: 0; }
}
/* Téléphone : au-dessus des cartes, la recherche, puis « Trier et filtrer » et les familles sur une seule rangée.
   Le tri, l'interrupteur et les raretés passent dans la feuille du bas (openSheet, album.js) ; le compteur reste
   annoncé aux lecteurs d'écran, et s'affiche sur le bouton de la feuille. */
@media (max-width: 600px) {
  .bx-alb__search { flex-basis: 100%; max-width: none; }
  .bx-alb__tools .bx-alb__row > .bx-select, .bx-alb__tools .bx-alb__miss, .bx-alb__tools [data-filters] { display: none; }
  .bx-alb__count { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .bx-alb__fbtn { display: inline-flex; }
  .bx-alb__fsep { display: block; align-self: flex-start; margin: 10px 8px 0; }   /* centré sur les puces de 40 px */
}

/* Feuille « Trier et filtrer » (téléphone) : les contrôles de la barre, rangés par rubrique, puces à la ligne. */
.bx-alb__sheet { gap: 22px; }
.bx-alb__sheet .bx-field { gap: 10px; }
.bx-alb__sheet .bx-field:has(> .bx-alb__grp:empty) { display: none; }
.bx-alb__sheet .bx-select { width: 100%; }
.bx-alb__sheet .bx-alb__miss { align-self: flex-start; }
.bx-alb__sheet .bx-alb__grp { display: flex; flex-wrap: wrap; gap: 8px; }
/* « Effacer » à sa largeur, « Afficher 2 179 cartes » prend le reste (à parts égales, il débordait). */
.bx-alb__sheetbtns > .bx-btn { flex: 0 0 auto; }
.bx-alb__sheetbtns > .bx-btn--primary { flex: 1 1 auto; }

/* ── Album : grille virtuelle (seules les cartes visibles sont dans la page) ── */
.vgrid { position: relative; contain: layout; }
.vcell { position: absolute; top: 0; left: 0; }
.vcell > .bx-cardbtn { width: 100%; }
.bx-alb [data-empty] .bx-empty { margin-top: 4px; }

/* Intercalaire du tri par rareté (cellule pleine largeur de la grille) : « Divin · 3 / 34 » posé en bas de la
   cellule, la place au-dessus sépare les raretés ; filet qui s'efface vers la droite, comme un titre de section. */
.bx-alb__sect { --rc: var(--r1); display: flex; align-items: center; gap: 10px; min-width: 0; height: 28px; }
.bx-alb__sect[data-r="2"] { --rc: var(--r2); }
.bx-alb__sect[data-r="3"] { --rc: var(--r3); }
.bx-alb__sect[data-r="4"] { --rc: var(--r4); }
.bx-alb__sect[data-r="5"] { --rc: var(--r5); }
.bx-alb__sect[data-r="6"] { --rc: var(--r6); }
.vcell.is-full > .bx-alb__sect { position: absolute; left: 0; right: 0; bottom: 0; }
.bx-alb__sectname { display: inline-flex; align-items: center; gap: 9px; flex: 0 0 auto; font: 800 1.06rem/1 var(--display); letter-spacing: -.01em; color: var(--rc); white-space: nowrap; }
.bx-alb__sectname::before { content: ''; flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.bx-alb__sectsep { flex: 0 0 auto; font: 700 15px/1 var(--font); color: var(--ink-4); }
.bx-alb__sectn { flex: 0 0 auto; font: 700 13px/1 var(--mono); font-variant-numeric: tabular-nums; color: var(--ink-3); word-spacing: -.32em; white-space: nowrap; }
.bx-alb__sectn b { font-weight: 700; color: var(--ink); }
.bx-alb__sect::after { content: ''; flex: 1 1 auto; min-width: 0; height: 1px; background: linear-gradient(90deg, var(--line-2), transparent); }

/* « À découvrir » : sous les cartes d'un joueur qui débute, les silhouettes des plus rares qui lui manquent.
   Même gabarit d'intercalaire, sans couleur de rareté ; sur PC et tablette, des rangées complètes sur les
   colonnes de la grille (--disc-cols et --disc-gap posés par album.js : une rangée de 7 ou 8, deux de 4 sur
   tablette), une rangée qui défile au doigt sur téléphone. */
.bx-alb__disc { margin-top: 40px; }
.bx-alb__sect.is-disc .bx-alb__sectname { color: var(--ink); }
.bx-alb__sect.is-disc .bx-alb__sectname::before { content: none; }
.bx-alb__disctxt { margin: 6px 0 16px; }
.bx-alb__discrow { display: grid; grid-template-columns: repeat(var(--disc-cols, 8), minmax(0, 1fr)); gap: var(--disc-gap, 18px); overflow: visible; padding: 4px 0 0; }
.bx-alb__discrow > [role="listitem"] { min-width: 0; }
.bx-alb__discact { display: flex; margin-top: 18px; }
@media (max-width: 600px) {
  .bx-alb__disc { margin-top: 32px; }
  .bx-alb__discrow { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: calc((100% - 24px) / 2.4); gap: 12px;
    overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; padding: 4px 0 6px; }
  .bx-alb__discrow > [role="listitem"] { scroll-snap-align: start; }
  .bx-alb__discact .bx-btn { flex: 1 1 auto; }
}

/* Mode sélection : rond vide sur les cartes qu'on peut cocher, manquantes estompées. */
.bx-alb__grid.is-selecting .bx-cardbtn[aria-pressed="false"]::after {
  content: ''; position: absolute; z-index: 6; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .45); background: rgba(7, 7, 9, .85); box-shadow: 0 0 0 2px var(--bg);
}
.bx-alb__grid.is-selecting .bx-cardbtn[aria-disabled="true"] { opacity: .32; cursor: default; }
.bx-alb__grid.is-selecting .bx-cardbtn[aria-disabled="true"]:hover { transform: none; }

/* Barre de sélection flottante (cahier §7.3 point 4) */
.bx-selbar {
  position: fixed; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 80; transform: translateX(-50%);
  display: flex; align-items: center; gap: 8px; width: min(720px, calc(100vw - 24px)); padding: 10px 12px;
  border-radius: 18px; background: var(--card-2); border: 1px solid var(--line-2); box-shadow: var(--shadow-pop);
  animation: bx-selbar-in .24s var(--ease-out);
}
@keyframes bx-selbar-in { from { opacity: 0; transform: translate(-50%, 12px); } }
.bx-selbar__n { flex: 1 1 auto; min-width: 0; padding-left: 6px; font: 600 14px/1.3 var(--font); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bx-selbar__n b { font: 700 15px/1 var(--mono); color: #fff; word-spacing: -.32em; }
.bx-selbar__btns { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.bx-selbar__amt { font-family: var(--mono); word-spacing: -.32em; }
.bx-selbar .bx-spin { width: 14px; height: 14px; }
.bx-alb__sm { display: none; }
@media (max-width: 600px) {
  .bx-alb__lg { display: none; }
  .bx-alb__sm { display: inline; }
  .bx-selbar { flex-wrap: wrap; gap: 6px 8px; padding: 6px 8px 10px 10px; }
  .bx-selbar__n { flex: 1 1 0; }
  .bx-selbar__x { order: 1; }
  .bx-selbar__btns { order: 2; flex: 1 1 100%; }
  .bx-selbar__btns .bx-btn { flex: 1 1 0; min-width: 0; padding: 0 8px; }
  .bx-selbar__amt { display: none; }
}
/* Le pied de page garde ses 48 px sous son dernier texte, comptés au-dessus de la barre : 16 px d'écart
   au bas de l'écran + 62 px de barre sur une ligne, 104 px sur deux lignes au téléphone. */
body.bx:has(.bx-selbar) .bx-foot { padding-bottom: calc(48px + 78px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 600px) { body.bx:has(.bx-selbar) .bx-foot { padding-bottom: calc(48px + 120px + env(safe-area-inset-bottom, 0px)); } }
/* Les notifications passent au-dessus de la barre (sauf quand une fenêtre est ouverte : elles sont en haut). */
body.bx:has(.bx-selbar):not(:has(.bx-modal)) .bx-toasts { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 600px) { body.bx:has(.bx-selbar):not(:has(.bx-modal)) .bx-toasts { bottom: calc(124px + env(safe-area-inset-bottom, 0px)); } }

/* ── Fenêtres de l'album : défausse des doublons, étiquettes ─────────────────── */
.bx-alb__plan { display: grid; gap: 12px; min-height: 64px; align-content: center; }
.bx-alb__plan > .bx-spin { justify-self: center; }
.bx-alb__plan .bx-pill .bx-num { margin-left: 2px; letter-spacing: 0; color: var(--ink); word-spacing: -.32em; }
.bx-alb__plansum { font-size: 15px; line-height: 1.55; color: var(--ink-2); }

.bx-tagrow { display: grid; grid-template-columns: 10px minmax(0, 1fr) 128px; grid-template-areas: "dot name color" ". n act"; align-items: center; gap: 10px 12px;
  padding: 12px 14px; border-bottom: 1px solid var(--line); }
.bx-tagrow:last-child { border-bottom: 0; }
.bx-tagrow > .bx-tagdot { grid-area: dot; width: 10px; height: 10px; }
.bx-tagrow > .bx-input { grid-area: name; }
.bx-tagrow > .bx-select { grid-area: color; }
.bx-tagrow__n { grid-area: n; white-space: nowrap; }
.bx-tagrow__act { grid-area: act; display: flex; justify-content: flex-end; gap: 4px; }
@media (max-width: 600px) {
  .bx-tagrow { grid-template-columns: 10px minmax(0, 1fr) auto; grid-template-areas: "dot name name" ". color color" ". n act"; padding: 12px; }
}
.bx-chip .bx-spin { width: 14px; height: 14px; border-width: 2px; }

/* ── Fiche d'une carte (cahier §7.4) ──────────────────────────────────────── */
.bx-cd-modal .bx-modal__body { padding: 32px; }
/* Bouton de fermeture qui reste visible quand on fait défiler la fiche (pas d'en-tête de fenêtre). */
.bx-cd__x { position: sticky; top: 32px; z-index: 6; height: 0; }
.bx-cd__x .bx-btn { position: absolute; top: -18px; right: -18px; background: var(--card-2); border-color: var(--line-2); }
.bx-cd__x .bx-btn:hover { background: #1d1d28; }

.bx-cd { display: grid; grid-template-columns: 360px minmax(0, 1fr); gap: 32px; align-items: start; }
.bx-cd__left { position: sticky; top: 32px; min-width: 0; }
.bx-cd__card { width: 100%; }
.bx-cd__copies { justify-content: center; margin-top: 16px; }
.bx-cd__copy { gap: 6px; }
.bx-cd__copy b { font: 700 13px/1 var(--mono); font-variant-numeric: tabular-nums; color: var(--ink); word-spacing: -.32em; }
.bx-cd__iri { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--chroma-ring); }
.bx-cd__star, .bx-cd__lk { display: inline-flex; }
.bx-cd__star svg { width: 13px; height: 13px; color: #f5c451; }
.bx-cd__lk svg { width: 12px; height: 12px; color: var(--ink-3); }
.bx-cd__cap { margin: 12px 0 0; text-align: center; font: 500 13px/1.5 var(--font); color: var(--ink-3); }
.bx-cd__cap .bx-num { color: var(--ink-2); word-spacing: -.32em; }

.bx-cd__right { min-width: 0; padding-top: 2px; }
.bx-cd__pills { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding-right: 48px; }
.bx-cd__name { margin: 14px 0 0; font: 800 1.9rem/1.05 var(--display); letter-spacing: -.02em; color: #fff; text-wrap: balance; overflow-wrap: anywhere; }
.bx-cd__sub { margin: 8px 0 0; font: 400 15px/1.5 var(--font); color: var(--ink-2); }
.bx-cd__right > .bx-ability { margin-top: 20px; }
.bx-cd__flavor { margin: 16px 0 0; max-width: 64ch; font: 400 14px/1.65 var(--font); color: var(--ink-3); }

/* Le coup en jeu : cadre 16:9, l'animation n'est jamais agrandie (object-fit: scale-down) */
.bx-cd__move { margin: 22px 0 0; }
.bx-cd__move .bx-micro { margin-bottom: 10px; }
.bx-cd__frame { display: grid; place-items: center; max-width: 400px; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden; background: #0d0e13; border: 1px solid var(--line); }
.bx-cd__frame img { display: block; width: 100%; height: 100%; object-fit: scale-down; }

/* Attaque et défense */
.bx-cd__power { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 22px; }
.bx-cd__power > div { padding: 14px 16px 13px; border-radius: 14px; background: var(--bg-2); border: 1px solid var(--line); }
.bx-cd__power b { display: block; font: 700 1.6rem/1 var(--mono); font-variant-numeric: tabular-nums; word-spacing: -.32em; }
.bx-cd__power .is-atk b { color: #ffb4a8; }
.bx-cd__power .is-def b { color: #a8c8ff; }
.bx-cd__power .bx-micro { margin-top: 9px; }

/* Données de la carte : deux colonnes, libellé en micro-libellé, valeur en mono */
.bx-cd__dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; margin: 18px 0 0; }
.bx-cd__dd { display: flex; flex-direction: column; gap: 7px; min-width: 0; padding: 12px 0; border-top: 1px solid var(--line); }
.bx-cd__dd.is-wide { grid-column: 1 / -1; }
.bx-cd__dd dt { font: 800 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.bx-cd__dd dd { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; font: 700 15px/1.3 var(--mono); color: var(--ink); }
.bx-cd__dd dd .bx-amt { vertical-align: baseline; }
.bx-cd__unit, .bx-cd__none, .bx-cd__txt { font: 500 14px/1.3 var(--font); color: var(--ink-3); white-space: pre; }
.bx-cd__txt { color: var(--ink-2); white-space: normal; }
.bx-cd__dd dd .bx-link, .bx-cd__dd dd .bx-plink { font: 700 14px/1.3 var(--font); }
/* Atelier : ce qui manque pour fabriquer la carte, en ligne propre sous le coût. */
.bx-cd__miss { flex: 1 1 100%; margin-top: 6px; font: 500 13px/1.45 var(--font); color: var(--ink-3); }
.bx-cd__miss .bx-num { color: var(--ink-2); }
/* Liens dans une valeur : zone de toucher de 40 px sans décaler la ligne. */
.bx-cd__dd dd a { display: inline-flex; align-items: center; min-width: 40px; padding: 12px 6px; margin: -12px -6px; }
.bx-cd__dlskel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 24px; margin-top: 18px; }
.bx-cd__dlskel .bx-skel { height: 42px; border-radius: 10px; }
.bx-cd__err { margin-top: 18px; font-size: 14px; color: var(--ink-3); }
.bx-cd__err .bx-link { display: inline-flex; align-items: center; min-height: 40px; padding: 0; border: 0; background: none; font: inherit; font-weight: 700; cursor: pointer; }

.bx-cd__wiki { display: inline-flex; align-items: center; min-height: 40px; margin-top: 8px; font-size: 14px; }

/* Actions : collées en bas de la colonne tant qu'on fait défiler la fiche. Deux visibles au plus, le reste dans « ... ». */
.bx-cd__act { position: sticky; bottom: 0; z-index: 3; display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 14px; padding: 16px 0; background: #101019; border-top: 1px solid var(--line); }
/* Fondu au-dessus du filet : la ligne qui passe sous la barre s'efface au lieu d'être tranchée net. Au bout du
   défilement, il ne couvre que la marge de 14 px et le bas vide du lien du wiki ou de la dernière donnée. */
.bx-cd__act::before { content: ''; position: absolute; left: 0; right: 0; bottom: calc(100% + 1px); height: 22px;
  background: linear-gradient(rgba(16, 16, 25, 0), #101019); pointer-events: none; }
.bx-cd__fav[aria-pressed="true"] { color: #f5c451; border-color: rgba(245, 196, 81, .4); }
.bx-cd__note { margin-top: -4px; }
.bx-cd__skbtn { width: 210px; height: 44px; border-radius: 999px; }
.bx-cd__skic { width: 40px; height: 40px; border-radius: 999px; }

@media (max-width: 860px) {
  .bx-cd { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .bx-cd__left { position: static; }
  .bx-cd__card { width: min(340px, 70vw); margin: 0 auto; }
  .bx-cd__pills { padding-right: 0; }
  /* Une colonne : le texte prend toute la largeur et passerait sous une croix flottante. La croix vit donc
     dans une barre collante opaque de 52 px, qui ne prend son filet qu'une fois la fiche défilée (.is-scrolled, detail.js). */
  .bx-cd__x { top: 0; display: flex; align-items: center; justify-content: flex-end; height: 52px; margin: -32px -32px 0; padding: 0 14px;
    background: #101019; border-bottom: 1px solid transparent; transition: border-color .2s; }
  .bx-cd__x .bx-btn { position: static; }
  .bx-cd-modal .bx-modal__box.is-scrolled .bx-cd__x { border-bottom-color: var(--line); }
}
/* Téléphone : feuille pleine hauteur, carte à 70 % de la largeur, puis les informations. */
@media (max-width: 600px) {
  .bx-cd-modal .bx-modal__box { height: calc(100dvh - 10px); max-height: none; }
  .bx-cd-modal .bx-modal__body { padding: 16px 16px 0; }
  /* La poignée de la feuille passe dans la barre de la croix : elle reste en haut quand on fait défiler. */
  .bx-cd-modal .bx-modal__box::before { display: none; }
  .bx-cd__x { margin: -16px -16px 0; padding: 0 8px; }
  .bx-cd__x::before { content: ''; position: absolute; top: 8px; left: 50%; width: 44px; height: 5px; margin-left: -22px; border-radius: 99px; background: rgba(255, 255, 255, .18); }
  .bx-cd__card { width: 70vw; }
  .bx-cd__name { font-size: 1.6rem; }
  .bx-cd__dl { column-gap: 16px; }
  .bx-cd__act { padding: 12px 0 calc(12px + env(safe-area-inset-bottom, 0px)); }
  .bx-cd__act > .bx-btn:not(.bx-btn--icon) { flex: 1 1 auto; }
  /* Action secondaire d'une carte manquante (liste de souhaits à côté de l'atelier) : dans « ... ». */
  .bx-cd__act > .bx-cd__opt { display: none; }
  .bx-cd__note { padding-bottom: 16px; }
}

/* ── Page partageable d'une carte (#/carte/:id) ─────────────────────────────── */
.bx-cdpage { display: grid; justify-items: center; gap: 12px; max-width: 440px; margin: clamp(8px, 4vh, 40px) auto 0; text-align: center; }
.bx-cdpage__card { width: min(320px, 76vw); margin-bottom: 10px; }
.bx-cdpage .bx-cd__pills { justify-content: center; padding: 0; }
.bx-cdpage__name { font: 800 clamp(1.6rem, 1.2rem + 1.4vw, 2.2rem)/1.05 var(--display); letter-spacing: -.02em; color: #fff; text-wrap: balance; overflow-wrap: anywhere; }
.bx-cdpage .bx-cd__sub { margin: 0; }
.bx-cdpage__act { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 10px; }

/* ── Mettre en vitrine ─────────────────────────────────────────────────────── */
.bx-cd__shows .bx-row { min-height: 56px; }
.bx-cd__rowact { flex: 0 0 auto; font: 700 13px/1 var(--font); color: var(--accent-2); }
.bx-cd__rowact.is-in { color: var(--ink-3); }
.bx-cd__newshow { flex-wrap: nowrap; }
.bx-cd__newshow .bx-input { flex: 1 1 auto; width: auto; min-width: 0; }


/* ===== css/pages/codes.css ===== */
/* BloxMasters - Codes cadeaux (src/js/plugins/codes.js) : panneau de la page Paquets (entre les missions et
   le coffre du jour) et bloc de la page d'administration. Jetons du cahier §3.1 seulement : aucune lueur,
   aucun emoji, un seul bouton principal par ligne, cibles de 44 px sur téléphone. */

.bx-code { margin-top: 14px; }
.bx-code__form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 420px); align-items: center; gap: 12px 24px; padding: 16px 20px; }
.bx-code__txt { display: grid; gap: 4px; min-width: 0; }
.bx-code__txt h3 { margin: 0; }
.bx-code__txt .bx-small { margin: 0; color: var(--ink-3); }
.bx-code__row { display: flex; gap: 10px; }
.bx-code__in { flex: 1 1 auto; min-width: 0; font-family: var(--mono); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.bx-code__in::placeholder { font-family: var(--font); font-weight: 500; letter-spacing: 0; text-transform: none; }
.bx-code__row .bx-btn { flex: 0 0 auto; }
/* Code arrivé par un lien : le panneau se signale (bordure d'accent), le joueur n'a plus qu'à valider. */
.bx-code.is-pending { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-dim); }

@media (max-width: 700px) {
  .bx-code__form { grid-template-columns: minmax(0, 1fr); padding: 16px 18px; }
}

/* Administration : récompenses et limites en grille souple, liste des codes défilante. */
.bx-adm-codes { margin-bottom: 8px; }
/* Champs alignés par le bas : un libellé sur deux lignes (« Paquets Double Légende ») ne décale pas sa case. */
.bx-adm-codes__rw { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); align-items: end; gap: 10px; }
.bx-adm-codes__list { border-top: 1px solid var(--line); }
.bx-adm-codes__scroll { margin: 16px 20px 20px; max-height: 420px; }
.bx-adm-codes__scroll .bx-table td { vertical-align: top; padding-top: 10px; padding-bottom: 10px; }
.bx-adm-codes__scroll .bx-adm__ref { display: block; margin-top: 3px; color: var(--ink-3); font-size: 12px; }
.bx-adm-codes__code { white-space: nowrap; }
.bx-adm-codes__acts { display: flex; justify-content: flex-end; gap: 6px; white-space: nowrap; }
@media (max-width: 700px) {
  .bx-adm-codes__scroll { margin: 14px 12px 16px; }
}


/* ===== css/pages/combat.css ===== */
/* BloxMasters - duels et raid (cahier docs/BLOXMASTERS_DESIGN.md §7.7 et §7.8).
   Salon des duels, choix de l'équipe, écran de combat (bandeau des PV, équipes, déroulé, verdict),
   question commune aux duels et au raid (.bx-quiz, .bx-ans, .bx-qhead), raid du jour.
   Uniquement de la mise en page : boutons, pastilles, panneaux, listes, barres viennent de
   components.css, la carte de card.css. */

/* ── Salon des duels : les trois modes (modèle .vt-pillar des raids) ───────── */
.bx-modes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.bx-mode { position: relative; display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 22px;
  border-radius: var(--r-l); background: var(--card); border: 1px solid var(--line); box-shadow: var(--hl);
  transition: border-color .2s, transform .2s var(--ease); }
.bx-mode::before { content: ''; position: absolute; left: 22px; right: 22px; top: -1px; height: 2px; border-radius: 0 0 2px 2px; background: var(--accent); opacity: .8; }
.bx-mode:hover { border-color: var(--accent-line); transform: translateY(-2px); }
.bx-mode__n { font: 700 13px/1 var(--mono); color: var(--accent-2); }
.bx-mode p { font-size: 15px; line-height: 1.5; color: var(--ink-2); }
.bx-mode__act { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; padding-top: 6px; }
.bx-mode__act .bx-chip { gap: 9px; }
.bx-mode__act .bx-amt { gap: 4px; color: var(--ink-3); }
.bx-mode__act .bx-amt .bx-num { font-size: 12px; font-weight: 700; }
/* Nouveau joueur (aucun duel) : l'entraînement, seul mode jouable sans ami, passe en tête (views/duels.js
   le place aussi en premier et le numérote 01). */
.bx-modes.is-newbie .bx-mode--levels { order: -1; }
/* Victoires récompensées du jour faites : la phrase au-dessus des niveaux (qui n'affichent plus de gain). */
.bx-mode .bx-mode__note { font-size: 13px; line-height: 1.45; color: var(--ink-3); }
/* En-tête du salon sur téléphone : le bouton principal d'abord, sur toute la largeur, l'autre dessous. */
@media (max-width: 600px) {
  .bx-du-ph .bx-ph__act > .bx-btn { flex: 1 1 100%; }
  .bx-du-ph .bx-ph__act > .bx-btn--primary { order: -1; }
}
@media (max-width: 900px) {
  .bx-modes { grid-template-columns: 1fr; gap: 12px; }
  .bx-mode { padding: 18px; }
}
/* Tablette : un mode par ligne, le bouton à droite du texte. Les trois niveaux de l'entraînement
   passent sous la phrase, sur une ligne : à droite, ils se coupaient en deux plus un. */
@media (max-width: 900px) and (min-width: 601px) {
  .bx-mode { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: 'n act' 't act' 'p act'; align-items: center; column-gap: 24px; row-gap: 8px; }
  .bx-mode__n { grid-area: n; }
  .bx-mode h3 { grid-area: t; }
  .bx-mode p { grid-area: p; }
  .bx-mode__act { grid-area: act; justify-content: flex-end; max-width: 300px; margin: 0; padding: 0; }
  .bx-mode--levels { grid-template-columns: minmax(0, 1fr); grid-template-areas: 'n' 't' 'p' 'act'; }
  .bx-mode--levels.has-note { grid-template-areas: 'n' 't' 'p' 'note' 'act'; }
  .bx-mode .bx-mode__note { grid-area: note; }   /* plus fort que .bx-mode p (zone p) */
  .bx-mode--levels .bx-mode__act { justify-content: flex-start; max-width: none; padding-top: 8px; }
}

/* Lignes du salon : avatar (ou vignette de l'adversaire du jeu), nom, équipe adverse, état */
.bx-cb-list { overflow: hidden; }   /* le fond d'une ligne survolée suit l'arrondi du panneau */
.bx-cb-list .bx-row { flex-wrap: wrap; row-gap: 10px; }
.bx-cb-row a.bx-row__main, a.bx-cb-row { text-decoration: none; color: inherit; }
.bx-cb-row a.bx-row__main:hover .bx-row__title { color: var(--accent-2); }
.bx-cb-ava { position: relative; display: block; width: 32px; height: 32px; flex: 0 0 32px; border-radius: 50%; overflow: hidden; }
.bx-cb-ava .bx-mini__vis { width: 32px; height: 32px; flex-basis: 32px; border-radius: 50%; }
.bx-cb-ava .bx-mini__vis[data-r] img { inset: 1px; border-radius: 50%; }
.bx-cb-ava .bx-mini__vis.is-contain[data-r] img { padding: 3px; }
.bx-cb-strip { display: flex; gap: 4px; flex: 0 0 auto; }
.bx-cb-strip .bx-mini__vis { width: 32px; height: 32px; flex-basis: 32px; border-radius: 8px; }
.bx-cb-strip .bx-mini__vis[data-r] img { border-radius: 7px; }
.bx-cb-strip .bx-mini__vis.is-contain[data-r] img { padding: 3px; }
.bx-cb-strip .bx-mini__glyph { font-size: 12px; }
.bx-cb-row__act { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.bx-cb-row__go { display: inline-grid; place-items: center; width: 20px; color: var(--ink-3); }
.bx-cb-row__go svg { width: 16px; height: 16px; }
.bx-cb-when { white-space: nowrap; }
.bx-row__num.is-up { color: var(--ok); }
.bx-row__num.is-down { color: var(--bad); }
@media (max-width: 600px) {
  .bx-cb-strip { display: none; }
  .bx-cb-row__act { width: 100%; justify-content: flex-end; }
  /* Au téléphone, la deuxième ligne passe à la ligne plutôt que de perdre l'heure sous des points de suspension. */
  .bx-cb-list .bx-row__meta { white-space: normal; }
}

/* ── Choix de l'équipe (fenêtre BM.pickTeam) ──────────────────────────────── */
/* Consigne (une phrase, deux au raid : ce que deviennent les capacités) */
.bx-team__note { display: grid; gap: 6px; margin-bottom: 18px; max-width: 620px; }
.bx-team__note + .bx-empty { padding: 24px 12px 8px; }
.bx-team__slots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.bx-team__col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.bx-team__ab { font-size: 13px; line-height: 1.45; color: var(--ink-3); text-align: center; text-wrap: pretty; }
.bx-team__empty { display: grid; place-content: center; justify-items: center; gap: 10px; width: 100%; aspect-ratio: 5 / 7; padding: 0;
  border-radius: 12px; border: 1px dashed var(--line-2); background: rgba(255, 255, 255, .02); color: var(--ink-2);
  font: 700 13px/1 var(--font); cursor: pointer; transition: border-color .15s, color .15s; }
.bx-team__empty:hover { border-color: var(--accent-line); color: var(--ink); }
.bx-team__sum { display: grid; gap: 14px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.bx-team__syn { display: grid; gap: 8px; }
/* Pendant le chargement : les mêmes blocs que l'équipe chargée (carte 5/7, deux lignes de capacité,
   deux chiffres, une phrase), pour que la fenêtre ne change presque pas de taille à l'arrivée. */
.bx-team__skab { display: grid; justify-items: center; gap: 7px; padding-top: 3px; }
.bx-team__skab .bx-skel--line { width: 88%; }
.bx-team__skab .bx-skel--line + .bx-skel--line { width: 60%; }
.bx-team__sum > .bx-skel--line { width: min(400px, 72%); }
@media (max-width: 600px) {
  .bx-team__slots { gap: 8px; }
  .bx-team__ab, .bx-team__skab { display: none; }
}

/* ── Écran de combat ───────────────────────────────────────────────────────── */
/* Colonne flex (et non grille) : le bandeau des PV reste collé tant que l'écran défile. */
.bx-cb { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.bx-cb-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 40px; }
.bx-cb-top > .bx-back { margin: 0 0 0 -8px; }
.bx-cb--play .bx-cb-top, .bx-cb--intro .bx-cb-top { width: 100%; max-width: 720px; margin: 0 auto -6px; }
.bx-cb-ph { margin: 0; }
.bx-cb-sub { font-size: 15px; line-height: 1.5; color: var(--ink-2); max-width: 620px; }

/* Bandeau des PV : l'adversaire à gauche, « Toi » à droite, collé sous l'en-tête sur PC.
   Couche 65 : au-dessus du décor saisonnier (60), sous l'en-tête (70) et ses menus (cahier 3.1).
   Collé contre l'en-tête, sans écart : un écart laissait voir le haut des équipes qui défilaient
   entre les deux. Une fois collé (.is-stuck, posé par views/duels.js), ses coins du haut deviennent
   droits et son filet du haut se confond avec celui de l'en-tête. */
.bx-vs { position: sticky; top: var(--head-h); z-index: 65;
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 18px;
  padding: 12px 18px; border-radius: var(--r-l); background: var(--card); border: 1px solid var(--line-2); box-shadow: var(--shadow-card), var(--hl); }
.bx-vs__side { display: flex; align-items: center; gap: 12px; min-width: 0; }
.bx-vs__side.is-me { flex-direction: row-reverse; text-align: right; }
.bx-vs__txt { display: grid; gap: 7px; flex: 1 1 auto; min-width: 0; }
.bx-vs__name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-vs__mid { font: 900 1rem/1 var(--display); letter-spacing: -.01em; color: var(--ink-3); }
@media (min-width: 961px) { .bx-vs.is-stuck { border-top-color: transparent; border-top-left-radius: 0; border-top-right-radius: 0; } }
@media (max-width: 960px) { .bx-vs { position: static; } }
@media (max-width: 600px) {
  .bx-vs { gap: 10px; padding: 12px; }
  .bx-vs__side { gap: 8px; }
}
@media (max-width: 480px) { .bx-vs .bx-cb-ava { display: none; } }

/* Équipes : trois cartes de chaque côté, « VS » entre les deux */
.bx-cb-teams { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 22px; }
.bx-cb-vsmark { font: 900 1rem/1 var(--display); color: var(--ink-3); }
.bx-cb-side { position: relative; display: grid; gap: 10px; align-content: start; min-width: 0; }
.bx-cb-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.bx-cb-card { transition: transform .2s var(--ease), opacity .3s; }
.bx-cb-card.is-atk { outline: 2px solid var(--accent); outline-offset: 3px; }
.bx-cb-card.is-used { opacity: .45; }
.bx-cb-slot { display: grid; place-items: center; aspect-ratio: 5 / 7; border-radius: 12px; border: 1px dashed var(--line-2); color: var(--ink-3); font-size: 13px; font-weight: 600; text-align: center; }
.bx-cb-syn { gap: 6px; }
@media (max-width: 760px) {
  .bx-cb-teams { grid-template-columns: 1fr; gap: 14px; }
  .bx-cb-vsmark { justify-self: center; }
  .bx-cb-cards { gap: 8px; }
}

/* Chiffre des dégâts, posé sur l'équipe touchée */
.bx-dmgpop { position: absolute; left: 50%; top: 52%; z-index: 7; display: none; transform: translate(-50%, -50%);
  font: 900 2.4rem/1 var(--display); letter-spacing: -.03em; color: var(--bad); white-space: nowrap; pointer-events: none;
  text-shadow: 0 2px 12px rgba(7, 7, 9, .85); }
.bx-dmgpop.is-on { display: block; animation: bx-dmg-in .4s var(--ease-out) backwards, bx-dmg-out .3s ease-in 1.1s forwards; }
@keyframes bx-dmg-in { from { opacity: 0; transform: translate(-50%, -50%) scale(.6); } }
@keyframes bx-dmg-out { to { opacity: 0; } }
/* Téléphone : le chiffre reste sur la carte touchée au lieu de couvrir ses voisines. */
@media (max-width: 600px) { .bx-dmgpop { font-size: 1.6rem; } }

/* Rejeu : équipe adverse, déroulé, ton équipe */
.bx-cb-arena { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px) minmax(0, 1fr); align-items: start; gap: 22px; }
.bx-cb-log .bx-list { min-height: 112px; }
.bx-cb-log__empty { padding: 18px 16px; font-size: 13px; color: var(--ink-3); }
.bx-cb-line { align-items: flex-start; animation: bx-in .3s var(--ease) backwards; }
.bx-cb-line .bx-row__main { display: grid; gap: 3px; }
.bx-cb-line .bx-row__meta { white-space: normal; }
.bx-cb-line__fx { display: block; font-size: 13px; line-height: 1.4; color: var(--accent-2); }
.bx-cb-line__dmg { margin-left: auto; padding-top: 2px; font: 700 14px/1.2 var(--mono); color: var(--bad); white-space: nowrap; word-spacing: -.32em; }
.bx-cb-line__dmg.is-zero { font: 600 13px/1.2 var(--font); color: var(--ok); word-spacing: normal; }
@media (max-width: 1100px) {
  .bx-cb-arena { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bx-cb-log { grid-column: 1 / -1; order: 3; }
}
@media (max-width: 640px) { .bx-cb-arena { grid-template-columns: 1fr; gap: 16px; } }

/* Verdict */
.bx-cb-end { display: grid; justify-items: center; gap: 12px; padding: 30px 22px 28px; text-align: center; }
.bx-cb-end .bx-h1.is-win { color: var(--ok); }
.bx-cb-end .bx-h1.is-lose { color: var(--bad); }
.bx-cb-end__why, .bx-cb-end__cap { max-width: 520px; font-size: 15px; line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }
.bx-cb-end__facts { justify-content: center; }
.bx-cb-end__act { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 6px; }
@media (max-width: 600px) { .bx-cb-end { padding: 24px 16px 20px; } .bx-cb-end__act .bx-btn { flex: 1 1 100%; } }

/* Revoir mes questions */
.bx-cb-recap > summary { display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 0 20px; list-style: none; font-weight: 700; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bx-cb-recap > summary::-webkit-details-marker { display: none; }
.bx-cb-recap > summary .bx-count { font: 700 12px/1 var(--mono); color: var(--accent-2); }
.bx-cb-recap > summary svg { width: 16px; height: 16px; margin-left: auto; color: var(--ink-3); transition: transform .2s; }
.bx-cb-recap[open] > summary { border-bottom: 1px solid var(--line); }
.bx-cb-recap[open] > summary svg { transform: rotate(180deg); }
.bx-cb-q { display: grid; justify-items: start; gap: 8px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.bx-cb-q:last-child { border-bottom: 0; }
.bx-cb-q__card { font-size: 13px; color: var(--ink-3); }
.bx-cb-q__q { font-weight: 700; line-height: 1.45; }
.bx-cb-q__a { display: flex; flex-wrap: wrap; gap: 6px; }
.bx-cb-q__a > span { display: inline-flex; align-items: center; min-height: 30px; padding: 4px 11px; border-radius: var(--r-s);
  border: 1px solid var(--line); background: rgba(255, 255, 255, .03); font-size: 13px; line-height: 1.3; color: var(--ink-3); }
.bx-cb-q__a > .is-good { color: var(--ok); background: var(--ok-dim); border-color: var(--ok-line); font-weight: 700; }
.bx-cb-q__a > .is-bad { color: var(--bad); background: var(--bad-dim); border-color: var(--bad-line); text-decoration: line-through; }
.bx-cb-q .bx-link { font-size: 13px; display: inline-flex; align-items: center; min-height: 32px; }
@media (max-width: 960px) { .bx-cb-q .bx-link { min-height: 40px; } }
@media (max-width: 600px) { .bx-cb-recap > summary, .bx-cb-q { padding-left: 16px; padding-right: 16px; } }

/* Attente de l'adversaire : trois points qui battent (fixes en mouvement réduit) */
.bx-cb-wait { display: grid; justify-items: center; gap: 12px; padding: 30px 22px 26px; text-align: center; }
.bx-cb-wait__bar { width: min(420px, 100%); }
.bx-cb-wait__n { font-size: 13px; color: var(--ink-3); }
.bx-cb-wait__n .bx-num { color: var(--ink); }
.bx-dots { display: inline-flex; gap: 4px; margin-left: 6px; vertical-align: .12em; }
.bx-dots i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: bx-dot 1.2s ease-in-out infinite; }
.bx-dots i:nth-child(2) { animation-delay: .15s; }
.bx-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes bx-dot { 0%, 70%, 100% { opacity: .25; } 35% { opacity: 1; } }

/* Encart de défense du premier duel (tutoriel) : posé avant la première question, le temps ne part
   qu'au clic sur « Je suis prêt ». Même largeur que la question qui le remplace. */
.bx-cb-intro { display: grid; justify-items: center; gap: 14px; width: 100%; max-width: 720px; margin: 0 auto; padding: 30px 22px 28px; text-align: center; }
.bx-cb-intro__t { max-width: 560px; font-size: 1.05rem; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.bx-cb-intro .bx-btn { margin-top: 4px; }
@media (max-width: 600px) { .bx-cb-intro { padding: 24px 16px 20px; } .bx-cb-intro .bx-btn { width: 100%; } }

/* ── La question (duels et raid) ───────────────────────────────────────────── */
.bx-qhead { display: flex; align-items: center; gap: 12px; width: 100%; max-width: 720px; margin: 0 auto; padding: 10px 16px;
  border-radius: var(--r-l); background: var(--card); border: 1px solid var(--line); box-shadow: var(--hl); }
.bx-qhead > .bx-mini__vis, .bx-qhead > .bx-cb-ava { flex: 0 0 auto; }
.bx-qhead__txt { display: grid; gap: 3px; flex: 1 1 auto; min-width: 0; }
.bx-qhead__t { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-qhead__m { font-size: 13px; color: var(--ink-3); }
.bx-qhead__steps { flex: 0 0 auto; width: 84px; height: 6px; }

.bx-quiz { display: grid; grid-template-columns: 180px minmax(0, 1fr); grid-template-areas: 'card head' 'card ans' 'card foot';
  grid-template-rows: auto auto 1fr; column-gap: 28px; row-gap: 16px; width: 100%; max-width: 720px; margin: 0 auto; }
.bx-quiz__card { grid-area: card; display: grid; gap: 12px; align-content: start; }
/* Capacité écrite une seule fois : dans le bloc sous la carte, pas aussi sur sa plaque. */
.bx-quiz__card .bxc__abt, .bx-quiz__card .bxc__ab { display: none; }
.bx-quiz__head { grid-area: head; display: grid; gap: 12px; min-width: 0; }
.bx-quiz__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bx-quiz__left { font: 700 13px/1 var(--mono); font-variant-numeric: tabular-nums; word-spacing: -.32em; color: var(--ink-2); }
.bx-quiz__bar > i { transition: none; }
.bx-quiz__q { padding-top: 4px; }
.bx-quiz__title { font: 700 1.2rem/1.35 var(--font); color: var(--ink); text-wrap: pretty; overflow-wrap: break-word; }
.bx-quiz__quote { margin: 10px 0 0; padding: 2px 0 2px 14px; border-left: 3px solid var(--line-2); font-size: 15px; line-height: 1.6; color: var(--ink-2); overflow-wrap: break-word; }
/* « trouve-t-on », « a-t-il » : jamais coupés à leurs traits d'union en fin de ligne (BM.questionHtml). */
.bx-nobr { white-space: nowrap; }
.bx-quiz__choices { grid-area: ans; display: grid; gap: 8px; }
.bx-quiz__foot { grid-area: foot; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-quiz__hint { color: var(--accent-2); font-weight: 600; }
@media (hover: none) { .bx-quiz__keys { display: none; } }

/* Une réponse : lettre dans un carré de 28 px, texte à gauche */
.bx-ans { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 10px 16px 10px 12px;
  border-radius: var(--r-m); background: var(--card-2); border: 1px solid var(--line-2); color: var(--ink);
  font: 600 15px/1.3 var(--font); text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: border-color .15s, background-color .15s; }
.bx-ans:hover:not(:disabled) { border-color: var(--accent-line); background: rgba(255, 255, 255, .06); }
.bx-ans:disabled { cursor: default; }
.bx-ans__k { display: grid; place-items: center; width: 28px; height: 28px; flex: 0 0 28px; border-radius: var(--r-s);
  background: rgba(255, 255, 255, .06); border: 1px solid var(--line); font: 700 13px/1 var(--mono); color: var(--ink-2); }
.bx-ans__t { min-width: 0; overflow-wrap: break-word; }
.bx-ans.is-picked { border-color: var(--accent); }
.bx-ans.is-picked .bx-ans__k { background: var(--accent); border-color: transparent; color: var(--on-accent); }
.bx-ans.is-good { border-color: var(--ok-line); background: var(--ok-dim); }
.bx-ans.is-good .bx-ans__k { background: var(--ok); border-color: transparent; color: var(--on-accent); }
.bx-ans.is-bad { border-color: var(--bad-line); background: var(--bad-dim); }
.bx-ans.is-bad .bx-ans__k { background: var(--bad); border-color: transparent; color: var(--on-accent); }
.bx-ans[data-removed] { opacity: .35; }
.bx-ans[data-removed] .bx-ans__t { text-decoration: line-through; }

/* Carte mystère : le dos, sa pastille, la rareté dessous (pas l'attaque : elle trahissait la carte) */
.bx-quiz__mys { position: relative; }
.bx-quiz__mys > .bx-pill { position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); background: rgba(7, 7, 9, .82); color: var(--ink); }
.bx-quiz__mysmeta { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; font-size: 13px; color: var(--ink-3); }
.bx-quiz__mysmeta .bx-num { color: var(--ink); }

@media (max-width: 600px) {
  .bx-qhead { padding: 10px 12px; }
  .bx-qhead__steps { width: 64px; }
  .bx-quiz { grid-template-columns: 104px minmax(0, 1fr); grid-template-areas: 'card head' 'ans ans' 'foot foot'; grid-template-rows: auto; column-gap: 14px; row-gap: 14px; }
  .bx-quiz__card .bx-ability, .bx-quiz__mysmeta, .bx-quiz__mys > .bx-pill { display: none; }
  .bx-quiz__head { align-content: start; gap: 10px; }
  .bx-quiz__q { padding-top: 0; }
  .bx-quiz__title { font-size: 1.06rem; }
  /* Description à reconnaître : citation plus serrée (même taille de 15 px, interligne réduit) et écarts
     réduits, pour que la 4e réponse reste dans un écran de 667 px (mesuré sur 427 questions des duels
     du banc : 4 % la dépassaient, 0,5 % après). */
  .bx-quiz__quote { margin-top: 8px; line-height: 1.4; }
  .bx-cb--play { gap: 12px; }
}
/* Pendant une question (duel et raid portent .bx-cb--play), le menu du jeu replié disparaît : la
   4e réponse tient au-dessus du pli d'un écran de 667 px. Le lien de retour reste. */
@media (max-width: 960px) {
  body.bx:has(.bx-cb--play) #bx-mnav { display: none; }
  .bx-cb--play .bx-qhead { padding: 8px 12px; }
}

/* ── Raid du jour ──────────────────────────────────────────────────────────── */
.bx-rd-scene { align-items: center; }
.bx-rd-card { width: 300px; }
.bx-rd-info { display: grid; justify-items: start; gap: 14px; min-width: 0; }
.bx-rd-info > .bx-hp { justify-self: stretch; }
.bx-rd-kick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bx-rd-flavor { max-width: 560px; font-size: 15px; line-height: 1.55; color: var(--ink-2); }
.bx-rd-act { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-top: 4px; }
.bx-rd-act .bx-btn .bx-coin__ic--onyx, .bx-rd-buy .bx-coin__ic--onyx { width: 18px; height: 18px; }
/* Attaque supplémentaire : le prix (gemme + chiffre en mono) dans le bouton, le compte du jour dessous */
.bx-rd-buy { display: inline-flex; flex-direction: column; align-items: center; gap: 6px; }
.bx-rd-price { display: inline-flex; align-items: center; gap: 5px; margin-left: 2px; font-family: var(--mono); font-weight: 700; line-height: 1; word-spacing: -.32em; }
.bx-rd-buy__note { font-size: 13px; line-height: 1.3; color: var(--ink-3); }
.bx-rd-buy__note .bx-num { color: var(--ink-2); }
.bx-rd-note { max-width: 560px; font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.bx-rd-board { margin-top: 40px; align-items: start; }
/* Panneaux du classement et des attaques : les lignes ne débordent pas des coins arrondis. */
.bx-rd-board > .bx-panel { min-width: 0; overflow: hidden; }
.bx-rd-rank[data-rank="1"] { color: var(--medal-or); }
.bx-rd-rank[data-rank="2"] { color: var(--medal-ar); }
.bx-rd-rank[data-rank="3"] { color: var(--medal-br); }
.bx-rd-board .bx-empty { padding: 26px 12px; }
.bx-rd-mini { display: block; width: 100%; min-width: 0; padding: 0; border: 0; background: none; color: inherit; text-align: left; font: inherit; cursor: pointer; }
.bx-rd-mini:hover .bx-mini__name { color: var(--accent-2); }
/* « Tes attaques » : l'effet qui explique les dégâts d'une carte passe à la ligne, en entier. */
.bx-rd-mini .bx-mini__meta { flex-wrap: wrap; white-space: normal; row-gap: 2px; }
.bx-rd-mini .bx-mini__meta > .bx-mini__sub { flex-basis: 100%; overflow: visible; }
.bx-rd-mini .bx-mini__meta > .bx-mini__sub::before { content: none; }
.bx-rd-total .bx-row__meta { white-space: normal; }
@media (max-width: 960px) and (min-width: 761px) { .bx-rd-card { width: 260px; } }
@media (max-width: 760px) {
  .bx-rd-card { width: min(300px, 100%); }
  .bx-rd-info { justify-items: center; }
  .bx-rd-info .bx-facts, .bx-rd-act, .bx-rd-kick { justify-content: center; }
  .bx-rd-board { margin-top: 28px; }
}
/* Téléphone : carte du boss plus petite, puis nom, barre de vie et bouton d'attaque avant les chiffres
   et la description, pour que « Attaquer » tienne dans le premier écran. */
@media (max-width: 600px) {
  .bx-rd-card { width: min(200px, 56vw); }
  .bx-rd-info > .bx-hp { order: 1; }
  .bx-rd-info > .bx-rd-act { order: 2; }
  .bx-rd-info > .bx-facts { order: 3; }
  .bx-rd-info > .bx-rd-flavor { order: 4; }
  .bx-rd-info > .bx-rd-note { order: 5; }
}

/* Fin d'attaque : total, place du jour, part de la vie du boss, heure des récompenses, cartes, boutons */
.bx-rd-end { display: grid; justify-items: center; gap: 10px; width: 100%; max-width: 760px; margin: 0 auto; padding: 32px 22px 28px; text-align: center; }
.bx-rd-end__big { font-variant-numeric: tabular-nums; }
.bx-rd-end__sub { font-size: 15px; color: var(--ink-2); }
.bx-rd-end__rank { margin-top: 6px; font-size: 1.06rem; font-weight: 700; line-height: 1.35; color: var(--ink); text-wrap: balance; }
.bx-rd-end__rank .bx-num { color: var(--accent-2); }
.bx-rd-end__part { font-size: 15px; line-height: 1.55; color: var(--ink-2); }
.bx-rd-end__part .bx-num { color: var(--ink); }
.bx-rd-end__when { font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-rd-per { display: grid; grid-template-columns: repeat(3, minmax(0, 156px)); justify-content: center; gap: 14px; width: 100%; margin-top: 14px; }
.bx-rd-per__it { display: grid; justify-items: center; gap: 8px; min-width: 0; }
.bx-rd-per__dmg { font-size: 15px; color: var(--ink); word-spacing: -.32em; }
.bx-rd-per__fx { display: block; font-size: 13px; line-height: 1.4; color: var(--accent-2); }
.bx-rd-syn { justify-content: center; }
.bx-rd-end__act { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: 10px 12px; margin-top: 10px; }
.bx-rd-end__extra:empty { display: none; }
@media (max-width: 600px) {
  .bx-rd-end { padding: 24px 14px 20px; }
  .bx-rd-per { gap: 8px; }
  .bx-rd-end__act { flex-direction: column; align-items: stretch; width: 100%; }
  .bx-rd-end__act .bx-btn, .bx-rd-end__act .bx-rd-buy { width: 100%; }
}

/* ── Mouvement réduit (réglage système ET réglage du jeu) ──────────────────── */
@media (prefers-reduced-motion: reduce) {
  .bx-dots i { animation: none; opacity: .7; }
  .bx-mode:hover { transform: none; }
}
body.reduce-motion .bx-dots i { animation: none; opacity: .7; }
body.reduce-motion .bx-mode:hover { transform: none; }


/* ===== css/pages/communaute.css ===== */
/* BloxMasters - pages Guildes, Classements et Succès (cahier docs/BLOXMASTERS_DESIGN.md, §7.9 à 7.11).
   Les composants communs (bx-panel, bx-row, bx-pill, bx-fact, bx-tabs...) sont dans components.css :
   cette feuille n'ajoute que ce qui est propre à ces trois pages.
   Préfixes : bx-emblem (emblème de guilde), bx-medal (pastille de médaille), bx-gd-* (guildes),
   bx-lb-* (classements), bx-ach-* et bx-achset* (succès, collections thématiques). */

/* ── Commun aux trois pages ────────────────────────────────────────────────── */

/* Pastille de médaille : or, argent, bronze (jetons --medal-*) */
.bx-medal { --m: var(--medal-or); text-transform: none; letter-spacing: .02em; color: var(--m); background: color-mix(in srgb, var(--m) 12%, transparent); border-color: color-mix(in srgb, var(--m) 50%, transparent); }
.bx-medal[data-m="2"] { --m: var(--medal-ar); }
.bx-medal[data-m="3"] { --m: var(--medal-br); }
/* Rang d'une ligne de liste : le chiffre prend la couleur de la médaille */
.bx-row__rank[data-m="1"], .bx-row__title[data-m="1"] { color: var(--medal-or); }
.bx-row__rank[data-m="2"], .bx-row__title[data-m="2"] { color: var(--medal-ar); }
.bx-row__rank[data-m="3"], .bx-row__title[data-m="3"] { color: var(--medal-br); }

/* Unité après un chiffre de ligne (« 267 points ») */
.bx-lb-row .bx-row__num small { margin-left: 6px; font: 500 13px/1 var(--font); color: var(--ink-3); word-spacing: normal; }

/* Liste en panneau : les fonds de ligne suivent l'arrondi du panneau ; la ligne du joueur reste
   épinglée en bas de l'écran tant qu'elle est plus bas que la vue (overflow: clip garde le sticky).
   Panneaux Membres et Demandes de la guilde : la ligne « moi » en dernière place ne dépasse plus
   de l'arrondi par ses coins carrés. */
.bx-lb-list, .bx-ach-donelist, .bx-achsets, .bx-ach-locked, section.bx-panel[data-pane="members"] { overflow: clip; }
.bx-lb-list .bx-row.is-me { position: sticky; bottom: 0; z-index: 2; background: linear-gradient(var(--accent-dim), var(--accent-dim)), #111019; box-shadow: inset 0 1px 0 var(--accent-line); }
.bx-lb-row.is-gap, .bx-gd-week .bx-row.is-gap { border-top: 1px dashed var(--line-2); }

/* ── Emblème de guilde (§7.9) ──────────────────────────────────────────────── */

.bx-emblem { --em: 64px; position: relative; display: inline-grid; place-items: center; flex: 0 0 var(--em); width: var(--em); height: var(--em); border-radius: 50%; overflow: hidden; }
.bx-emblem--sm { --em: 32px; }
.bx-emblem--pod { --em: 72px; }
.bx-emblem--lg { --em: 112px; }
/* Carte choisie : la vignette de la carte (BM.miniVisHtml) agrandie en médaillon, anneau de sa rareté */
.bx-emblem.bx-mini__vis[data-r] { width: var(--em); height: var(--em); flex: 0 0 var(--em); border-radius: 50%; box-shadow: 0 0 0 2px var(--rc); }
.bx-emblem.bx-mini__vis[data-r] img { inset: 0; width: 100%; height: 100%; border-radius: 50%; }
.bx-emblem.bx-mini__vis.is-contain[data-r] img { padding: 16%; }
.bx-emblem .bx-mini__glyph { font-size: max(13px, calc(var(--em) * .32)); }
.bx-emblem .bx-mini__sw { width: 46%; height: 46%; border-radius: 24%; }
/* Sans carte : le sigle de la guilde */
.bx-emblem.is-tag { background: var(--card-2); box-shadow: 0 0 0 2px var(--line-2); }
.bx-emblem.is-tag b { font: 900 max(11px, calc(var(--em) * .3))/1 var(--display); letter-spacing: -.02em; color: var(--ink); }
.bx-emblem.is-tag[data-len="3"] b { font-size: max(11px, calc(var(--em) * .24)); }
.bx-emblem.is-tag[data-len="4"] b { font-size: max(11px, calc(var(--em) * .19)); letter-spacing: -.04em; }
/* En 32 px (lignes de liste), un anneau plus fin */
.bx-emblem--sm.bx-mini__vis[data-r] { box-shadow: 0 0 0 1.5px var(--rc); }
.bx-emblem--sm.is-tag { box-shadow: 0 0 0 1.5px var(--line-2); }
.bx-emblem--sm.is-tag b { font-size: 13px; font-weight: 800; }   /* une seule lettre : le sigle entier est écrit à côté */

/* ── Guildes : liste (§7.9.1) ──────────────────────────────────────────────── */

.bx-gd-price { display: inline-flex; align-items: center; gap: 5px; margin-left: 2px; padding-left: 11px; border-left: 1px solid rgba(11, 11, 16, .24); }
.bx-btn:not(.bx-btn--primary) .bx-gd-price { border-left-color: var(--line-2); }

.bx-gd-invites { margin-bottom: 22px; }
.bx-gd-invites .bx-panel__head .bx-badge { margin-left: 0; }
.bx-gd-rowact { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; flex: 0 0 auto; }
.bx-gd-role { height: 22px; padding: 0 8px; margin-left: 8px; flex: 0 0 auto; vertical-align: 1px; }

.bx-gd-tools { margin: 0 0 18px; }
.bx-gd-tools .bx-search { display: block; max-width: 460px; }

.bx-gd-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.bx-gd-grid__empty { grid-column: 1 / -1; }
.bx-gd-more { grid-column: 1 / -1; margin-top: 4px; }   /* « Seules les 40 premières guildes sont affichées... » */
/* Le pied reste en bas quand une fiche voisine plus haute étire la rangée : les filets s'alignent. */
.bx-gd-card { display: grid; grid-template-columns: 64px minmax(0, 1fr); grid-template-rows: 1fr auto; gap: 14px 16px; align-items: start; padding: 18px 18px 14px; transition: border-color .15s; }
.bx-gd-card:hover { border-color: var(--line-2); }
.bx-gd-card.is-mine { border-color: var(--accent-line); }
.bx-gd-card > .bx-gd-card__main { position: static; min-width: 0; }   /* le lien couvre toute la fiche */
/* Nom court, sans pastille : le texte se centre sur la hauteur du médaillon au lieu de rester collé en haut */
.bx-gd-card__main { display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; min-height: 64px; }
.bx-gd-card__name { margin: 3px 0 0; overflow: hidden; overflow-wrap: anywhere; text-wrap: balance; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.bx-gd-card__name a { color: var(--ink); text-decoration: none; }
.bx-gd-card__name a::after { content: ''; position: absolute; inset: 0; border-radius: 20px; }
.bx-gd-card__name a:focus-visible { outline: none; }
.bx-gd-card:has(.bx-gd-card__name a:focus-visible) { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.bx-gd-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.bx-gd-card__meta { margin-top: 8px; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-gd-card__foot { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 40px; padding-top: 12px; border-top: 1px solid var(--line); pointer-events: none; }
.bx-gd-card__foot > .bx-btn { pointer-events: auto; z-index: 1; }

/* ── Guildes : page d'une guilde (§7.9.2 à 7.9.4) ──────────────────────────── */


.bx-gd-scene { grid-template-columns: auto minmax(0, 1fr); }
.bx-gd-scene.has-act { grid-template-columns: auto minmax(0, 1fr) auto; }
.bx-gd-scene__txt { min-width: 0; }
.bx-gd-scene.has-more .bx-gd-scene__txt { padding-right: 40px; }
.bx-gd-scene__kick { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }
.bx-gd-scene .bx-h1 { overflow-wrap: anywhere; }
.bx-gd-scene__desc { max-width: 620px; margin-top: 12px; font-size: 15px; line-height: 1.55; color: var(--ink-2); white-space: pre-line; overflow-wrap: anywhere; }
.bx-gd-scene .bx-facts { margin-top: 16px; }
.bx-gd-scene__act { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.bx-gd-scene__more { position: absolute; top: 16px; right: 16px; z-index: 2; }
@media (max-width: 760px) {
  .bx-gd-scene, .bx-gd-scene.has-act { grid-template-columns: minmax(0, 1fr); }
  .bx-gd-scene.has-more .bx-gd-scene__txt { padding-right: 0; }
  .bx-gd-scene.has-more .bx-emblem { margin-top: 8px; }
  .bx-gd-scene__kick, .bx-gd-scene .bx-facts { justify-content: center; }
  .bx-gd-scene__desc { margin-left: auto; margin-right: auto; }
  .bx-gd-scene__act { align-items: center; }
  .bx-gd-scene__more { top: 10px; right: 10px; }
}

/* Sections : onglets sur téléphone, deux colonnes sur PC */
.bx-gd-tabs { display: none; }
.bx-gd-tabs .bx-badge { margin-left: 7px; }
.bx-gd-body { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 14px; align-items: start; margin-top: 22px; }
.bx-gd-col { display: grid; gap: 14px; min-width: 0; }
@media (max-width: 900px) { .bx-gd-body { grid-template-columns: minmax(0, 1fr); } }   /* tablette : les sections l'une sous l'autre */
.bx-gd-body .bx-panel__head .bx-small, .bx-lb-box .bx-panel__head .bx-small { white-space: nowrap; }
@media (max-width: 760px) {
  .bx-gd-tabs { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); width: 100%; margin-top: 14px; border-radius: 16px; }
  .bx-gd-tabs > * { justify-content: center; }
  .bx-gd-body { grid-template-columns: minmax(0, 1fr); margin-top: 12px; }
  .bx-gd-col { display: contents; }   /* les sections deviennent les cases de la grille : pas d'écart pour une colonne vide */
  .bx-gd-body[data-tab="chat"] [data-pane]:not([data-pane="chat"]),
  .bx-gd-body[data-tab="members"] [data-pane]:not([data-pane="members"]),
  .bx-gd-body[data-tab="week"] [data-pane]:not([data-pane="week"]) { display: none; }
}

/* Discussion : bulles, messages système en pastille, saisie qui grandit jusqu'à 4 lignes */
.bx-gd-chat { display: flex; flex-direction: column; }
.bx-gd-chat__log { display: flex; flex-direction: column; height: 480px; padding: 12px 16px 14px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
.bx-gd-chat__log > :first-child { margin-top: auto; }   /* peu de messages : ils se posent en bas, près de la saisie */
.bx-gd-chat__log > .bx-empty { margin: auto 0; }
/* Sections l'une sous l'autre (tablette, téléphone) : le fil suit le nombre de messages, jusqu'à 60 %
   de l'écran, au lieu d'une hauteur fixe qui laisserait un grand panneau vide au-dessus de trois messages.
   Sur PC, la hauteur fixe reste : la discussion fait face à la colonne des membres. */
@media (max-width: 900px) {
  .bx-gd-chat__log { height: auto; min-height: 180px; max-height: min(60vh, 480px); }
}
@media (max-width: 760px) {
  .bx-gd-chat__log { padding: 10px 12px 12px; }
  .bx-gd-chat > .bx-panel__head { display: none; }   /* l'onglet « Discussion » le dit déjà */
}
.bx-gd-sysrow { display: flex; justify-content: center; margin: 12px 0 2px; }
.bx-pill.bx-gd-sys { height: auto; min-height: 26px; max-width: 92%; padding: 5px 12px; justify-content: center; white-space: normal; text-align: center;
  text-transform: none; letter-spacing: 0; font: 500 13px/1.4 var(--font); color: var(--ink-3); border-color: var(--line); background: rgba(255, 255, 255, .03); }
.bx-gd-msg { display: flex; align-items: flex-start; gap: 8px; max-width: min(86%, 560px); margin-top: 12px; }
.bx-gd-msg.is-cont { margin-top: 3px; padding-left: 36px; }
.bx-gd-msg__ava { width: 28px; height: 28px; flex: 0 0 28px; margin-top: 2px; border-radius: 50%; object-fit: cover; background: var(--card-2); }
.bx-gd-msg__col { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.bx-gd-msg__who { display: flex; align-items: baseline; gap: 8px; padding: 0 2px; font: 600 13px/1.2 var(--font); color: var(--ink-3); }
.bx-gd-msg__who b { font-weight: 600; color: var(--ink-2); }
.bx-gd-msg__who time { font: 500 11px/1 var(--mono); color: var(--ink-3); }
.bx-gd-msg__body { padding: 9px 12px; border-radius: 4px 14px 14px 14px; background: var(--card-2); color: var(--ink); font-size: 15px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.bx-gd-msg.is-mine { align-self: flex-end; }
.bx-gd-msg.is-mine.is-cont { padding-left: 0; }
.bx-gd-msg.is-mine .bx-gd-msg__col { align-items: flex-end; }
.bx-gd-msg.is-mine .bx-gd-msg__body { border-radius: 14px 4px 14px 14px; background: var(--accent-dim); box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .16); }
.bx-gd-chat__form { display: flex; align-items: flex-end; gap: 8px; padding: 12px; border-top: 1px solid var(--line); }
.bx-gd-chat__form .bx-textarea { height: 44px; min-height: 44px; max-height: 108px; padding: 11px 14px; line-height: 1.4; resize: none; overflow-y: auto; }
.bx-gd-chat__form .bx-btn--icon { width: 44px; min-height: 44px; flex: 0 0 44px; }

/* Membres */
.bx-gd-count { margin-left: -4px; font-size: 13px; color: var(--ink-3); }
.bx-gd-colhead { display: flex; justify-content: space-between; gap: 12px; padding: 14px 16px 4px; }
.bx-gd-member .bx-row__num { min-width: 36px; text-align: right; }
/* Avatar et nom forment un seul lien vers le profil (cible pleine hauteur sur téléphone) */
.bx-gd-member__link, .bx-gd-rowlink { display: flex; align-items: center; gap: 12px; flex: 1 1 auto; min-width: 0; min-height: 40px; color: inherit; text-decoration: none; }
.bx-gd-rowlink { display: block; align-content: center; }
.bx-gd-member__link:hover .bx-gd-member__n, .bx-gd-rowlink:hover .bx-row__title { color: var(--accent-2); }
.bx-gd-member__name { display: flex; align-items: center; min-width: 0; }
.bx-gd-member__n { min-width: 0; overflow: hidden; text-overflow: ellipsis; transition: color .15s; }
.bx-gd-rowlink .bx-row__title { display: flex; align-items: center; transition: color .15s; }
.bx-gd-mbtn { margin: -4px -8px -4px -2px; border-color: transparent; background: none; }
/* Place du bouton « ... » sur les lignes qui n'en ont pas (40 px moins ses 10 px de marges négatives),
   et même retrait sous l'intitulé : 16 px de marge + 30 px de case + 12 px d'écart. */
.bx-gd-mslot { flex: 0 0 30px; }
.bx-gd-colhead.has-menu { padding-right: 58px; }
.bx-gd-req .bx-row__main { min-width: 120px; }
@media (max-width: 600px) { .bx-gd-req, .bx-gd-invites .bx-row { flex-wrap: wrap; } }

/* Classement de la semaine (dans la page de la guilde) */
.bx-gd-week { overflow: clip; }
.bx-gd-weeknote { padding: 12px 16px 0; }
.bx-gd-weekempty .bx-empty { padding: 26px 16px 10px; }
.bx-gd-weekfoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; padding: 8px 16px 10px; border-top: 1px solid var(--line); }
.bx-gd-weekfoot .bx-how { padding-left: 0; }
.bx-gd-weekfoot .bx-link { display: inline-flex; align-items: center; min-height: 40px; font-size: 13px; }

/* Réglages du chef, repliés */
.bx-gd-settings > summary { display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 0 20px; list-style: none; cursor: pointer; font: 700 1.06rem/1.25 var(--font); color: var(--ink); -webkit-tap-highlight-color: transparent; }
.bx-gd-settings > summary::-webkit-details-marker { display: none; }
.bx-gd-settings > summary svg { width: 18px; height: 18px; margin-left: auto; color: var(--ink-3); transition: transform .2s; }
.bx-gd-settings[open] > summary { border-bottom: 1px solid var(--line); }
.bx-gd-settings[open] > summary svg { transform: rotate(180deg); }
.bx-gd-settings__body { gap: 18px; padding: 18px 20px 20px; }
.bx-gd-embrow { display: flex; align-items: center; gap: 12px; }
.bx-gd-embrow .bx-small { flex: 1; min-width: 0; }
.bx-gd-danger { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px; padding-top: 16px; border-top: 1px solid var(--line); }
.bx-gd-danger b { display: block; font-size: 15px; }
.bx-gd-danger .bx-small { margin-top: 2px; }

/* Fenêtre de création */
.bx-gd-form { gap: 16px; }
.bx-gd-sigle { text-transform: uppercase; letter-spacing: .08em; }
.bx-gd-sigle::placeholder { text-transform: none; letter-spacing: 0; }

/* ── Classements (§7.10) ───────────────────────────────────────────────────── */

/* La barre d'onglets suit le titre et ne bouge plus d'un onglet à l'autre ; dessous, les faits de l'onglet
   à gauche, « Comment ça marche » et son bouton à droite (au téléphone : les uns sous les autres). */
.bx-lb-tabs { margin-bottom: 0; }
.bx-lb-intro { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin: 16px 0 22px; }
.bx-lb-intro__sub { min-width: 0; }
.bx-lb-intro__sub:empty { display: none; }
.bx-lb-intro > .bx-ph__act { margin-left: auto; }
@media (max-width: 600px) { .bx-lb-intro > .bx-ph__act { margin-left: 0; } }
/* Cinq onglets sur téléphone : trois puis deux, chacun assez large pour « Collection » */
@media (max-width: 600px) {
  .bx-lb-tabs.bx-tabs--grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .bx-lb-tabs.bx-tabs--grid > * { grid-column: span 2; }
  .bx-lb-tabs.bx-tabs--grid > :nth-child(n+4) { grid-column: span 3; }
}
.bx-lb-sub { max-width: 620px; }

/* Podium : 2, 1, 3 ; le premier surélevé de 24 px ; pas de socle ni de halo */
.bx-lb-podium { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; gap: 14px; max-width: 780px; margin: 6px auto 28px; padding: 0; list-style: none; }
.bx-lb-pod { --m: var(--medal-or); min-width: 0; grid-row: 1; }
.bx-lb-pod[data-m="1"] { grid-column: 2; margin-bottom: 24px; }
.bx-lb-pod[data-m="2"] { --m: var(--medal-ar); grid-column: 1; }
.bx-lb-pod[data-m="3"] { --m: var(--medal-br); grid-column: 3; }
.bx-lb-pod__in { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 24px 14px 20px; color: inherit; text-align: center; text-decoration: none; transition: border-color .15s; }
.bx-lb-pod__in:hover { border-color: var(--line-2); }
.bx-lb-pod.is-me .bx-lb-pod__in { border-color: var(--accent-line); }
.bx-lb-pod__ava { width: 72px; height: 72px; margin-bottom: 4px; border-radius: 50%; object-fit: cover; background: var(--card-2); box-shadow: 0 0 0 3px var(--m); }
.bx-lb-pod .bx-emblem, .bx-lb-pod .bx-emblem.bx-mini__vis[data-r] { margin-bottom: 4px; box-shadow: 0 0 0 3px var(--m); }
.bx-lb-pod__name { max-width: 100%; font: 700 15px/1.25 var(--font); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-lb-pod .bx-lb-title { max-width: 100%; }
.bx-lb-pod__meta { max-width: 100%; margin-top: -4px; font-size: 13px; line-height: 1.35; color: var(--ink-3); }
.bx-lb-pod__val { display: flex; align-items: baseline; justify-content: center; gap: 6px; margin-top: 2px; }
.bx-lb-pod__val b { font: 700 1.4rem/1 var(--mono); color: #fff; }
.bx-lb-pod__val small { font: 500 13px/1 var(--font); color: var(--ink-3); }
@media (max-width: 600px) {
  .bx-lb-podium { gap: 8px; margin-bottom: 22px; }
  .bx-lb-pod[data-m="1"] { margin-bottom: 16px; }
  .bx-lb-pod__in { gap: 8px; padding: 16px 6px 14px; border-radius: 16px; }
  .bx-lb-pod__ava { width: 56px; height: 56px; }
  .bx-lb-pod .bx-emblem { --em: 56px; }
  .bx-lb-pod__name { font-size: 13px; }
  .bx-lb-pod .bx-lb-title, .bx-lb-pod__meta { display: none; }
  .bx-lb-pod__val { flex-direction: column; align-items: center; gap: 4px; }
  .bx-lb-pod__val b { font-size: 1.06rem; }
}

/* Lignes : rang, avatar, nom, titre et sigle de guilde, valeur */
.bx-lb-list .bx-row__rank { width: 36px; flex-basis: 36px; }
.bx-lb-meta { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
.bx-lb-meta .bx-pill { flex: 0 0 auto; height: 20px; padding: 0 7px; }
.bx-lb-meta__txt { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.bx-lb-tag { color: var(--ink-2); }
.bx-lb-title { --tc: var(--r1); flex: 0 1 auto; min-width: 0; max-width: 200px; text-transform: none; letter-spacing: 0; font-weight: 700;
  color: var(--tc); background: color-mix(in srgb, var(--tc) 9%, transparent); border-color: color-mix(in srgb, var(--tc) 45%, transparent); }
.bx-lb-title > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.bx-lb-meta .bx-lb-title { flex: 0 1 auto; }
.bx-lb-title[data-r="2"] { --tc: var(--r2); }
.bx-lb-title[data-r="3"] { --tc: var(--r3); }
.bx-lb-title[data-r="4"] { --tc: var(--r4); }
.bx-lb-title[data-r="5"] { --tc: var(--r5); }
.bx-lb-title[data-r="6"] { --tc: var(--r6); }
@media (max-width: 600px) {
  .bx-lb-list .bx-row { gap: 10px; padding-left: 12px; padding-right: 14px; }
  .bx-lb-list .bx-row__rank { width: 28px; flex-basis: 28px; }
  .bx-lb-meta .bx-lb-title { max-width: 120px; }
  .bx-lb-row .bx-row__num small, .bx-lb-more { display: none; }
}

.bx-lb-panels { margin-top: 0; }
.bx-lb-panels.bx-stack { gap: 14px; }
.bx-lb-weekempty { margin-bottom: 22px; border: 1px dashed var(--line-2); border-radius: 18px; }
.bx-lb-panelempty .bx-empty { padding: 30px 16px; }

/* Concours de la semaine */
.bx-lb-contest { padding: 24px 26px; margin-bottom: 14px; }
.bx-lb-contest h2 { margin-top: 10px; }
.bx-lb-contest__desc { max-width: 620px; margin-top: 8px; font-size: 15px; color: var(--ink-2); }
.bx-lb-contest .bx-small { margin-top: 10px; }
.bx-lb-split { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.bx-lb-rw { min-height: 48px; }
.bx-lb-rw .bx-row__title { font-size: 15px; line-height: 1.3; white-space: normal; text-wrap: balance; }   /* « 8e à 10e places » passe à la ligne, jamais coupé */
.bx-lb-rw__pills { display: flex; gap: 6px; flex: 0 0 auto; }
.bx-lb-beli .bx-coin__ic--beli, .bx-ach-beli .bx-coin__ic--beli { width: 6px; height: 12px; }
.bx-lb-beli .bx-num, .bx-ach-beli .bx-num { letter-spacing: 0; }
.bx-lb-prev { display: grid; gap: 6px; padding: 16px 16px 14px; border-top: 1px solid var(--line); }
.bx-lb-prev__t { font-size: 15px; }
.bx-lb-prev__list { display: grid; gap: 2px; margin: 4px 0 0; padding: 0; list-style: none; }
.bx-lb-prev__list a { display: flex; align-items: center; gap: 10px; min-height: 40px; font-size: 15px; color: inherit; text-decoration: none; }
.bx-lb-prev__list a:hover .bx-lb-prev__n { color: var(--accent-2); }
.bx-lb-prev__n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: color .15s; }
.bx-lb-prev__list .bx-row__rank { width: 20px; flex-basis: 20px; text-align: left; }
.bx-lb-prev__v { margin-left: auto; font-size: 13px; color: var(--ink-3); }
.bx-lb-prev__v .bx-num { color: var(--ink-2); }
/* Tablette : les récompenses passent sous le classement ; côte à côte, leur colonne ferait moins de
   330 px, la largeur d'un libellé de places et de ses deux pastilles. */
@media (max-width: 960px) { .bx-lb-split { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 760px) { .bx-lb-contest { padding: 20px 18px; } }

/* Grands tirages */
.bx-lb-pull { min-width: 0; margin: 0; }
.bx-lb-pull figcaption { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; font-size: 13px; line-height: 1.35; }
/* Nom du joueur : 40 px de haut au doigt (ligne de 17,5 px + 2 x 12 px), sans décaler la légende. */
.bx-lb-pull figcaption .bx-plink { align-self: flex-start; min-width: 44px; max-width: 100%; padding: 12px 0; margin: -12px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-lb-pull figcaption > span { color: var(--ink-3); }

/* Chargement : podium et lignes */
.bx-lb-skel { display: grid; gap: 22px; }
.bx-lb-skel__pod { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; gap: 14px; width: 100%; max-width: 780px; margin: 6px auto 0; }
.bx-lb-skel__pod .bx-skel { height: 196px; border-radius: 20px; }
.bx-lb-skel__pod .bx-skel:nth-child(2) { height: 220px; }

/* Barème du score dans « Comment est calculé le score » */
.bx-lb-scale { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 28px; max-width: 400px; margin: 2px 0; }
.bx-lb-scale > span { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bx-lb-scale .bx-num { font-size: 15px; color: var(--ink); }

/* ── Succès (§7.11) ────────────────────────────────────────────────────────── */

.bx-ach-n { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 7px; margin-left: 2px; border-radius: 999px; background: rgba(11, 11, 16, .16); font: 700 13px/1 var(--mono); }
.bx-ach-total { margin: -6px 0 22px; }
.bx-ach-tabs .bx-badge { margin-left: 7px; }
.bx-ach-body > section:first-child > .bx-sec { margin-top: 28px; }
.bx-sec .bx-ach-n2 { font-size: 13px; color: var(--ink-3); }

.bx-ach-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.bx-ach { display: flex; flex-direction: column; gap: 6px; padding: 20px; }
.bx-ach__t { margin-top: 4px; }
.bx-ach__d { font-size: 13px; line-height: 1.45; color: var(--ink-3); }
/* Barre et récompenses tombent au pied de la carte : sur une même ligne de la grille, elles s'alignent
   quelle que soit la longueur de la description. Le compteur a une largeur fixe, assez pour le plus long
   (« 10 000 / 10 000 ») : toutes les barres ont la même longueur, d'une carte à l'autre. */
.bx-ach__prog { display: flex; align-items: center; gap: 12px; margin-top: auto; padding-top: 8px; }
.bx-ach__prog .bx-bar { flex: 1; }
.bx-ach__prog .bx-num { flex: 0 0 auto; min-width: 8em; font-size: 13px; color: var(--ink-2); text-align: right; white-space: nowrap; }
.bx-ach__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-top: auto; padding-top: 14px; }
.bx-ach__prog + .bx-ach__foot { margin-top: 0; }   /* la barre a déjà pris l'espace libre */
.bx-ach__rw { display: flex; flex-wrap: wrap; gap: 6px; }
.bx-ach__foot > .bx-btn { margin-left: auto; }
.bx-ach-first { margin-top: 28px; }
.bx-achsets { margin-top: 22px; }
@media (max-width: 600px) {
  .bx-ach { padding: 16px 16px 14px; }
  .bx-ach__foot { padding-top: 10px; }
}

/* Terminés : liste compacte, deux colonnes sur grand écran */
.bx-ach-done { min-height: 52px; padding: 8px 16px; }
.bx-ach-check { display: grid; place-items: center; width: 26px; height: 26px; flex: 0 0 26px; border-radius: 50%; background: var(--ok-dim); color: var(--ok); }
.bx-ach-check svg { width: 14px; height: 14px; }
.bx-ach-done .bx-row__time { align-self: center; padding-top: 0; }
@media (min-width: 900px) {
  .bx-ach-donelist { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bx-ach-donelist > .bx-row:nth-child(odd) { border-right: 1px solid var(--line); }
  .bx-ach-donelist > .bx-row:nth-child(odd):nth-last-child(2) { border-bottom: 0; }
}

/* Verrouillés : repliés */
.bx-ach-locked { margin-top: 40px; }
.bx-ach-locked > summary { display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 0 20px; list-style: none; cursor: pointer; font: 700 15px/1.3 var(--font); color: var(--ink-2); -webkit-tap-highlight-color: transparent; }
.bx-ach-locked > summary:hover { color: var(--ink); }
.bx-ach-locked > summary::-webkit-details-marker { display: none; }
.bx-ach-locked > summary svg { width: 18px; height: 18px; margin-left: auto; color: var(--ink-3); transition: transform .2s; }
.bx-ach-locked[open] > summary { border-bottom: 1px solid var(--line); }
.bx-ach-locked[open] > summary svg { transform: rotate(180deg); }
.bx-ach-lockrow .bx-row__title { color: var(--ink-2); }
.bx-ach-lockrow .bx-row__num { min-width: 64px; margin-left: 0; text-align: right; color: var(--ink-3); font-size: 13px; }
.bx-ach-lockrow .bx-ach__rw { flex: 0 0 auto; flex-wrap: nowrap; }
@media (max-width: 600px) {
  .bx-ach-lockrow { flex-wrap: wrap; row-gap: 8px; }
  .bx-ach-lockrow .bx-row__main { flex: 1 1 100%; }
  .bx-ach-lockrow .bx-row__meta { white-space: normal; }
  .bx-ach-lockrow .bx-row__num { margin-left: auto; }
}

/* Collections thématiques : une ligne par collection */
.bx-achset { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 14px 32px; align-items: center; min-height: 0; padding: 18px 20px; }
.bx-achset.is-claim { background: linear-gradient(90deg, rgba(var(--accent-rgb), .07), transparent 60%); }
.bx-achset__main { min-width: 0; }
.bx-achset__name { font: 700 15px/1.3 var(--font); }
.bx-achset__desc { margin-top: 3px; font-size: 13px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-achset__cards { margin-top: 12px; padding-bottom: 0; }
.bx-achset__card { display: block; flex: 0 0 auto; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 10px; background: none; cursor: pointer; transition: transform .15s var(--ease); -webkit-tap-highlight-color: transparent; }
.bx-achset__card:hover { transform: translateY(-2px); }
.bx-achset__card:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.bx-achset__more { flex: 0 0 auto; align-self: center; padding: 0 4px 0 6px; font: 700 13px/1 var(--mono); color: var(--ink-3); }
.bx-achset__side { display: grid; gap: 12px; min-width: 0; }
.bx-achset__count { display: flex; align-items: center; gap: 12px; }
.bx-achset__count .bx-bar { flex: 1; }
.bx-achset__count .bx-num { min-width: 64px; font-size: 14px; text-align: right; white-space: nowrap; }
.bx-achset.is-full .bx-achset__count .bx-num { color: var(--ok); }
.bx-achset__end { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; min-height: 40px; }
@media (max-width: 760px) {
  .bx-achset { grid-template-columns: minmax(0, 1fr); padding: 16px; }
  .bx-achset__desc { white-space: normal; }
}

/* ── Mouvement réduit ──────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) { .bx-achset__card:hover { transform: none; } }
body.reduce-motion .bx-achset__card:hover { transform: none; }


/* ===== css/pages/compte.css ===== */
/* BloxMasters - pages du compte : Boutique (cahier 7.12), Profil (7.13), Messages et Amis (7.14),
   Réglages (7.15), Administration (7.16). Composants communs : components.css ; cette feuille ne
   contient que la mise en page propre à ces vues (préfixes bx-shop, bx-offer, bx-wallet, bx-tier,
   bx-backs, bx-prof, bx-prog, bx-friends, bx-dm, bx-shw, bx-set, bx-adm). */

/* ═════════════════════════════════ BOUTIQUE ═════════════════════════════════ */

.bx-shop__tabs { margin-bottom: 22px; }
.bx-shop__box { min-height: 320px; }
.bx-shop__rules { display: inline-flex; align-items: center; min-height: 40px; }
@media (max-width: 600px) {
  .bx-shop__tabs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; border-radius: 16px; }
  .bx-shop__tabs > a { justify-content: center; padding: 0 8px; border-radius: 12px; }
}

/* Grilles d'offres : 5 colonnes de paquets en Beli sur PC, 3 colonnes d'offres Onyx (en ligne) */
.bx-offers { display: grid; grid-template-columns: repeat(auto-fill, minmax(208px, 1fr)); gap: 14px; }
.bx-offers--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.bx-offers--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1100px) { .bx-offers--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .bx-offers, .bx-offers--wide { grid-template-columns: minmax(0, 1fr); gap: 12px; } }
.bx-offer__skel { height: 372px; border-radius: 22px; }

/* Offre : modèle .pack de la page Onyx (style.css:197-200) */
.bx-offer { container: bx-offer / inline-size; position: relative; overflow: hidden; border-radius: 22px;
  background: linear-gradient(165deg, #14121e, #0c0c12); border: 1px solid var(--line); box-shadow: var(--hl);
  transition: transform .4s var(--ease), border-color .4s; }
.bx-offer::before { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(64% 46% at 82% -6%, rgba(var(--accent-rgb), .14), transparent 70%); }
.bx-offer:hover { transform: translateY(-6px); border-color: rgba(var(--accent-rgb), .55); }
.bx-offer__in { --stk: 22px; position: relative; display: flex; flex-direction: column; gap: 18px; height: 100%; padding: 26px 24px 22px; }

/* Visuel : le sachet (120 px) posé sur une ombre de sol, ou une vraie ressource (coffre, gemme) */
.bx-offer__vis { position: relative; isolation: isolate; display: grid; place-items: center; height: 196px; }
.bx-offer__pack { position: relative; width: 120px; }
.bx-offer__pack::after { content: ''; position: absolute; z-index: -1; left: 6%; right: 6%; bottom: -14px; height: 16px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0, 0, 0, .6), transparent); }
.bx-offer__pack.is-stack > .bx-pack:not(:last-child) { position: absolute; inset: 0; }
.bx-offer__pack.is-stack > .bx-pack:nth-child(1) { transform: translateX(calc(var(--stk) * -1)) rotate(-8deg) scale(.92); }
.bx-offer__pack.is-stack > .bx-pack:nth-child(2) { transform: translateX(var(--stk)) rotate(8deg) scale(.92); }
.bx-offer__img { width: 128px; height: 128px; object-fit: contain; }
.bx-offer__img.is-gem { width: 76px; height: 76px; }

.bx-offer__body { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.bx-offer__name { font: 800 1.16rem/1.15 var(--display); letter-spacing: -.01em; color: #fff; text-wrap: balance; }
.bx-offer__desc, .bx-offer__note { font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-offer__note b { color: var(--ink); }
.bx-offer__foot { display: flex; flex-direction: column; align-items: stretch; gap: 14px; margin-top: auto; padding-top: 12px; }
.bx-offer__price { display: inline-flex; align-items: center; gap: 8px; font: 900 1.6rem/1 var(--display); letter-spacing: -.02em; color: #fff; white-space: nowrap; }
.bx-offer__price .bx-coin__ic--beli { width: 11px; height: 22px; }
.bx-offer__price .bx-coin__ic--onyx { width: 24px; height: 24px; }
.bx-offer .bx-btn[disabled] { opacity: .6; }
/* Équivalent en euros sous un prix en Onyx (shop.js, décision D3 de ratox) : à titre indicatif, en petit, sous le
   chiffre (offre, passe, dos de carte). La règle et son taux sont écrits une fois, dans le portefeuille. */
.bx-offer__pricebox { display: grid; justify-items: start; gap: 6px; min-width: 0; }
.bx-eur { font: 500 13px/1.3 var(--font); color: var(--ink-3); white-space: nowrap; }
/* « Acheter 5 d'un coup » sous le bouton principal, sur toute la largeur du pied. */
.bx-offer__more { align-self: center; }
.bx-offer__foot .bx-offer__more { flex-basis: 100%; }

/* Paquets premium : meilleure offre, pastilles (« Meilleur prix », économie), quantité du lot */
.bx-offer.is-best { border-color: var(--accent-line); }
.bx-offer__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px; }
.bx-offer__qty { position: absolute; z-index: 3; right: -10px; top: 14%; min-width: 40px; height: 40px; padding: 0 10px; border-radius: 99px;
  background: var(--accent); color: var(--on-accent); font: 900 1rem/40px var(--display); text-align: center; white-space: nowrap; }
/* « Il te manque N Onyx » : un lien vers la page Onyx, écrit comme un bouton secondaire */
.bx-buy--need > span { white-space: nowrap; }
.bx-buy--need b { font-weight: 800; }

/* Chances d'un paquet premium : une ligne sous l'offre (pourcentages en mono), feuille « Voir les chances » */
.bx-odds { margin: 2px 0 0; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-odds b { color: var(--ink-2); }
.bx-odds__more { align-self: flex-start; display: inline-flex; align-items: center; min-height: 40px; margin: -7px 0 -5px; padding: 0; border: 0;
  background: none; color: var(--accent-2); font: 700 13px/1 var(--font); cursor: pointer; }
.bx-odds__more:hover { text-decoration: underline; text-underline-offset: 3px; }
.bx-oddsheet__sec { margin-top: 18px; }
.bx-oddsheet__sec > .bx-micro { margin-bottom: 10px; }
.bx-oddsheet__list { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.bx-oddsheet__list .bx-row { min-height: 46px; padding: 8px 14px; }
.bx-oddsheet__list .bx-row__main { color: var(--ink-2); line-height: 1.35; }
.bx-oddsheet__list .bx-row__num { padding-left: 12px; color: var(--ink); }
.bx-oddsheet .bx-small { margin-top: 16px; }

/* Offre large (Onyx, téléphone) : visuel à gauche, texte à droite */
@container bx-offer (min-width: 340px) {
  .bx-offer__in { --stk: 12px; flex-direction: row; align-items: stretch; gap: 18px; padding: 22px; }
  .bx-offer__vis { flex: 0 0 112px; height: auto; min-height: 150px; }
  .bx-offer__pack { width: 96px; }
  .bx-offer__pack.is-stack { width: 88px; }
  .bx-offer__img { width: 96px; height: 96px; }
  .bx-offer__img.is-gem { width: 60px; height: 60px; }
  .bx-offer__foot { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px; }
  .bx-offer__foot .bx-btn--block { width: auto; }
  .bx-offer__price { font-size: 1.4rem; }
}
/* Offre large mais étroite (téléphone) : visuel resserré pour garder le prix et le bouton sur une ligne */
@container bx-offer (min-width: 340px) and (max-width: 420px) {
  .bx-offer__in { gap: 14px; padding: 18px 16px; }
  .bx-offer__vis { flex-basis: 90px; min-height: 132px; }
  .bx-offer__pack { width: 84px; }
  .bx-offer__pack.is-stack { width: 76px; }
  .bx-offer__img { width: 84px; height: 84px; }
  .bx-offer__price { font-size: 1.3rem; }
}
@media (max-width: 640px) {
  .bx-offer:hover { transform: none; }
  .bx-offer__in { padding: 18px 16px; }
}

/* Portefeuille Onyx : une ligne (cahier 7.12) */
.bx-wallet__main { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; padding: 18px 22px; }
.bx-wallet__gem { width: 48px; height: 48px; flex: 0 0 48px; object-fit: contain; }
/* Le texte prend la place libre (le bouton ou la pastille partent à droite) et passe à la ligne au lieu de
   pousser la pierre seule sur sa ligne. */
.bx-wallet__txt { display: grid; flex: 1 1 200px; gap: 7px; min-width: 0; }
.bx-wallet__n { font: 900 1.8rem/1 var(--display); letter-spacing: -.02em; color: #fff; white-space: nowrap; }
.bx-wallet__n b { font-weight: 900; }
.bx-wallet__n small { margin-left: 2px; font: 600 1rem/1 var(--font); letter-spacing: 0; color: var(--ink-3); }
.bx-wallet__how { font-size: 13px; line-height: 1.4; color: var(--ink-3); }
.bx-wallet__eur { font-size: 12px; line-height: 1.45; color: var(--ink-3); text-wrap: pretty; }
/* Portefeuille bloqué : une pastille courte ; la phrase qui explique quoi faire est dans .bx-wallet__how */
.bx-wallet__frozen { flex: 0 0 auto; }
.bx-wallet__pending { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding: 14px 22px; border-top: 1px solid var(--line); }
.bx-wallet__pending .bx-btn { margin-left: auto; }
@media (max-width: 600px) {
  .bx-wallet__main { padding: 16px; }
  .bx-wallet__go { width: 100%; }
  .bx-wallet__pending { padding: 14px 16px; }
  .bx-wallet__pending .bx-btn { width: 100%; margin-left: 0; }
}

/* Passe Capitaine : carte de palier (modèle .tier de Prestige, bffr/style.css:337-356) */
.bx-tier { margin-top: 40px; display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; align-items: center; gap: 28px; padding: 32px; border-radius: 24px;
  background: linear-gradient(168deg, rgba(var(--r6-rgb), .14), var(--card) 56%); border: 1.5px solid rgba(var(--r6-rgb), .36); box-shadow: var(--hl); }
.bx-tier__art { width: 96px; height: 96px; object-fit: contain; align-self: start; }
.bx-tier__k { color: var(--r6); }
.bx-tier__name { margin-top: 8px; font: 900 clamp(1.4rem, 1.1rem + 1vw, 1.9rem)/1.05 var(--display); letter-spacing: -.02em; color: #fff; }
.bx-tier__on { margin-top: 12px; }
.bx-tier__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 26px; margin: 18px 0 0; padding: 0; list-style: none; color: var(--ink-2); font-size: 15px; line-height: 1.4; }
.bx-tier__list li { position: relative; padding-left: 26px; }
.bx-tier__list li::before { content: ''; position: absolute; left: 0; top: 2px; width: 16px; height: 16px; background: var(--r6);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat; }
.bx-tier__buy { display: grid; justify-items: end; gap: 8px; min-width: 220px; text-align: right; }
.bx-tier__price { display: inline-flex; align-items: center; gap: 10px; font: 900 2.4rem/1 var(--display); letter-spacing: -.03em; color: #fff; }
.bx-tier__price .bx-coin__ic--onyx { width: 30px; height: 30px; }
.bx-tier__buy .bx-btn { margin-top: 8px; }
.bx-tier__value { margin: 16px 0 0; font-size: 13px; line-height: 1.45; color: var(--ink-2); }
.bx-tier__auto { color: var(--ink-2); }
@media (max-width: 960px) {
  .bx-tier { grid-template-columns: 72px minmax(0, 1fr); gap: 20px 22px; }
  .bx-tier__art { width: 72px; height: 72px; }
  .bx-tier__buy { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: 8px 16px; min-width: 0; padding-top: 18px; border-top: 1px solid rgba(var(--r6-rgb), .2); text-align: left; }
  .bx-tier__buy .bx-btn { margin: 0 0 0 auto; }
}
@media (max-width: 600px) {
  .bx-tier { grid-template-columns: minmax(0, 1fr); padding: 22px 18px; }
  .bx-tier__list { grid-template-columns: minmax(0, 1fr); }
  .bx-tier__buy .bx-btn { width: 100%; margin: 4px 0 0; }
}

/* Dos de carte en vente (cahier 7.12) */
.bx-backs { display: grid; grid-template-columns: repeat(auto-fit, minmax(124px, 1fr)); gap: 24px 14px; }
/* Colonne intérieure bornée à la case : un libellé sans retour à la ligne ne peut plus élargir la case (au téléphone,
   les dos se chevauchaient et la page défilait à l'horizontale avec « Portefeuille bloqué »). */
.bx-backs__item { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; align-content: start; gap: 8px; min-width: 0; text-align: center; }
/* Le dos est un bouton : il s'ouvre en grand avant l'achat */
.bx-backs__vis { display: block; width: min(140px, 100%); margin-bottom: 6px; padding: 0; border: 0; border-radius: 12px; background: none; color: inherit;
  cursor: pointer; transition: transform .2s var(--ease); }
.bx-backs__item:hover .bx-backs__vis { transform: translateY(-4px); }
.bx-backs__item.is-on .bx-backs__vis { outline: 2px solid var(--accent); outline-offset: 4px; }
.bx-backs__name { font-size: 15px; font-weight: 700; color: var(--ink); }
.bx-backs__state { display: flex; align-items: center; justify-content: center; min-height: 26px; }
.bx-backs__price { font-size: 15px; }
.bx-backs__eur { margin-top: -6px; font-size: 12px; }   /* collé au prix qu'il traduit */
.bx-backs__item .bx-buy--need { height: auto; min-height: 36px; padding: 6px 12px; line-height: 1.2; white-space: normal; text-align: center; }
.bx-backs__item .bx-buy--need > span { white-space: normal; }
@media (max-width: 600px) {
  .bx-backs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px 10px; }
  .bx-backs__item .bx-btn { width: 100%; padding: 0 8px; }
  .bx-backs__item .bx-buy--need { min-height: 40px; padding: 6px 8px; }
  .bx-backs__name { font-size: 13px; }
}
@media (hover: none) { .bx-backs__item:hover .bx-backs__vis { transform: none; } }

/* Un dos en grand (fenêtre d'aperçu avant l'achat) */
.bx-backprev { display: grid; grid-template-columns: 180px minmax(0, 1fr); align-items: center; gap: 22px; }
.bx-backprev__vis { width: 180px; }
@media (max-width: 600px) {
  .bx-backprev { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 16px; text-align: center; }
  .bx-backprev__vis { width: 156px; }
}

/* ═════════════════════════════════ PROFIL ══════════════════════════════════ */

.bx-prof { grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; }
.bx-prof__ava { width: 96px; height: 96px; }
.bx-prof__main { display: grid; justify-items: start; gap: 10px; min-width: 0; }
.bx-prof__name { margin: 0; font: 800 2rem/1.05 var(--display); letter-spacing: -.02em; color: #fff; overflow-wrap: anywhere; }
.bx-prof__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; max-width: 100%; }
.bx-prof__guild { display: inline-flex; align-items: center; gap: 8px; min-height: 26px; color: var(--ink-2); font-size: 15px; font-weight: 700; text-decoration: none; }
.bx-prof__guild:hover { color: var(--ink); }
.bx-sec .bx-prof__more { display: inline-flex; align-items: center; min-height: 40px; }
@media (max-width: 960px) { .bx-prof__guild { min-height: 40px; } }
.bx-prof__bio { max-width: 560px; font-size: 15px; line-height: 1.55; color: var(--ink-2); overflow-wrap: anywhere; }
.bx-prof__seen { font-size: 13px; color: var(--ink-3); }
.bx-prof__facts { margin-top: 4px; }
/* Place au classement, à la suite du score : « Score 18 220 · 12e » */
.bx-prof__rank { color: var(--ink-2); }
.bx-prof__rank::before { content: '\00B7'; margin-right: 8px; color: var(--ink-4); }
.bx-prof__act { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
@media (max-width: 760px) {
  .bx-prof { grid-template-columns: minmax(0, 1fr); }
  .bx-prof__main { justify-items: center; }
  .bx-prof__name { font-size: 1.6rem; }
  .bx-prof__tags, .bx-prof__facts, .bx-prof__act { justify-content: center; }
}

/* Titre équipé : pastille à la couleur de rareté de la carte Titre (sans crochets) */
.bx-prof__title { --rc: var(--r1); --rc-rgb: var(--r1-rgb); max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  color: var(--rc); background: rgba(var(--rc-rgb), .08); border-color: rgba(var(--rc-rgb), .5); }
.bx-prof__title[data-r="2"] { --rc: var(--r2); --rc-rgb: var(--r2-rgb); }
.bx-prof__title[data-r="3"] { --rc: var(--r3); --rc-rgb: var(--r3-rgb); }
.bx-prof__title[data-r="4"] { --rc: var(--r4); --rc-rgb: var(--r4-rgb); }
.bx-prof__title[data-r="5"] { --rc: var(--r5); --rc-rgb: var(--r5-rgb); }
.bx-prof__title[data-r="6"] { --rc: var(--r6); --rc-rgb: var(--r6-rgb); }
.bx-prof__cap { color: var(--r6); background: rgba(var(--r6-rgb), .08); border-color: rgba(var(--r6-rgb), .45); }

/* Vitrines : cartes de taille moyenne (200 px et plus) */
.bx-prof__shows { gap: 14px; }
.bx-prof__showhead { display: flex; align-items: baseline; gap: 12px; margin-bottom: 18px; }
/* Le panneau prend la largeur de ses cartes (220 px chacune, cinq par ligne au plus) : une vitrine de deux cartes ne laisse pas un grand vide. */
.bx-prof__show { width: fit-content; max-width: 100%; }
.bx-prof__showgrid { display: grid; grid-template-columns: repeat(var(--n, 5), minmax(0, 220px)); gap: 18px; }
@media (max-width: 600px) { .bx-prof__show { width: auto; } .bx-prof__showgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } }
/* Tablette : la vitrine est centrée sous la scène du profil, plus calée à gauche. Pas sous 601 px : elle y prend
   toute la largeur, et une marge auto l'écraserait (la pile en colonne ne l'étirerait plus, ses cartes tomberaient à 0). */
@media (min-width: 601px) and (max-width: 1023px) { .bx-prof__show { margin-inline: auto; } }
.bx-sec .bx-prof__total { color: var(--ink-2); }

/* Progression par famille : deux colonnes de lignes, sans icône */
.bx-prog { columns: 2; column-gap: 44px; }
.bx-prog__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 7px 12px; margin-bottom: 16px; break-inside: avoid; }
.bx-prog__name { overflow: hidden; color: var(--ink-2); font-size: 15px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.bx-prog__n { color: var(--ink); font-size: 13px; }
.bx-prog__row .bx-bar { grid-column: 1 / -1; }
.bx-prog__row.is-done .bx-bar > i { background: var(--ok); }
@media (max-width: 760px) { .bx-prog { columns: 1; } .bx-prog__row { margin-bottom: 13px; } }

.bx-prof__pulls .bx-row { min-height: 60px; }
.bx-prof__pulls .bx-row__time { align-self: center; padding-top: 0; }

/* Fenêtre « Ma vitrine » */
.bx-shw { gap: 14px; }
.bx-shw__head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin-bottom: 16px; }
.bx-shw__item { position: relative; }
.bx-shw__rm { position: absolute; z-index: 7; top: -8px; right: -8px; display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 1px solid var(--line-2); border-radius: 50%; background: var(--card-2); color: var(--ink-2); cursor: pointer;
  box-shadow: 0 0 0 3px var(--card); transition: color .15s, border-color .15s, background-color .15s; }
.bx-shw__rm:hover { color: var(--bad); border-color: var(--bad-line); background: linear-gradient(var(--bad-dim), var(--bad-dim)), var(--card-2); }
.bx-shw__rm svg { width: 15px; height: 15px; }
@media (max-width: 960px) { .bx-shw__rm { width: 40px; height: 40px; top: -10px; right: -10px; } }
@media (max-width: 600px) { .bx-shw__head > .bx-inline { width: 100%; } .bx-shw__head > .bx-inline .bx-btn { flex: 1 1 0; } }

/* ════════════════════════════ AMIS ET MESSAGES ═════════════════════════════ */


/* Amis : la liste à gauche, l'ajout et les demandes à droite ; une colonne sur téléphone */
.bx-friends { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.bx-friends__list { grid-column: 1; grid-row: 1 / span 3; }
.bx-friends > :not(.bx-friends__list) { grid-column: 2; }
.bx-friends__addbody { display: grid; gap: 14px; }
.bx-friends__res { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.bx-friends__res .bx-row { padding: 10px 12px; }
.bx-friends__res .bx-empty { padding: 22px 14px; }
.bx-friends__btns { display: flex; flex: 0 0 auto; gap: 6px; }
.bx-friends .bx-panel__head .bx-badge { margin-left: auto; }
.bx-friends .bx-row .bx-pill { flex: 0 0 auto; }
.bx-friends a.bx-row__title { margin: -9px 0; padding: 9px 0; }
@media (max-width: 960px) {
  .bx-friends { grid-template-columns: minmax(0, 1fr); }
  .bx-friends__list, .bx-friends > :not(.bx-friends__list) { grid-column: 1; grid-row: auto; }
}
@media (max-width: 600px) {
  .bx-friends .bx-row { padding: 10px 12px; gap: 10px; }
  .bx-friends__btns .bx-btn--ghost { padding: 0 10px; }
}

/* Messages : deux volets sur PC (conversations | fil), une vue à la fois sur téléphone */
.bx-dm { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 14px; height: clamp(460px, calc(100dvh - 236px), 820px); }
.bx-dm__side { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.bx-dm__list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 6px; }
.bx-dm__list > .bx-empty { padding: 32px 14px; }
.bx-dm__conv { align-items: center; min-height: 60px; padding: 10px; border-bottom: 0; border-radius: 14px; }
.bx-dm__conv[aria-current="page"] { background: var(--accent-dim); }
.bx-dm__side-end { display: grid; flex: 0 0 auto; justify-items: end; gap: 6px; align-self: flex-start; padding-top: 2px; }
.bx-dm__side-end .bx-row__time { margin: 0; padding: 0; }
.bx-dm__chat { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
.bx-dm__chat > .bx-empty, .bx-dm__load { margin: auto; }
.bx-dm__head { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 10px 16px; border-bottom: 1px solid var(--line); }
.bx-dm__head .bx-row__meta { margin-top: 2px; }
.bx-dm__name { display: block; overflow: hidden; margin: -9px 0; padding: 9px 0; font-size: 15px; text-overflow: ellipsis; white-space: nowrap; }
.bx-dm__back { display: none; }
.bx-dm__feed { display: flex; flex: 1; flex-direction: column; gap: 12px; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 18px 18px 10px; }
.bx-dm__feed > :first-child { margin-top: auto; }   /* peu de messages : ils se posent en bas, près de la saisie (comme .bx-gd-chat__log) */
.bx-dm__feed > .bx-empty { margin: auto; }

/* Bulles : les mêmes valeurs que la discussion de guilde (cahier 7.9) */
.bx-dm__msg { display: flex; align-items: flex-start; gap: 8px; max-width: min(78%, 560px); }
.bx-dm__msg.is-run { margin-top: -8px; }
.bx-dm__msg.is-mine { align-self: flex-end; flex-direction: row-reverse; }
.bx-dm__ava { display: block; width: 28px; height: 28px; flex: 0 0 28px; }
.bx-dm__col { display: grid; justify-items: start; gap: 4px; min-width: 0; }
.bx-dm__msg.is-mine .bx-dm__col { justify-items: end; }
.bx-dm__bubble { max-width: 100%; padding: 9px 12px; border-radius: 4px 14px 14px 14px; background: var(--card-2); color: var(--ink); font-size: 15px; line-height: 1.45; }
.bx-dm__msg.is-mine .bx-dm__bubble { border-radius: 14px 4px 14px 14px; background: var(--accent-dim); }
.bx-dm__msg.is-run .bx-dm__bubble { border-radius: 14px; }
.bx-dm__text { display: block; white-space: pre-wrap; overflow-wrap: anywhere; }
.bx-dm__card + .bx-dm__text { margin-top: 8px; }
.bx-dm__meta { font: 500 11px/1.2 var(--font); color: var(--ink-3); }
.bx-dm__card { display: block; width: 100%; min-width: 220px; margin: -3px -5px; padding: 3px 5px; border: 0; border-radius: 10px; background: none; color: inherit; text-align: left; cursor: pointer; }
.bx-dm__card:hover { background: rgba(255, 255, 255, .04); }
.bx-dm__sys { align-self: center; max-width: 92%; text-align: center; }
.bx-dm__sys .bx-pill { height: auto; min-height: 40px; padding: 6px 14px; font: 700 13px/1.3 var(--font); letter-spacing: 0; text-transform: none; white-space: normal; text-decoration: none; }
.bx-dm__sys .bx-pill:hover { border-color: var(--accent); }

.bx-dm__form { display: flex; align-items: flex-end; gap: 8px; padding: 12px; border-top: 1px solid var(--line); }
.bx-dm__form .bx-btn--icon { width: 44px; min-height: 44px; flex: 0 0 44px; }
.bx-dm__in { flex: 1; min-width: 0; height: 44px; min-height: 44px; max-height: 132px; padding: 11px 14px; line-height: 1.4; resize: none; }
@media (max-width: 760px) {
  .bx-dm { grid-template-columns: minmax(0, 1fr); height: auto; }
  .bx-dm__list { overflow: visible; }
  .bx-dm.has-open .bx-dm__side, .bx-dm:not(.has-open) .bx-dm__chat { display: none; }
  .bx-dm.has-open .bx-dm__chat { height: calc(100dvh - 150px); min-height: 420px; }
  .bx-dm__ph:has(+ .bx-dm.has-open) { display: none; }
  .bx-dm__back { display: inline-flex; margin-left: -8px; }
  .bx-dm__head { padding: 8px 12px; gap: 10px; }
  .bx-dm__feed { padding: 14px 12px 8px; }
  .bx-dm__msg { max-width: 88%; }
  .bx-dm__card { min-width: 0; }
  .bx-dm__form { padding: 10px; }
}

/* ════════════════════════════════ RÉGLAGES ═════════════════════════════════ */

/* Colonne de 760 px centrée, comme la page des règles (.bx-rules, accueil.css) */
.bx-set, .bx-set__ph { max-width: 760px; margin-inline: auto; }
.bx-set { display: grid; gap: 14px; }
.bx-set__backnote { margin-top: 16px; }
.bx-set__account { display: flex; align-items: flex-start; gap: 16px; }
.bx-set__ava { width: 56px; height: 56px; flex: 0 0 56px; }
.bx-set__name { display: block; margin-bottom: 4px; font-size: 1.06rem; }
.bx-set__logout { display: inline-flex; align-items: center; min-height: 40px; margin-top: 2px; color: var(--ink-3); font: 700 13px/1 var(--font); text-decoration: none; transition: color .15s; }
.bx-set__logout:hover { color: var(--bad); }
.bx-set__facts { padding: 0 22px 22px; }
.bx-set__rows { padding: 2px 22px; }
.bx-set__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; min-height: 68px; padding: 12px 0; border-bottom: 1px solid var(--line); cursor: pointer; }
div.bx-set__row { cursor: default; }
.bx-set__row:last-child { border-bottom: 0; }
.bx-set__txt { display: grid; flex: 1 1 220px; gap: 3px; min-width: 0; }
.bx-set__txt b { color: var(--ink); font-size: 15px; }
.bx-set__row > .bx-chips, .bx-set__row > .bx-switch, .bx-set__row > .bx-btn { flex: 0 0 auto; }
.bx-set__row .bx-switch { min-height: 40px; }
.bx-set__profile { gap: 14px; }
.bx-set__bioact { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bx-set__titlerow { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px; padding-top: 16px; border-top: 1px solid var(--line); }
.bx-set__title { display: flex; align-items: center; min-height: 26px; margin-top: 10px; }
.bx-set .bx-panel__head .bx-link { display: inline-flex; align-items: center; min-height: 40px; font-size: 13px; }
.bx-set__backs { display: grid; grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); gap: 12px; }
.bx-set__back { display: grid; justify-items: center; align-content: start; gap: 8px; padding: 10px 8px 12px; border: 1px solid transparent; border-radius: 16px;
  background: none; color: inherit; font: inherit; text-align: center; cursor: pointer; transition: background-color .15s, border-color .15s; }
.bx-set__back:hover { background: rgba(255, 255, 255, .03); border-color: var(--line); }
.bx-set__back[aria-pressed="true"] { background: var(--accent-dim); border-color: var(--accent-line); cursor: default; }
.bx-set__backvis { display: block; width: 100%; max-width: 120px; margin-bottom: 2px; }
.bx-set__back b { font-size: 15px; }
@media (max-width: 600px) {
  .bx-set__rows { padding: 2px 16px; }
  .bx-set__facts { padding: 0 16px 16px; }
  .bx-set__account { gap: 12px; }
  .bx-set__backs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .bx-set__back b { font-size: 13px; }
}

/* ════════════════════════════ ADMINISTRATION ═══════════════════════════════ */

/* Chiffres du jeu : deux tableaux « libellé | nombre » côte à côte, l'un sous l'autre sur téléphone */
.bx-adm__statgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.bx-adm__statgrid > .bx-table + .bx-table { border-left: 1px solid var(--line); }
.bx-adm__statgrid .bx-table th { position: static; background: none; }
.bx-adm__statgrid .bx-table th, .bx-adm__statgrid .bx-table td { padding: 0 20px; }
.bx-adm__statgrid .bx-table td:first-child { color: var(--ink-2); }
@media (max-width: 760px) {
  .bx-adm__statgrid { grid-template-columns: minmax(0, 1fr); }
  .bx-adm__statgrid > .bx-table + .bx-table { border-left: 0; border-top: 1px solid var(--line); }
  .bx-adm__statgrid .bx-table th, .bx-adm__statgrid .bx-table td { padding: 0 16px; }
}
/* Ventes Onyx : mêmes tableaux côte à côte (aujourd'hui | 7 jours), lignes de total en gras */
.bx-adm__sales { margin-top: 14px; }
.bx-adm__sales .bx-table th:not(:first-child) { text-align: right; }
.bx-adm__sales .bx-table tr.is-total td { border-top: 1px solid var(--line-2); color: var(--ink); font-weight: 800; }
.bx-adm__sales .bx-table tr.is-sub td { height: 36px; }
.bx-adm__sales .bx-table td.is-num + td.is-num { padding-left: 4px; }
.bx-adm__salesnote { padding: 12px 20px 16px; border-top: 1px solid var(--line); }
@media (max-width: 760px) { .bx-adm__salesnote { padding: 12px 16px 14px; } }

.bx-adm__grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 14px; align-items: start; }
@media (max-width: 960px) { .bx-adm__grid { grid-template-columns: minmax(0, 1fr); } }
.bx-adm__find { display: flex; gap: 8px; }
.bx-adm__player { gap: 18px; }
.bx-adm__who { display: flex; align-items: center; gap: 12px; }
.bx-adm__who > .bx-grow { flex: 1 1 0; }
.bx-adm__name { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 4px; }
.bx-adm__name b { font-size: 1.06rem; }
.bx-adm__h { margin-bottom: 10px; }
.bx-adm__scroll { max-height: 340px; overflow: auto; overscroll-behavior: contain; border: 1px solid var(--line); border-radius: 14px; }
.bx-adm__scroll .bx-table td { padding-top: 6px; padding-bottom: 6px; }
.bx-table td.is-neg { color: var(--bad); }
.bx-table td.is-pos { color: var(--ok); }
.bx-adm__reason { display: block; font-weight: 600; }
.bx-adm__ref { display: block; max-width: 240px; overflow: hidden; color: var(--ink-3); font: 500 11px/1.3 var(--mono); text-overflow: ellipsis; white-space: nowrap; }
.bx-table .bx-adm__when { width: 1%; text-align: right; white-space: nowrap; }
.bx-table td.bx-adm__when { color: var(--ink-3); font-size: 13px; }
.bx-adm__acts { display: grid; }
.bx-adm__group { display: grid; gap: 12px; padding: 18px 0; border-bottom: 1px solid var(--line); }
.bx-adm__group:first-child { padding-top: 0; }
.bx-adm__group:last-child { padding-bottom: 0; border-bottom: 0; }
.bx-adm__line { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.bx-adm__group .bx-switch { justify-self: start; }
.bx-adm__group .bx-field:has(> .bx-input:disabled) { opacity: .45; }
.bx-adm__group .bx-input:disabled { cursor: not-allowed; }

.bx-adm__cfgbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin-bottom: 14px; }
.bx-adm__cfgbar .bx-search { flex: 1 1 260px; max-width: 380px; }
.bx-adm__cfgs { gap: 14px; }
.bx-adm__cfglist { display: flex; flex-direction: column; }
.bx-adm__cfg { display: grid; grid-template-columns: minmax(0, 1fr) minmax(170px, 280px) auto; align-items: center; gap: 8px 14px; padding: 12px 20px; border-bottom: 1px solid var(--line); }
.bx-adm__cfg:last-child { border-bottom: 0; }
.bx-adm__cfgtxt { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 10px; min-width: 0; }
.bx-adm__cfgtxt b { font-size: 15px; font-weight: 650; }
.bx-adm__key { flex-basis: 100%; color: var(--ink-3); font-size: 13px; overflow-wrap: anywhere; }
.bx-adm__mod { display: none; }
.bx-adm__cfg.is-changed .bx-adm__mod { display: inline-flex; }
.bx-adm__cfg.is-changed { background: rgba(var(--accent-rgb), .035); }
.bx-adm__val { font-family: var(--mono); }
/* Champs chiffrés : l'espace insécable des milliers ramenée à une espace fine, comme ailleurs en mono (components.css:105) */
.bx-adm__val.is-num { font-variant-numeric: tabular-nums; word-spacing: -.32em; }
textarea.bx-adm__val { min-height: 64px; padding: 10px 12px; }
@media (min-width: 961px) { .bx-adm__val { font-size: 13px; } }

/* Réglage par rareté : libellé et « Enregistrer » sur la première ligne, une case par rareté dessous */
.bx-adm__cfg.is-rar { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "txt save" "rar rar"; row-gap: 14px; }
.bx-adm__cfg.is-rar > .bx-adm__cfgtxt { grid-area: txt; }
.bx-adm__cfg.is-rar > [data-save] { grid-area: save; }
.bx-adm__rars { grid-area: rar; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px 10px; }
.bx-adm__rar { display: grid; justify-items: start; align-content: start; gap: 6px; min-width: 0; }
.bx-adm__orig { max-width: 100%; overflow: hidden; color: var(--ink-3); font-size: 13px; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 960px) { .bx-adm__rars { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 600px) { .bx-adm__rars { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

@media (max-width: 760px) {
  .bx-adm__cfg { grid-template-columns: minmax(0, 1fr) auto; padding: 14px 16px; }
  .bx-adm__cfgtxt { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
  .bx-adm__find { flex-wrap: wrap; }
  .bx-adm__find .bx-btn { width: 100%; }
}

/* ═══════════════════════════════ VENT DU JOUR ════════════════════════════════
   Une ligne discrète (page Paquets, src/js/plugins/vent.js) : pas de lueur ni de violet néon, pas
   d'icône nouvelle (cahier §9.1), juste un trait d'accent avant le texte, comme .bx-small ailleurs. */
.bx-vent { display: flex; align-items: baseline; gap: 8px; color: var(--ink-3); }
.bx-vent::before { content: ''; flex: 0 0 auto; width: 10px; height: 2px; border-radius: 1px; background: rgba(var(--accent-rgb), .7); }


/* ===== css/pages/doubles.css ===== */
/* BloxMasters - Doubles comptes (src/js/plugins/doubles.js), page d'administration : un bloc par groupe de
   comptes liés, ses comptes puis ses paires avec ce qu'elles se sont transmis et la décision du staff.
   Jetons du cahier §3.1 seulement : aucune lueur, aucun emoji, cibles de 44 px sur téléphone. */

.bx-adm-dbl { margin-bottom: 8px; }
.bx-adm-dbl__intro { padding: 14px 20px; border-bottom: 1px solid var(--line); }
.bx-adm-dbl__intro p { margin: 0; max-width: 86ch; }
.bx-adm-dbl__grp { display: grid; gap: 14px; padding: 18px 20px; border-bottom: 1px solid var(--line); }
.bx-adm-dbl__grp:last-child { border-bottom: 0; }
.bx-adm-dbl__grphead { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }

.bx-adm-dbl__players { display: grid; gap: 12px; }
.bx-adm-dbl__who { display: flex; align-items: center; gap: 12px; }
.bx-adm-dbl__who > .bx-grow { display: grid; gap: 2px; flex: 1 1 0; min-width: 0; }
.bx-adm-dbl__who .bx-adm__name { margin-bottom: 0; }
.bx-adm-dbl__facts { color: var(--ink-3); }
.bx-adm-dbl__acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }

.bx-adm-dbl__pairs { display: grid; gap: 10px; }
.bx-adm-dbl__pair { display: grid; gap: 6px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-m); }
.bx-adm-dbl__pairhead { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.bx-adm-dbl__flow { margin: 0; padding-left: 18px; color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.bx-adm-dbl__pair .bx-adm-dbl__acts { justify-content: flex-start; margin-top: 4px; }

@media (max-width: 760px) {
  .bx-adm-dbl__intro { padding: 12px 16px; }
  .bx-adm-dbl__grp { padding: 16px; }
  .bx-adm-dbl__who { flex-wrap: wrap; align-items: flex-start; }
  .bx-adm-dbl__who > .bx-adm-dbl__acts { width: 100%; justify-content: flex-start; }
  .bx-adm-dbl__acts .bx-btn { min-height: 44px; }
}


/* ===== css/pages/marche.css ===== */
/* BloxMasters - pages Marché (cahier 7.5 : liste, enchère, mes ventes, fenêtre de mise en vente) et
   Échanges (cahier 7.6 : offres, partenaires, composition d'une offre). Vues : js/views/market.js et
   js/views/trades.js. Tout est composé avec les classes communes (components.css) ; ce fichier ne
   pose que la mise en page propre à ces vues, sous le préfixe bx-mk- (et .bx-trade, nommé par le cahier).
   Aucune teinte hors des jetons, sauf le point irisé du chromatique, repris de card.css. */

/* ── Commun aux deux pages ─────────────────────────────────────────────────── */
/* Point irisé du chromatique (mêmes couleurs que .bxc__chroma i, card.css) */
.bx-mk-iris { display: inline-block; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
  background: var(--chroma-ring); }

.bx-mk-nothing { font-size: 13px; color: var(--ink-3); }
/* Liens de texte (nom d'un joueur, « Voir son album ») : zone de toucher de 40 px sans changer la ligne */
.bx-trade__who .bx-plink, .bx-mk-auction__seller .bx-plink, .bx-mk-bid__state .bx-plink, .bx-mk-with .bx-plink, .bx-mk-with .bx-link, .bx-mk-partner__head .bx-plink {
  display: inline-block; min-width: 40px; padding: 12px 0; margin: -12px 0; }
.bx-mk-dot { margin: 0 6px; color: var(--ink-4); }

/* Une carte en ligne (vignette, nom, rareté) qui ouvre sa fiche : échanges, résumé d'une offre */
.bx-mk-cardrow { display: flex; align-items: center; width: 100%; min-width: 0; min-height: 48px; padding: 4px 8px 4px 4px;
  border: 0; border-radius: 12px; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: background-color .15s; -webkit-tap-highlight-color: transparent; }
.bx-mk-cardrow:hover { background: rgba(255, 255, 255, .04); }
.bx-mk-cardrow .bx-mini { flex: 1 1 auto; }
/* Vignettes seules (au-delà de trois cartes, partenaires) */
.bx-mk-vis { display: flex; flex-wrap: wrap; gap: 6px; }
.bx-mk-visbtn { display: block; padding: 0; border: 0; border-radius: 10px; background: none; cursor: pointer;
  transition: transform .15s var(--ease); -webkit-tap-highlight-color: transparent; }
.bx-mk-visbtn:hover { transform: translateY(-2px); }

/* En-tête de page sur téléphone : le bouton principal sur toute la largeur, le reste dessous. Le bouton
   désactivé du verrou des paquets (« Vendre dès 50 paquets ouverts ») prend la même place : son libellé
   ne tiendrait pas dans une demi-largeur. « Comment ça marche » reste calé à gauche, comme ailleurs. */
@media (max-width: 600px) {
  .bx-mk-ph .bx-ph__act { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; }
  .bx-mk-ph .bx-ph__act > .bx-btn--primary, .bx-mk-ph .bx-ph__act > .bx-mk-locked { grid-column: 1 / -1; order: -1; }
}

/* Verrou des paquets (BM.tradeGateHtml, detail.js) : sous l'en-tête du Marché et des Échanges, le compte
   « Paquets ouverts 16 / 50 », sa barre, puis ce qu'il reste à ouvrir et ce qui est déjà permis. */
.bx-mk-gate { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; max-width: 660px; margin: -6px 0 26px; }
.bx-mk-gate > .bx-mk-gate__top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0;
  font: 600 13px/1.2 var(--font); color: var(--ink-3); }
.bx-mk-gate > .bx-mk-gate__top .bx-num { font-size: 13px; color: #fff; }
.bx-mk-gate > .bx-mk-gate__txt { max-width: none; margin: 2px 0 0; font: 500 13px/1.45 var(--font); color: var(--ink-2); }
.bx-mk-gate + .bx-tabs { margin-bottom: 4px; }
/* Composer un échange verrouillé : le même bloc dans un état vide, avec le chemin vers les paquets. Seul
   l'âge du compte Discord manque (.is-age, sans barre) : la phrase se centre comme le reste de l'état vide. */
.bx-mk-gatebox { margin-top: 4px; }
.bx-mk-gatebox > .bx-mk-gate { width: min(100%, 420px); margin: 6px 0 8px; text-align: left; }
.bx-mk-gatebox > .bx-mk-gate.is-age { text-align: center; }

/* ── 7.5 Marché : barre d'outils ───────────────────────────────────────────── */
.bx-mk-tools { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin: 0 0 26px; }
.bx-mk-tools__top { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.bx-mk-tools__q { flex: 1 1 240px; min-width: 0; }
.bx-mk-tools__fam { flex: 0 1 220px; width: auto; min-width: 180px; }
.bx-mk-sort { display: flex; align-items: center; gap: 10px; min-width: 0; margin-left: auto; }
.bx-mk-sort .bx-micro { flex: 0 0 auto; }
.bx-mk-sort .bx-chips { flex: 1 1 auto; min-width: 0; }
.bx-mk-sep { flex: 0 0 1px; align-self: center; width: 1px; height: 20px; margin: 0 4px; background: var(--line-2); }
/* Quand le tri passe à la ligne, il se cale à gauche comme le reste */
@media (max-width: 1100px) { .bx-mk-sort { flex: 1 1 100%; margin-left: 0; } }
@media (max-width: 760px) { .bx-mk-tools__q, .bx-mk-tools__fam { flex: 1 1 100%; } }

/* Filtre « ventes de cette carte » (lien depuis la fiche) */
.bx-mk-cardfilter { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; margin-bottom: 16px; padding: 14px 16px; }
.bx-mk-cardfilter__txt { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; flex: 1 1 auto; min-width: 0; }

/* ── 7.5 Marché : grille des ventes ────────────────────────────────────────── */
.bx-mk-grid { grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 28px 18px; }
@media (max-width: 600px) { .bx-mk-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 12px; } }
.bx-mk-auc { display: flex; flex-direction: column; gap: 12px; min-width: 0; color: inherit; text-decoration: none; -webkit-tap-highlight-color: transparent; }
.bx-mk-auc__card { border-radius: 12px; transition: transform .2s var(--ease); }
@media (hover: hover) {
  .bx-mk-auc:hover .bx-mk-auc__card { transform: translateY(-4px); }
  .bx-mk-auc:hover .bxc { --bxc-drop: 0 22px 40px -16px rgba(0, 0, 0, .85); }
}
.bx-mk-auc:focus-visible { outline: none; }
.bx-mk-auc:focus-visible .bx-mk-auc__card { outline: 2px solid var(--accent-2); outline-offset: 3px; }
.bx-mk-auc__info { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 0 2px; }
.bx-mk-auc__price { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.bx-mk-auc__price .bx-amt { font-size: 16px; color: #fff; }
.bx-mk-auc__bids { margin-left: auto; font: 500 13px/1 var(--font); color: var(--ink-3); white-space: nowrap; }
.bx-mk-auc__line { font: 500 13px/1.35 var(--font); color: var(--ink-3); }
.bx-mk-auc__line .bx-time, .bx-mk-auc__line .bx-num { color: var(--ink); }
.bx-mk-auc__who { overflow: hidden; font: 500 13px/1.35 var(--font); color: var(--ink-3); text-overflow: ellipsis; white-space: nowrap; }
.bx-mk-auc__who.is-lead { color: var(--ok); font-weight: 700; }
.bx-mk-auc__who.is-mine { color: var(--accent-2); font-weight: 700; }
.bx-mk-auc__line .bx-time.is-soon, .bx-mk-row .bx-time.is-soon { color: var(--warn); }
.bx-mk-more { display: flex; justify-content: center; margin-top: 30px; }

/* ── 7.5 Page d'une enchère ────────────────────────────────────────────────── */
.bx-mk-auction { display: grid; grid-template-columns: 360px minmax(0, 1fr); gap: 32px 44px; align-items: start; }
.bx-mk-auction__card { position: sticky; top: calc(var(--head-h) + 24px); }
.bx-mk-auction__side { min-width: 0; max-width: 680px; }
.bx-mk-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.bx-mk-auction__name { margin-top: 14px; font: 800 1.9rem/1.08 var(--display); letter-spacing: -.02em; color: #fff; overflow-wrap: anywhere; text-wrap: balance; }
.bx-mk-auction__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; margin-top: 12px; font-size: 14px; color: var(--ink-3); }
.bx-mk-auction__meta .bx-num { color: var(--ink); }
.bx-mk-auction__seller { display: inline-flex; align-items: center; gap: 8px; min-height: 24px; }
.bx-mk-auction__facts { margin-top: 16px; }
/* Fait « Prix habituel » suivi de son aide « ? » (BM.helpBtn), comme « Éclats » dans l'album : le rond se
   centre sur sa pastille et s'y colle ; l'écart de la rangée le sépare du fait suivant. La zone de toucher
   de 40 px déborde sans grandir la rangée. */
.bx-mk-fx { display: inline-flex; align-items: center; height: 34px; }
.bx-mk-auction__fiche { display: inline-flex; align-items: center; min-height: 40px; margin-top: 12px; padding: 0; border: 0; background: none; font-size: 14px; cursor: pointer; }
.bx-mk-count { font: 700 13px/1 var(--mono); color: var(--ink-3); }

/* Bloc de mise */
.bx-mk-bid { margin-top: 20px; padding: 22px; }
.bx-mk-bid__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 26px; }
.bx-mk-bid__amt { display: flex; align-items: center; gap: 12px; margin-top: 10px; font: 900 2.4rem/1 var(--display); letter-spacing: -.03em; color: #fff; }
.bx-mk-bid__amt .bx-coin__ic--beli { width: 15px; height: 30px; }
.bx-mk-bid__end { margin-top: 12px; font-size: 15px; color: var(--ink-2); }
.bx-mk-bid__end .bx-time { color: #fff; }
.bx-mk-bid__state { margin-top: 12px; font-size: 15px; color: var(--ink-2); }
.bx-mk-bid__note { margin-top: 12px; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-mk-bid__acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.bx-mk-bid__form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; margin-top: 18px; }
.bx-mk-bid__form .bx-stepper { height: 52px; }
.bx-mk-bid__form .bx-btn--lg { min-width: 140px; }
.bx-mk-bid .bx-stepper button, .bx-mk-sell .bx-stepper button { display: grid; flex: 0 0 auto; place-items: center; }
.bx-mk-bid__form .bx-stepper button { width: 52px; }
.bx-mk-bid__bal { margin-top: 10px; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-mk-bid__bal .bx-num { color: var(--ink); }
.bx-mk-bid__buy { margin-top: 14px; }
.bx-mk-bid__rules { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 13px; line-height: 1.5; color: var(--ink-3); }

/* Historique des mises */
.bx-mk-hist__at { display: block; margin-top: 4px; font: 500 12px/1 var(--mono); color: var(--ink-3); }
.bx-mk-hist .bx-row__num .bx-amt { font-size: 14px; }
.bx-mk-hist__none { padding: 18px 16px; font-size: 14px; color: var(--ink-3); }

@media (max-width: 860px) {
  .bx-mk-auction { grid-template-columns: 1fr; gap: 26px; }
  .bx-mk-auction__card { position: static; width: min(300px, 100%); margin: 0 auto; }
}
@media (max-width: 600px) {
  .bx-mk-bid { padding: 18px 16px; }
  .bx-mk-bid__form { grid-template-columns: 1fr; }
}

/* ── 7.5 Mes ventes et mises ───────────────────────────────────────────────── */
.bx-mk-ph + .bx-tabs { margin-bottom: 4px; }
.bx-mk-row .bx-row__meta .bx-time { color: var(--ink-2); }
/* Montant à gauche de la pastille, sur la même ligne : les pastilles sont à la même hauteur et calées
   à droite dans toutes les lignes, qu'il y ait un montant ou non. */
.bx-mk-row__side { display: flex; flex: 0 0 auto; flex-direction: row-reverse; align-items: center; gap: 12px; margin-left: auto; }
.bx-mk-row__amt .bx-amt { font-size: 14px; color: #fff; }
/* Téléphone : côte à côte, pastille et montant mangeraient le nom de la carte. La pastille reste sur la
   ligne du nom, en haut à droite dans toutes les lignes, et le montant passe dessous. */
@media (max-width: 600px) {
  .bx-mk-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: auto auto; gap: 4px 12px; }
  .bx-mk-row > :not(.bx-mk-row__side) { grid-row: 1 / 3; }
  .bx-mk-row__side { display: contents; }
  .bx-mk-row__side > .bx-pill { grid-area: 1 / 3; align-self: start; justify-self: end; }
  .bx-mk-row__amt { grid-area: 2 / 3; align-self: start; justify-self: end; }
}

/* ── 7.5 Fenêtre « Mettre aux enchères » (BM.sellCopy) ─────────────────────── */
.bx-mk-sell { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 22px; align-items: start; }
.bx-mk-sell__card { display: grid; gap: 10px; justify-items: center; text-align: center; }
.bx-mk-sell__card .bxc { width: 150px; }
.bx-mk-sell__card .bx-num { color: var(--ink); }
.bx-mk-sell__form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; min-width: 0; }
.bx-mk-sell__hint { font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.bx-mk-sell__tax { padding-top: 14px; border-top: 1px solid var(--line); font-size: 13px; line-height: 1.5; color: var(--ink-3); }
@media (max-width: 600px) {
  .bx-mk-sell { grid-template-columns: 1fr; gap: 18px; }
  .bx-mk-sell__card .bxc { width: 140px; }
}

/* ── 7.6 Échanges : liste des offres ───────────────────────────────────────── */
.bx-mk-trades { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
.bx-trade { padding: 18px; }
.bx-trade__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.bx-trade__who { flex: 1 1 auto; min-width: 0; font-size: 15px; color: var(--ink-2); }
.bx-trade__time { font: 500 13px/1 var(--font); color: var(--ink-3); white-space: nowrap; }
.bx-trade__msg { margin-top: 14px; padding: 10px 14px; border: 1px solid var(--line); border-radius: 14px; background: rgba(255, 255, 255, .03);
  font-size: 14px; line-height: 1.5; color: var(--ink-2); overflow-wrap: anywhere; }
.bx-trade__body { display: grid; grid-template-columns: minmax(0, 1fr) 40px minmax(0, 1fr); gap: 16px; align-items: start; margin-top: 16px; }
.bx-trade__side { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.bx-mk-cards { display: flex; flex-direction: column; gap: 2px; margin: 0 -4px; }
.bx-trade__swap { align-self: center; display: grid; place-items: center; width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 50%;
  background: rgba(255, 255, 255, .03); color: var(--ink-3); }
.bx-trade__swap svg { width: 18px; height: 18px; }
/* Deux icônes : l'échange horizontal entre les deux colonnes, l'échange vertical (swapV) quand les côtés s'empilent. */
.bx-trade__swap .bx-trade__v { display: none; }
.bx-trade__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.bx-trade__chat { display: inline-flex; align-items: center; min-height: 40px; margin-right: auto; color: var(--accent-2); font: 700 13px/1 var(--font); text-decoration: none; }
.bx-trade__chat:hover { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 600px) {
  .bx-trade { padding: 16px; }
  /* En-tête d'une offre : avatar sur deux lignes, nom et statut sur la première, l'heure dessous, alignée sur le nom. */
  .bx-trade__head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 12px; row-gap: 2px; align-items: center; }
  .bx-trade__head > .bx-ava { grid-row: 1 / 3; }
  .bx-trade__who { grid-column: 2; grid-row: 1; }
  .bx-trade__head > .bx-pill { grid-column: 3; grid-row: 1; }
  .bx-trade__time { grid-column: 2 / 4; grid-row: 2; }
  .bx-trade__body { grid-template-columns: 1fr; gap: 12px; }
  .bx-trade__swap { justify-self: center; }
  .bx-trade__swap .bx-trade__h { display: none; }
  .bx-trade__swap .bx-trade__v { display: block; width: 20px; height: 20px; }
  .bx-trade__foot { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bx-trade__foot > .bx-btn--primary, .bx-trade__foot > .bx-btn:last-child:nth-child(2), .bx-trade__foot > .bx-mk-locked { grid-column: 1 / -1; }
  .bx-trade__foot > .bx-btn--primary, .bx-trade__foot > .bx-mk-locked { order: -1; }
  /* Offre reçue sous le verrou des paquets : « Accepter dès... » grisé puis « Refuser », chacun sur sa ligne. */
  .bx-trade__foot:has(> .bx-mk-locked) > .bx-btn { grid-column: 1 / -1; }
  .bx-trade__chat { grid-column: 1 / -1; justify-content: center; margin: 0; order: 5; }
}

/* Partenaires suggérés */
.bx-mk-lead { margin: -4px 0 16px; }
.bx-mk-partners { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 14px; }
.bx-mk-partner { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: 16px; padding: 18px; }
.bx-mk-partner__head { display: flex; align-items: center; gap: 10px; }
.bx-mk-partner__seen { display: block; margin-top: 4px; font-size: 13px; color: var(--ink-3); }
.bx-mk-partner__row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }

/* ── 7.6 Composer un échange ───────────────────────────────────────────────── */
.bx-mk-with { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; font-size: 15px; color: var(--ink-2); }
.bx-mk-with .bx-link { margin-left: 6px; font-size: 14px; }
.bx-mk-tb__tabs { display: none; }
.bx-mk-tb { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 340px) minmax(0, 1fr); gap: 16px; align-items: start; }
.bx-mk-tb__pane { min-width: 0; }
.bx-mk-tb__pane > .bx-panel__head { padding: 14px 16px; }
.bx-mk-tb__n { margin-left: auto; font: 700 12px/1 var(--mono); color: var(--accent-2); white-space: nowrap; }
.bx-mk-tb__chosen { margin-left: auto; font: 700 13px/1 var(--font); color: var(--accent-2); white-space: nowrap; }
.bx-mk-tb__tools { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.bx-mk-tb__grid { max-height: min(66vh, 720px); overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px 18px; scrollbar-width: thin; }
.bx-mk-tb__cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 14px 10px; }
.bx-mk-tb__more { display: flex; justify-content: center; margin-top: 16px; }
.bx-mk-tb__sum { position: sticky; top: calc(var(--head-h) + 16px); max-height: calc(100vh - var(--head-h) - 32px); overflow-y: auto; overscroll-behavior: contain; }
.bx-mk-tb__sumbody { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 16px; }
.bx-mk-tb__pile { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.bx-mk-tb__pilehead { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bx-mk-tb__items { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; margin: 0 -4px; }
.bx-mk-tb__item { display: flex; align-items: center; gap: 2px; min-width: 0; }
.bx-mk-tb__item .bx-mk-cardrow { flex: 1 1 auto; }
.bx-mk-tb__item > .bx-btn--icon { flex: 0 0 40px; }   /* « Retirer », « Ajouter un autre » : 40 px même au téléphone */
.bx-mk-tb__amt { position: relative; }
.bx-mk-tb__amt .bx-coin__ic { position: absolute; top: 50%; left: 15px; transform: translateY(-50%); pointer-events: none; }
.bx-mk-tb__amt .bx-input { padding-left: 34px; font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; word-spacing: -.32em; }
.bx-mk-tb__bal { font-size: 13px; color: var(--ink-3); }
.bx-mk-tb__bal .bx-num { color: var(--ink); }
/* Les deux piles du résumé sont l'une sous l'autre : l'échange vertical (swapV), dessiné droit. */
.bx-mk-tb__swap { justify-self: center; display: grid; place-items: center; width: 36px; height: 36px; border: 1px solid var(--line); border-radius: 50%;
  color: var(--ink-3); }
.bx-mk-tb__swap svg { width: 18px; height: 18px; }
.bx-mk-tb__rule { text-align: center; }
.bx-mk-tb__sentinel { display: block; height: 1px; margin-bottom: -1px; }
.bx-mk-tb__bar { display: none; }
@keyframes bx-mk-bar-in { from { opacity: 0; transform: translateY(12px); } }
@media (max-width: 960px) {
  /* Onglets collés en haut de l'écran (l'en-tête du site est dans le flux à cette largeur) : on change de
     volet et on voit le nombre de cartes choisies de chaque côté sans remonter une liste de 70 cartes. */
  .bx-mk-tb__tabs { position: sticky; top: 8px; z-index: 20; display: inline-flex; margin-bottom: 14px;
    transition: background-color .2s, border-color .2s, box-shadow .2s; }
  .bx-mk-tb__tabs.is-stuck { background: var(--card-2); border-color: var(--line-2); box-shadow: var(--shadow-pop); }
  .bx-mk-tb { grid-template-columns: 1fr; }
  .bx-mk-tb > [data-pane]:not(.is-active) { display: none; }
  .bx-mk-tb__pane > .bx-panel__head { display: none; }   /* l'onglet nomme déjà le volet */
  .bx-mk-tb__grid { max-height: none; overflow: visible; }
  .bx-mk-tb__sum { position: static; max-height: none; overflow: visible; }
  /* Rappel de l'offre en bas de l'écran (même matière que la barre de sélection de l'album) ; collé et non
     fixe : en fin de liste il se pose sous les cartes au lieu de couvrir le pied de page. */
  .bx-mk-tb__bar { position: sticky; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); z-index: 20;
    display: flex; align-items: center; gap: 10px; margin-top: 14px; padding: 8px 8px 8px 16px;
    border-radius: 18px; background: var(--card-2); border: 1px solid var(--line-2); box-shadow: var(--shadow-pop); }
  .bx-mk-tb__barn { flex: 1 1 auto; min-width: 0; font: 600 14px/1.3 var(--font); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .bx-mk-tb__barn b { font: 700 15px/1 var(--mono); color: #fff; }
  .bx-mk-tb__bar > .bx-btn { flex: 0 0 auto; }
  .bx-main > .bx-mk-tb__bar { animation: bx-mk-bar-in .24s var(--ease-out); }   /* rejoué à chaque apparition */
  /* Les notifications passent au-dessus du rappel (sauf fenêtre ouverte : elles sont alors en haut). */
  body.bx:has(.bx-mk-tb__bar:not([hidden])):not(:has(.bx-modal)) .bx-toasts { bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 600px) {
  .bx-mk-tb__tabs { display: grid; }
  .bx-mk-tb__cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 8px; }
  .bx-mk-tb__tools, .bx-mk-tb__grid { padding-left: 12px; padding-right: 12px; }
}

/* ── Fiche d'une carte (detail.js) : données ────────────────────────────────── */
/* Libellés en mots simples (« Sorties sur le serveur », « Prix habituel au marché ») : au téléphone, certains
   passent sur deux lignes. Les deux valeurs d'une même rangée restent alignées, posées en bas de leur case
   (les cases d'une rangée de la grille ont la même hauteur), et l'interligne de 1,3 écarte les deux lignes
   d'un libellé (l'accent de MARCHÉ ne touche plus la ligne du dessus). Le reste de la fiche est dans album.css. */
.bx-cd__dd:not(.is-wide) { justify-content: space-between; }
.bx-cd__dd dt { line-height: 1.3; }

/* ── Mouvement réduit ──────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .bx-mk-auc__card, .bx-mk-visbtn { transition: none; }
  .bx-mk-auc:hover .bx-mk-auc__card, .bx-mk-visbtn:hover { transform: none; }
}
body.reduce-motion .bx-mk-auc__card, body.reduce-motion .bx-mk-visbtn { transition: none; }
body.reduce-motion .bx-mk-auc:hover .bx-mk-auc__card, body.reduce-motion .bx-mk-visbtn:hover { transform: none; }


/* ===== css/pages/missions.css ===== */
/* BloxMasters - Missions du jour (src/js/plugins/missions.js) : panneau de la page Paquets, sous la
   baie (ou dans le logement des Premiers pas une fois le tutoriel fini). Jetons du cahier §3.1
   seulement : aucune lueur, aucune couleur hors charte, aucun emoji ; un seul bouton principal par
   ligne (Réclamer, ou le lien « Y aller » tant que ce n'est pas fait) ; cibles de 40 px au moins
   sur téléphone. */

.bx-missions { margin-top: 14px; }
.bx-missions.is-loading { display: grid; padding: 4px 0; overflow: hidden; }
.bx-missions.is-loading .bx-skel--row:last-child { border-bottom: 0; }

.bx-missions__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding: 12px 20px; border-bottom: 1px solid var(--line); }
.bx-missions__head h3 { margin: 0; white-space: nowrap; }
/* Pastille du titre : .bx-fact telle quelle (34 px, texte centré) ; .bx-missions__n est le compteur de chaque ligne. */
.bx-missions__count { white-space: nowrap; }
.bx-missions__reset { margin-left: auto; color: var(--ink-3); white-space: nowrap; }

.bx-missions__list { margin: 0; padding: 0; list-style: none; }
.bx-missions__row {
  display: grid; grid-template-columns: minmax(0, 1fr) 120px auto auto;
  align-items: center; gap: 8px 16px; padding: 14px 20px; border-bottom: 1px solid var(--line);
}
.bx-missions__row:last-child { border-bottom: 0; }
.bx-missions__row.is-done { opacity: .68; }

.bx-missions__info { display: grid; gap: 2px; min-width: 0; }
.bx-missions__title { font: 700 14px/1.3 var(--font); color: var(--ink); }
.bx-missions__reward { font: 500 12px/1.3 var(--font); color: var(--ink-3); }

.bx-missions__bar { width: 120px; }
.bx-missions__n { font: 600 12px/1 var(--font); color: var(--ink-3); white-space: nowrap; }

.bx-missions__act { display: flex; justify-content: flex-end; }
.bx-missions__ok { display: flex; align-items: center; gap: 6px; font: 600 13px/1 var(--font); color: var(--ok); white-space: nowrap; }

.bx-missions__bonus { margin: 14px 20px 18px; }
.bx-missions__bonus.is-done { display: flex; align-items: center; gap: 6px; color: var(--ink-3); font: 500 13px/1.3 var(--font); margin: 0; padding: 14px 20px; }
.bx-missions__bonus.bx-btn { margin: 14px 20px 18px; }

@media (max-width: 640px) {
  .bx-missions__row {
    grid-template-columns: 1fr auto; grid-template-areas: "info act" "bar bar";
    row-gap: 10px;
  }
  .bx-missions__info { grid-area: info; }
  .bx-missions__act { grid-area: act; }
  .bx-missions__bar { grid-area: bar; width: 100%; }
  .bx-missions__n { display: none; }
  .bx-missions__reset { margin-left: 0; flex-basis: 100%; }
}


/* ===== css/pages/parrainage.css ===== */
/* BloxMasters - module parrainage (panneau « Invite tes amis », carte « Rejoins le Discord »).
   Composants communs repris de components.css (.bx-panel, .bx-pad, .bx-input, .bx-btn, .bx-fact,
   .bx-pill...) : rien ici n'en redéfinit un. Juste les deux rangées propres à ce module. */

.bx-ref__row { align-items: stretch; }
.bx-ref__input { flex: 1 1 260px; min-width: 0; font-family: var(--mono); }
.bx-ref__row .bx-btn { flex: 0 0 auto; }

.bx-ref-discord__row { align-items: center; gap: 16px; }
.bx-ref-discord__row .bx-small { margin: 4px 0 0; }

@media (max-width: 600px) {
  .bx-ref-discord__row { flex-wrap: wrap; }
}


/* ===== css/pages/tuto.css ===== */
/* BloxMasters - tutoriel « Premiers pas » (src/js/tuto.js) : fenêtre d'accueil, panneau de la page Paquets,
   bulles d'aide (.bx-tip), encarts en ligne (.bx-tuto-inline). Jetons du cahier §3.1 seulement ; une seule
   entrée animée (bx-rise), aucune lueur, aucune animation en boucle hors de l'indicateur de chargement d'un
   bouton qui attend le serveur ; cibles de 40 px au moins sur téléphone ; aucun texte sous 11 px. Couche des
   bulles : 85 (au-dessus de la barre de sélection de l'album à 80, sous la scène d'ouverture à 140, les
   fenêtres à 150 et les notifications à 160). */

/* ── Fenêtre d'accueil ─────────────────────────────────────────────────────── */
.bx-tuto-welcome .bx-modal__box { width: min(500px, 100%); }
.bx-tuto__welcome { display: grid; justify-items: center; gap: 16px; text-align: center; }
.bx-tuto__pack { width: 140px; margin: 4px 0 2px; }
.bx-tuto__welcome .bx-modal__text { max-width: 420px; }
.bx-tuto__facts { justify-content: center; }
.bx-tuto__note { max-width: 380px; }
.bx-tuto-welcome .bx-modal__btns { justify-content: space-between; }
@media (max-width: 600px) {
  .bx-tuto__welcome { gap: 14px; }
  /* Le bouton principal en haut, pleine largeur ; « Passer le tutoriel » dessous. */
  .bx-tuto-welcome .bx-modal__btns { flex-direction: column-reverse; align-items: stretch; }
  .bx-tuto-welcome .bx-modal__btns > .bx-btn { flex: 0 0 auto; width: 100%; }
}

/* ── Panneau « Premiers pas » (page Paquets, sous la baie) ─────────────────── */
.bx-tuto { margin-top: 14px; }
.bx-tuto.is-loading { display: grid; padding: 4px 0; overflow: hidden; }
.bx-tuto.is-loading .bx-skel--row:last-child { border-bottom: 0; }

.bx-tuto__head { display: flex; align-items: center; gap: 14px; padding: 12px 12px 12px 20px; border-bottom: 1px solid var(--line); }
.bx-tuto__head h3 { margin: 0; white-space: nowrap; }
.bx-tuto__bar { flex: 1 1 auto; max-width: 320px; }
.bx-tuto__more { margin-left: auto; color: var(--ink-3); }

.bx-tuto__list { margin: 0; padding: 0; list-style: none; }
.bx-tuto__step { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; grid-template-areas: "vis txt act";
  align-items: center; gap: 6px 16px; padding: 14px 20px; border-bottom: 1px solid var(--line); }
.bx-tuto__step:last-child { border-bottom: 0; }
.bx-tuto__step.is-claim { background: var(--accent-dim); }

/* Vraies images, dans une case de 48 px : sachet, coffre, cartes (même hauteur pour toutes). */
.bx-tuto__vis { grid-area: vis; display: flex; align-items: center; justify-content: center; width: 48px; height: 48px; }
.bx-tuto__vis > img { width: 100%; height: 100%; object-fit: contain; }
.bx-tuto__obj { display: block; height: 100%; aspect-ratio: 5 / 7; }
.bx-tuto__obj.is-pack { aspect-ratio: 25 / 36; }
/* À cette taille : coins de 4 px, filet seul (sans ombre portée), celui de la rareté pour une carte. */
.bx-tuto__obj > .bxc, .bx-tuto__obj > .bx-pack { width: 100%; border-radius: 4px; box-shadow: inset 0 0 0 1px var(--line-2); }
.bx-tuto__obj > .bxc { box-shadow: inset 0 0 0 1px rgba(var(--rc-rgb), .45); }
/* Carte manquante en silhouette : un peu plus marquée qu'en grand, sinon elle disparaît à cette taille. */
.bx-tuto__obj > .bxc[data-missing] .bxc__win img { opacity: .3; }
/* Pile de trois sachets (étape 6, fin des Premiers pas). */
.bx-tuto__stack { position: relative; display: block; width: 100%; height: 100%; }
.bx-tuto__stack > .bx-tuto__obj { position: absolute; top: 4px; height: calc(100% - 8px); }
.bx-tuto__stack > :nth-child(1) { left: 2px; transform: rotate(-9deg); }
.bx-tuto__stack > :nth-child(2) { left: 50%; translate: -50% 0; z-index: 1; }
.bx-tuto__stack > :nth-child(3) { right: 2px; transform: rotate(9deg); }

.bx-tuto__txt { grid-area: txt; min-width: 0; }
.bx-tuto__t { display: block; font: 700 15px/1.3 var(--font); color: var(--ink); }
.bx-tuto__c { margin: 3px 0 0; font: 500 13px/1.45 var(--font); color: var(--ink-3); }
.bx-tuto__rw { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; }
.bx-tuto__rwnote { font: 500 13px/1.3 var(--font); color: var(--ink-3); }
.bx-tuto__act { grid-area: act; justify-self: end; display: flex; align-items: center; }
.bx-tuto .bx-btn[aria-busy="true"] { opacity: .7; }
.bx-tuto .bx-btn .bx-spin { width: 14px; height: 14px; }
.bx-tuto__ok { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; color: var(--ok); font: 700 13px/1 var(--font); white-space: nowrap; }
.bx-tuto__ok svg { width: 16px; height: 16px; flex: 0 0 16px; }

/* Étape faite et réclamée : une ligne courte, image atténuée, coche « Fait ». */
.bx-tuto__step.is-done { padding-top: 8px; padding-bottom: 8px; }
.bx-tuto__step.is-done .bx-tuto__vis { height: 34px; opacity: .6; }
.bx-tuto__step.is-done .bx-tuto__t { color: var(--ink-3); font-weight: 650; }

/* Téléphone : une ligne repliée sous la baie, qui s'ouvre en liste. */
.bx-tuto__fold > summary { list-style: none; }
.bx-tuto__fold > summary::-webkit-details-marker { display: none; }
.bx-tuto__sum { display: flex; align-items: center; gap: 10px; min-height: 60px; padding: 10px 16px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bx-tuto__sumt { display: grid; gap: 3px; flex: 1 1 auto; min-width: 0; }
.bx-tuto__sumt b { font: 700 15px/1.2 var(--font); color: var(--ink); }
.bx-tuto__sumt b .bx-num { margin-left: 4px; color: var(--accent-2); }
.bx-tuto__next { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 500 13px/1.3 var(--font); color: var(--ink-3); }
.bx-tuto__sum > .bx-badge { flex: 0 0 auto; }
.bx-tuto .bx-tuto__car { width: 16px; height: 16px; flex: 0 0 16px; color: var(--ink-3); transition: transform .2s; }
.bx-tuto__fold[open] .bx-tuto__car { transform: rotate(180deg); }
.bx-tuto__fold > .bx-tuto__bar { max-width: none; margin: 0 16px 6px; }
.bx-tuto__fold[open] > .bx-tuto__list { border-top: 1px solid var(--line); }
.bx-tuto__mfoot { display: flex; justify-content: center; padding: 4px 16px 10px; border-top: 1px solid var(--line); }
.bx-tuto__mfoot .bx-btn { color: var(--ink-3); }

/* Fin des Premiers pas : la récompense, puis trois objectifs et « Masquer ». */
.bx-tuto__end { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; grid-template-areas: "vis txt act"; align-items: center; gap: 8px 16px; padding: 18px 20px; }
.bx-tuto__end h3 { margin: 4px 0 0; }
.bx-tuto__goals { padding: 0 20px 16px; }
.bx-tuto__goalsk { margin: 2px 0 6px; }
.bx-tuto__goals .bx-list { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.bx-tuto__goal { min-height: 52px; }
.bx-tuto__goal .bx-row__title { white-space: normal; font-size: 14px; }
.bx-tuto__goal .bx-tuto__go { width: 16px; height: 16px; flex: 0 0 16px; color: var(--ink-3); }
.bx-tuto__goal.is-done .bx-row__title { color: var(--ink-3); }
.bx-tuto__endfoot { display: flex; justify-content: flex-end; margin-top: 12px; }

@media (max-width: 600px) {
  .bx-tuto__step { grid-template-areas: "vis txt" ". act"; grid-template-columns: 48px minmax(0, 1fr); gap: 10px 12px; padding: 14px 16px; }
  .bx-tuto__act { justify-self: start; }
  .bx-tuto__step.is-done { grid-template-areas: "vis txt act"; grid-template-columns: 48px minmax(0, 1fr) auto; }
  .bx-tuto__step.is-done .bx-tuto__act { justify-self: end; }
  .bx-tuto__end { grid-template-areas: "vis txt" ". act"; grid-template-columns: 48px minmax(0, 1fr); padding: 16px; }
  .bx-tuto__end .bx-tuto__act { justify-self: stretch; }
  .bx-tuto__end .bx-tuto__act .bx-btn { width: 100%; }
  .bx-tuto__goals { padding: 0 16px 14px; }
  .bx-tuto__endfoot .bx-btn { width: 100%; }
}

/* ── Bulles d'aide ─────────────────────────────────────────────────────────── */
.bx-tip { position: fixed; z-index: 85; width: 300px; max-width: calc(100vw - 24px); padding: 14px 14px 10px 16px;
  border-radius: 18px; background: var(--card-2); border: 1px solid var(--accent-line); box-shadow: var(--shadow-pop);
  animation: bx-rise .24s var(--ease-out); }
.bx-tip__caret { position: absolute; top: -7px; left: var(--cx, 50%); width: 12px; height: 12px; margin-left: -6px; transform: rotate(45deg);
  background: var(--card-2); border-top: 1px solid var(--accent-line); border-left: 1px solid var(--accent-line); }
.bx-tip.is-up .bx-tip__caret { top: auto; bottom: -7px; border: 0; border-right: 1px solid var(--accent-line); border-bottom: 1px solid var(--accent-line); }
.bx-tip__x { position: absolute; top: 4px; right: 4px; color: var(--ink-3); }
.bx-tip__k { padding-right: 40px; color: var(--accent-2); }
.bx-tip__p { margin: 8px 0 0; padding-right: 8px; font: 500 14px/1.5 var(--font); color: var(--ink); }
.bx-tip__p .bx-time { color: var(--ink); }
.bx-tip__act { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; margin-top: 12px; }
.bx-tip__skip { display: inline-flex; align-items: center; min-height: 40px; padding: 0 4px; border: 0; background: none;
  color: var(--ink-3); font: 600 13px/1 var(--font); cursor: pointer; }
.bx-tip__skip:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
/* Téléphone : une carte fixe en bas de l'écran. */
.bx-tip.is-sheet { left: 12px; right: 12px; top: auto; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); width: auto; max-width: none; padding: 14px 14px 10px 16px; }
.bx-tip.is-sheet .bx-tip__caret { display: none; }
.bx-tip.is-sheet .bx-tip__act .bx-btn--primary { flex: 1 1 auto; min-height: 44px; }
/* Une notification ne recouvre pas la bulle du bas : elle passe en haut, comme au-dessus d'une feuille. */
body.bx:has(.bx-tip.is-sheet) .bx-toasts { top: 14px; bottom: auto; }
/* Cible mise en avant : un filet de l'accent, sans lueur ni animation. */
body.bx .bx-tip-target { outline: 2px solid var(--accent) !important; outline-offset: 3px; }

/* ── Encarts en ligne (fiche d'une carte, récapitulatif, ligne sous une carte révélée) ── */
.bx-tuto-inline { display: grid; gap: 6px; padding: 12px 14px; border-radius: 14px; background: var(--accent-dim); border: 1px solid var(--accent-line);
  color: var(--ink-2); font: 500 13px/1.45 var(--font); text-align: left; animation: bx-rise .24s var(--ease-out); }
.bx-tuto-inline p { margin: 0; }
.bx-tuto-inline .bx-micro { color: var(--accent-2); }
.bx-tuto-inline.is-card { grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 4px 12px; margin: 18px 0 -6px; }
.bx-tuto-inline.is-card .bx-tuto-inline__txt { display: grid; gap: 5px; }
.bx-tuto-inline.is-op { width: 100%; max-width: 640px; margin: 16px auto 0; }
.bx-tuto-inline.is-line { display: block; max-width: 460px; margin: 10px auto 0; padding: 0; border: 0; background: none; text-align: center; color: var(--ink-2); }
@media (max-width: 600px) {
  .bx-tuto-inline.is-card { grid-template-columns: minmax(0, 1fr); }
  .bx-tuto-inline.is-card .bx-btn { justify-self: start; margin-left: -10px; }
}

/* Mouvement réduit (réglage système et réglage du jeu) : rien ne bouge. */
@media (prefers-reduced-motion: reduce) { .bx-tip, .bx-tuto-inline { animation: none; } }
body.reduce-motion .bx-tip, body.reduce-motion .bx-tuto-inline { animation: none; }
