/* ═══════════════════════════════════════════════════════════════════════════
   KAIROS — DESIGN SYSTEM DARK FANTASY MODERNE
   Interface de jeu de cartes tactique & codex arcanique
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Nuances d'obsidienne & de verre sombre */
  --bg-deep: #06080d;
  --bg: #0a0d14;
  --bg-2: #101522;
  --bg-3: #171e2e;
  --bg-surface: rgba(16, 21, 34, 0.85);
  --bg-glass: rgba(12, 16, 26, 0.78);
  --line: rgba(70, 85, 115, 0.28);
  --line-light: rgba(120, 145, 190, 0.18);
  --line-gold: rgba(245, 185, 66, 0.35);

  /* Typographie & Encre */
  --ink: #f0f4fc;
  --ink-bright: #ffffff;
  --ink-dim: #a4b3cc;
  --ink-faint: #65748f;

  /* La hauteur de la barre du haut. Elle etait recopiee en dur dans quatre
     `calc(100dvh - var(--topbar-h))` : sur mobile la barre se compacte, et les quatre
     copies mentaient toutes en meme temps. */
  --topbar-h: 58px;
  /*  LA BANDE NOIRE QUE CHAQUE RENDU PORTE SUR SES QUATRE COTES.
      `flat_view(margin=1.03)` cadre 3 % plus large que la carte ; le fond est
      transparent au rendu, mais le PNG est ecrit en RGB et la transparence
      s'effondre en noir. Mesure : 1,367 % en largeur, jusqu'a 1,429 % en
      hauteur (les coins arrondis decalent un peu la lecture). On prend le
      maximum -- une fraction de pixel coupee en trop ne se voit pas, une
      bande noire oubliee si. Elle sert au cartable ET a la loupe, d'ou sa
      place ici. */
  --carte-marge: 1.44%;
  /*  ET DE QUOI LUI RENDRE SA TAILLE.
      Rogner seul ne suffit pas : la carte devient plus petite que son
      logement, et c'est la POCHETTE qu'on voit apparaitre autour d'elle --
      un cerne blanc a la place du noir, ce qui ne vaut pas mieux. On la
      repousse donc a ses dimensions d'origine : 1 / (1 - 2 x 1,44 %), soit
      1,0297. Les deux nombres vont ensemble ; changer l'un sans l'autre
      laisse un liseré d'un cote ou de l'autre. */
  --carte-retaille: 1.0297;

  /* Or & Métaux Précieux */
  --accent: #f5b942;
  --accent-light: #ffe89e;
  --accent-dark: #b87f16;
  --gold-grad: linear-gradient(135deg, #fff0b3 0%, #f5b942 50%, #b87f16 100%);
  /* L'OR DU LOGO, le meme que la vitrine (vitrine.css) : le mot KAIROS en
     Cinzel Decorative et son sceau, partout dans le jeu (31/10/2026). */
  --or-metal: linear-gradient(170deg, #fff1bd 0%, #e6bd62 14%, #b0812f 36%, #f0cf7c 52%, #96682a 74%, #d9ae56 92%, #f3d88e 100%);
  --gold-glow: rgba(245, 185, 66, 0.25);

  /* Statuts */
  --ok: #34d399;
  --ok-glow: rgba(52, 211, 153, 0.25);
  --bad: #f87171;
  --bad-glow: rgba(248, 113, 113, 0.25);
  --energy: #38bdf8;

  /* 6 Éléments Sacrés */
  --el-feu: #ff5722;
  --el-feu-glow: rgba(255, 87, 34, 0.38);
  --el-eau: #0284c7;
  --el-eau-glow: rgba(2, 132, 199, 0.38);
  --el-terre: #10b981;
  --el-terre-glow: rgba(16, 185, 129, 0.38);
  /*  L'AIR EST BLANC, PAS BLEU. A #38bdf8 il etait un bleu ciel pose a cote
      du bleu profond de l'Eau : deux elements de la meme couleur sur la Roue,
      et on ne les distinguait qu'a l'icone. Sa teinte canonique, dans
      rules.js, est pale -- base #8CCCF2, accent #E0FAFF. On la suit. */
  --el-air: #e3f3fd;
  --el-air-glow: rgba(214, 238, 252, 0.40);
  --el-ether: #a855f7;
  --el-ether-glow: rgba(168, 85, 247, 0.38);
  --el-lumiere: #f59e0b;
  --el-lumiere-glow: rgba(245, 158, 11, 0.38);

  /* Typographie */
  --font-title: 'Cinzel', serif;
  --font-ornate: 'Cinzel Decorative', serif;
  --font-ui: 'Plus Jakarta Sans', 'Outfit', system-ui, sans-serif;
  --font-num: 'Fraunces', Georgia, serif;
}

* { box-sizing: border-box; }

[hidden] {
  display: none !important;
}

[hidden] { display: none !important; }

/* ── Corps & Fond Vivant ─────────────────────────────────────────────────── */
body {
  margin: 0;
  background-color: var(--bg-deep);
  color: var(--ink);
  font: 14px/1.55 var(--font-ui);
  min-height: 100vh;
  overflow-x: hidden;
  position: relative;
  letter-spacing: 0.01em;
}

/* Fond cosmique arcanique avec halos d'énergie */
.fantasy-bg-fx {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none; overflow: hidden;
  background:
    radial-gradient(1400px 900px at 50% -10%, #151d2e 0%, var(--bg-deep) 75%);
}

.fx-orb {
  position: absolute; border-radius: 50%;
  filter: blur(80px); opacity: 0.16;
  pointer-events: none;
  animation: orbFloat 18s ease-in-out infinite alternate;
}
.fx-orb-1 {
  width: 550px; height: 550px;
  background: radial-gradient(circle, #f5b942 0%, #b87f16 70%, transparent 100%);
  top: -150px; left: 20%;
}
.fx-orb-2 {
  width: 650px; height: 650px;
  background: radial-gradient(circle, #7928ca 0%, #0070f3 60%, transparent 100%);
  bottom: -100px; right: 5%;
  animation-duration: 24s; animation-delay: -6s;
}
.fx-orb-3 {
  width: 480px; height: 480px;
  background: radial-gradient(circle, #059669 0%, #0284c7 60%, transparent 100%);
  top: 40%; left: -120px;
  animation-duration: 20s; animation-delay: -12s;
}
/*  Au doigt, les orbes ne derivent plus. Animees, chacune vivait sur sa
    propre couche GPU, grandie de son flou (1300 px de cote au telephone) :
    123 Mo pour trois lueurs a 7 % d'opacite. Fixes, elles se peignent une
    fois dans le fond, et le telephone garde sa memoire pour ce qu'on voit. */
@media (hover: none), (pointer: coarse) {
  .fx-orb { animation: none; }
}
@keyframes orbFloat {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(40px, 60px) scale(1.12); }
  100% { transform: translate(-30px, -40px) scale(0.95); }
}

/* ══ LE FOND DE L'ACCUEIL EST UN MUR ══════════════════════════════════════
   Le halo cosmique convenait a une salle de jeu, pas a une page qui rappelle
   une loi plus vieille que le joueur. Sur l'accueil, la meme pierre que la
   section des six elements passe derriere TOUT : grand appareil a joints
   decales, use par le bas, avec le grain du calcaire. Les orbes restent,
   mais baissees et rechauffees -- ce n'est plus une nebuleuse, c'est une
   torche loin dans la salle.
   Le mur ne vit que sur l'accueil : `:has` le retire des que la vue change,
   sans toucher au reste de l'interface.
   ════════════════════════════════════════════════════════════════════════ */
body:has(#view-accueil.is-on, #view-menu.is-on) .fantasy-bg-fx {
  background:
    /*  LE SCEAU. A peine grave, a peine visible : six crans, deux anneaux et
        les rayons du cadran, tailles dans la pierre par ceux qui sont partis. */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1000' height='1000'><g fill='none' stroke='rgba(0,0,0,.55)' stroke-width='7'><circle cx='500' cy='500' r='430'/><circle cx='500' cy='500' r='406'/><circle cx='500' cy='500' r='300'/><circle cx='500' cy='500' r='120'/><circle cx='500' cy='135' r='34'/><path d='M500 500 L500 200'/><circle cx='816' cy='318' r='34'/><path d='M500 500 L760 350'/><circle cx='816' cy='682' r='34'/><path d='M500 500 L760 650'/><circle cx='500' cy='865' r='34'/><path d='M500 500 L500 800'/><circle cx='184' cy='682' r='34'/><path d='M500 500 L240 650'/><circle cx='184' cy='318' r='34'/><path d='M500 500 L240 350'/></g><g fill='none' stroke='rgba(255,238,209,.10)' stroke-width='2.5' transform='translate(0,3)'><circle cx='500' cy='500' r='430'/><circle cx='500' cy='500' r='406'/><circle cx='500' cy='500' r='300'/><circle cx='500' cy='500' r='120'/><circle cx='500' cy='135' r='34'/><path d='M500 500 L500 200'/><circle cx='816' cy='318' r='34'/><path d='M500 500 L760 350'/><circle cx='816' cy='682' r='34'/><path d='M500 500 L760 650'/><circle cx='500' cy='865' r='34'/><path d='M500 500 L500 800'/><circle cx='184' cy='682' r='34'/><path d='M500 500 L240 650'/><circle cx='184' cy='318' r='34'/><path d='M500 500 L240 350'/></g></svg>") center 120px / 1100px 1100px no-repeat,
    /*  LE LIERRE. Deux rideaux etroits qui descendent par les bords : le lieu
        n'est plus tenu. Il reste dans les gouttieres, jamais sous le texte. */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='1400' opacity='.62'><path d='M96 -20Q120 49 61 118Q103 190 51 263Q65 332 40 401Q84 461 96 522Q166 578 144 634Q189 691 124 748Q142 816 123 884Q177 966 146 1049Q203 1133 183 1216Q235 1294 203 1373Q273 1440 258 1508' fill='none' stroke='rgb(56,68,34)' stroke-width='2.1' opacity='.45'/><path d='M54 -20Q84 44 54 109Q77 185 62 261Q143 325 128 390Q162 453 102 517Q158 600 166 683Q248 759 226 834Q254 915 214 996Q229 1078 204 1159Q247 1227 222 1295Q284 1352 276 1410' fill='none' stroke='rgb(56,68,34)' stroke-width='3.1' opacity='.45'/><path d='M40 -20Q90 46 60 112Q100 192 72 272Q94 350 39 428Q48 487 10 546Q66 621 79 696Q95 775 49 854Q59 931 14 1007Q95 1072 69 1136Q126 1204 132 1273Q176 1349 131 1425' fill='none' stroke='rgb(56,68,34)' stroke-width='2.8' opacity='.45'/><ellipse cx='66' cy='120' rx='12' ry='7' transform='rotate(99 66 120)' fill='rgb(64,84,38)' opacity='0.60'/><ellipse cx='58' cy='224' rx='15' ry='10' transform='rotate(70 58 224)' fill='rgb(64,84,38)' opacity='0.50'/><ellipse cx='54' cy='430' rx='10' ry='6' transform='rotate(107 54 430)' fill='rgb(52,70,32)' opacity='0.51'/><ellipse cx='61' cy='398' rx='14' ry='9' transform='rotate(80 61 398)' fill='rgb(64,84,38)' opacity='0.56'/><ellipse cx='24' cy='550' rx='11' ry='7' transform='rotate(150 24 550)' fill='rgb(84,100,46)' opacity='0.41'/><ellipse cx='14' cy='530' rx='15' ry='9' transform='rotate(123 14 530)' fill='rgb(64,84,38)' opacity='0.56'/><ellipse cx='103' cy='704' rx='13' ry='8' transform='rotate(128 103 704)' fill='rgb(64,84,38)' opacity='0.49'/><ellipse cx='104' cy='656' rx='9' ry='6' transform='rotate(87 104 656)' fill='rgb(84,100,46)' opacity='0.60'/><ellipse cx='24' cy='826' rx='11' ry='7' transform='rotate(21 24 826)' fill='rgb(84,100,46)' opacity='0.48'/><ellipse cx='14' cy='1022' rx='10' ry='6' transform='rotate(14 14 1022)' fill='rgb(84,100,46)' opacity='0.46'/><ellipse cx='37' cy='1020' rx='10' ry='6' transform='rotate(47 37 1020)' fill='rgb(84,100,46)' opacity='0.31'/><ellipse cx='63' cy='1142' rx='11' ry='7' transform='rotate(156 63 1142)' fill='rgb(84,100,46)' opacity='0.47'/><ellipse cx='75' cy='1147' rx='12' ry='7' transform='rotate(78 75 1147)' fill='rgb(84,100,46)' opacity='0.51'/><ellipse cx='134' cy='1213' rx='11' ry='7' transform='rotate(104 134 1213)' fill='rgb(64,84,38)' opacity='0.41'/><ellipse cx='137' cy='1223' rx='13' ry='8' transform='rotate(60 137 1223)' fill='rgb(52,70,32)' opacity='0.50'/><ellipse cx='135' cy='1437' rx='8' ry='5' transform='rotate(66 135 1437)' fill='rgb(84,100,46)' opacity='0.44'/><ellipse cx='44' cy='77' rx='14' ry='9' transform='rotate(5 44 77)' fill='rgb(84,100,46)' opacity='0.51'/><ellipse cx='35' cy='86' rx='13' ry='8' transform='rotate(48 35 86)' fill='rgb(52,70,32)' opacity='0.36'/><ellipse cx='86' cy='251' rx='10' ry='6' transform='rotate(146 86 251)' fill='rgb(64,84,38)' opacity='0.32'/><ellipse cx='75' cy='217' rx='13' ry='8' transform='rotate(49 75 217)' fill='rgb(64,84,38)' opacity='0.31'/><ellipse cx='147' cy='355' rx='15' ry='9' transform='rotate(15 147 355)' fill='rgb(84,100,46)' opacity='0.40'/><ellipse cx='100' cy='505' rx='10' ry='6' transform='rotate(102 100 505)' fill='rgb(64,84,38)' opacity='0.58'/><ellipse cx='84' cy='457' rx='16' ry='10' transform='rotate(158 84 457)' fill='rgb(84,100,46)' opacity='0.43'/><ellipse cx='184' cy='672' rx='12' ry='8' transform='rotate(52 184 672)' fill='rgb(52,70,32)' opacity='0.57'/><ellipse cx='185' cy='687' rx='16' ry='10' transform='rotate(22 185 687)' fill='rgb(64,84,38)' opacity='0.31'/><ellipse cx='230' cy='775' rx='14' ry='9' transform='rotate(31 230 775)' fill='rgb(52,70,32)' opacity='0.37'/><ellipse cx='201' cy='815' rx='8' ry='5' transform='rotate(164 201 815)' fill='rgb(64,84,38)' opacity='0.40'/><ellipse cx='206' cy='951' rx='12' ry='8' transform='rotate(147 206 951)' fill='rgb(64,84,38)' opacity='0.37'/><ellipse cx='203' cy='1142' rx='11' ry='7' transform='rotate(136 203 1142)' fill='rgb(64,84,38)' opacity='0.38'/><ellipse cx='240' cy='1293' rx='8' ry='5' transform='rotate(9 240 1293)' fill='rgb(52,70,32)' opacity='0.59'/><ellipse cx='258' cy='1355' rx='11' ry='7' transform='rotate(70 258 1355)' fill='rgb(52,70,32)' opacity='0.41'/><ellipse cx='260' cy='1375' rx='9' ry='6' transform='rotate(100 260 1375)' fill='rgb(84,100,46)' opacity='0.52'/><ellipse cx='68' cy='61' rx='15' ry='9' transform='rotate(10 68 61)' fill='rgb(84,100,46)' opacity='0.45'/><ellipse cx='72' cy='89' rx='14' ry='8' transform='rotate(83 72 89)' fill='rgb(64,84,38)' opacity='0.37'/><ellipse cx='47' cy='269' rx='15' ry='10' transform='rotate(67 47 269)' fill='rgb(84,100,46)' opacity='0.54'/><ellipse cx='48' cy='396' rx='13' ry='8' transform='rotate(19 48 396)' fill='rgb(84,100,46)' opacity='0.51'/><ellipse cx='38' cy='359' rx='11' ry='7' transform='rotate(95 38 359)' fill='rgb(84,100,46)' opacity='0.33'/><ellipse cx='72' cy='470' rx='12' ry='7' transform='rotate(125 72 470)' fill='rgb(52,70,32)' opacity='0.47'/><ellipse cx='124' cy='630' rx='15' ry='10' transform='rotate(11 124 630)' fill='rgb(52,70,32)' opacity='0.56'/><ellipse cx='122' cy='741' rx='16' ry='10' transform='rotate(46 122 741)' fill='rgb(84,100,46)' opacity='0.42'/><ellipse cx='147' cy='855' rx='14' ry='9' transform='rotate(29 147 855)' fill='rgb(84,100,46)' opacity='0.47'/><ellipse cx='154' cy='1056' rx='9' ry='6' transform='rotate(17 154 1056)' fill='rgb(84,100,46)' opacity='0.45'/><ellipse cx='164' cy='1212' rx='9' ry='6' transform='rotate(93 164 1212)' fill='rgb(64,84,38)' opacity='0.56'/><ellipse cx='207' cy='1357' rx='16' ry='10' transform='rotate(160 207 1357)' fill='rgb(52,70,32)' opacity='0.31'/><ellipse cx='201' cy='1342' rx='9' ry='6' transform='rotate(65 201 1342)' fill='rgb(52,70,32)' opacity='0.44'/><ellipse cx='256' cy='1511' rx='15' ry='9' transform='rotate(100 256 1511)' fill='rgb(52,70,32)' opacity='0.60'/></svg>") left -40px top -40px no-repeat,
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='1400' opacity='.62'><path d='M47 -20Q32 49 68 117Q16 186 0 254Q-44 310 -47 365Q-98 426 -82 487Q-117 563 -80 639Q-135 700 -90 761Q-149 822 -121 883Q-196 946 -184 1009Q-183 1088 -147 1168Q-218 1238 -206 1309Q-247 1373 -227 1437' fill='none' stroke='rgb(56,68,34)' stroke-width='2.8' opacity='.45'/><path d='M33 -20Q-38 61 -31 143Q-99 202 -99 261Q-119 317 -86 373Q-115 433 -110 492Q-145 569 -123 646Q-139 729 -98 813Q-139 887 -121 961Q-160 1038 -123 1115Q-160 1197 -137 1279Q-175 1341 -152 1403' fill='none' stroke='rgb(56,68,34)' stroke-width='3.3' opacity='.45'/><path d='M77 -20Q32 63 55 145Q17 217 80 288Q82 359 118 429Q75 504 101 578Q77 640 106 702Q56 757 53 812Q9 877 19 942Q-29 1012 8 1081Q-9 1166 4 1251Q-11 1308 12 1365Q-22 1446 -12 1527' fill='none' stroke='rgb(56,68,34)' stroke-width='3.3' opacity='.45'/><ellipse cx='39' cy='124' rx='13' ry='8' transform='rotate(143 39 124)' fill='rgb(64,84,38)' opacity='0.43'/><ellipse cx='85' cy='257' rx='12' ry='7' transform='rotate(133 85 257)' fill='rgb(84,100,46)' opacity='0.35'/><ellipse cx='138' cy='414' rx='14' ry='9' transform='rotate(59 138 414)' fill='rgb(84,100,46)' opacity='0.55'/><ellipse cx='99' cy='539' rx='16' ry='10' transform='rotate(179 99 539)' fill='rgb(64,84,38)' opacity='0.51'/><ellipse cx='110' cy='650' rx='9' ry='5' transform='rotate(52 110 650)' fill='rgb(64,84,38)' opacity='0.59'/><ellipse cx='52' cy='825' rx='11' ry='7' transform='rotate(13 52 825)' fill='rgb(84,100,46)' opacity='0.36'/><ellipse cx='43' cy='939' rx='9' ry='6' transform='rotate(44 43 939)' fill='rgb(64,84,38)' opacity='0.30'/><ellipse cx='5' cy='1035' rx='14' ry='9' transform='rotate(24 5 1035)' fill='rgb(84,100,46)' opacity='0.42'/><ellipse cx='30' cy='1192' rx='9' ry='6' transform='rotate(179 30 1192)' fill='rgb(84,100,46)' opacity='0.49'/><ellipse cx='-17' cy='1265' rx='10' ry='6' transform='rotate(46 -17 1265)' fill='rgb(84,100,46)' opacity='0.40'/><ellipse cx='-14' cy='1333' rx='13' ry='8' transform='rotate(23 -14 1333)' fill='rgb(84,100,46)' opacity='0.45'/><ellipse cx='-21' cy='1484' rx='13' ry='8' transform='rotate(131 -21 1484)' fill='rgb(64,84,38)' opacity='0.52'/><ellipse cx='-55' cy='91' rx='12' ry='8' transform='rotate(46 -55 91)' fill='rgb(84,100,46)' opacity='0.51'/><ellipse cx='-44' cy='145' rx='13' ry='8' transform='rotate(53 -44 145)' fill='rgb(64,84,38)' opacity='0.58'/><ellipse cx='-110' cy='269' rx='10' ry='6' transform='rotate(3 -110 269)' fill='rgb(52,70,32)' opacity='0.42'/><ellipse cx='-107' cy='324' rx='12' ry='7' transform='rotate(60 -107 324)' fill='rgb(84,100,46)' opacity='0.51'/><ellipse cx='-112' cy='459' rx='10' ry='7' transform='rotate(6 -112 459)' fill='rgb(84,100,46)' opacity='0.49'/><ellipse cx='-145' cy='627' rx='14' ry='9' transform='rotate(162 -145 627)' fill='rgb(84,100,46)' opacity='0.52'/><ellipse cx='-88' cy='821' rx='15' ry='9' transform='rotate(75 -88 821)' fill='rgb(64,84,38)' opacity='0.56'/><ellipse cx='-115' cy='907' rx='13' ry='8' transform='rotate(179 -115 907)' fill='rgb(52,70,32)' opacity='0.52'/><ellipse cx='-125' cy='1096' rx='12' ry='8' transform='rotate(93 -125 1096)' fill='rgb(52,70,32)' opacity='0.48'/><ellipse cx='-124' cy='1072' rx='14' ry='8' transform='rotate(90 -124 1072)' fill='rgb(84,100,46)' opacity='0.50'/><ellipse cx='-128' cy='1234' rx='9' ry='6' transform='rotate(163 -128 1234)' fill='rgb(84,100,46)' opacity='0.58'/><ellipse cx='-167' cy='1376' rx='14' ry='9' transform='rotate(165 -167 1376)' fill='rgb(64,84,38)' opacity='0.42'/><ellipse cx='-147' cy='1367' rx='9' ry='6' transform='rotate(89 -147 1367)' fill='rgb(64,84,38)' opacity='0.51'/><ellipse cx='86' cy='86' rx='12' ry='8' transform='rotate(121 86 86)' fill='rgb(84,100,46)' opacity='0.55'/><ellipse cx='-11' cy='240' rx='13' ry='8' transform='rotate(51 -11 240)' fill='rgb(52,70,32)' opacity='0.39'/><ellipse cx='-63' cy='363' rx='10' ry='6' transform='rotate(140 -63 363)' fill='rgb(64,84,38)' opacity='0.60'/><ellipse cx='-67' cy='314' rx='12' ry='8' transform='rotate(115 -67 314)' fill='rgb(52,70,32)' opacity='0.59'/><ellipse cx='-71' cy='484' rx='12' ry='8' transform='rotate(7 -71 484)' fill='rgb(64,84,38)' opacity='0.38'/><ellipse cx='-86' cy='639' rx='15' ry='9' transform='rotate(16 -86 639)' fill='rgb(84,100,46)' opacity='0.42'/><ellipse cx='-96' cy='744' rx='15' ry='9' transform='rotate(143 -96 744)' fill='rgb(52,70,32)' opacity='0.44'/><ellipse cx='-136' cy='891' rx='16' ry='10' transform='rotate(176 -136 891)' fill='rgb(84,100,46)' opacity='0.59'/><ellipse cx='-192' cy='955' rx='12' ry='7' transform='rotate(99 -192 955)' fill='rgb(52,70,32)' opacity='0.45'/><ellipse cx='-164' cy='1133' rx='14' ry='9' transform='rotate(25 -164 1133)' fill='rgb(64,84,38)' opacity='0.60'/><ellipse cx='-183' cy='1286' rx='16' ry='10' transform='rotate(15 -183 1286)' fill='rgb(64,84,38)' opacity='0.43'/><ellipse cx='-203' cy='1311' rx='12' ry='8' transform='rotate(30 -203 1311)' fill='rgb(84,100,46)' opacity='0.55'/><ellipse cx='-238' cy='1388' rx='12' ry='8' transform='rotate(49 -238 1388)' fill='rgb(52,70,32)' opacity='0.36'/></svg>") right -50px top 180px no-repeat,
    /*  LA <svg xmlns='http://www.w3.org/2000/svg' width='800' height='480' opacity='.42'><defs><filter id='b' x='-40%' y='-40%' width='180%' height='180%'><feGaussianBlur stdDeviation='4'/></filter></defs><g filter='url(%23b)'><ellipse cx='132' cy='3' rx='24' ry='8' fill='rgb(58,76,34)' opacity='0.62'/><ellipse cx='380' cy='-4' rx='29' ry='7' fill='rgb(92,106,52)' opacity='0.30'/><ellipse cx='297' cy='-6' rx='22' ry='8' fill='rgb(74,92,40)' opacity='0.52'/><ellipse cx='349' cy='5' rx='30' ry='9' fill='rgb(58,76,34)' opacity='0.31'/><ellipse cx='263' cy='-5' rx='20' ry='4' fill='rgb(58,76,34)' opacity='0.54'/><ellipse cx='71' cy='-7' rx='26' ry='8' fill='rgb(74,92,40)' opacity='0.41'/><ellipse cx='388' cy='-6' rx='14' ry='3' fill='rgb(74,92,40)' opacity='0.36'/><ellipse cx='539' cy='4' rx='26' ry='10' fill='rgb(92,106,52)' opacity='0.32'/><ellipse cx='448' cy='-1' rx='21' ry='8' fill='rgb(58,76,34)' opacity='0.58'/><ellipse cx='328' cy='120' rx='17' ry='4' fill='rgb(58,76,34)' opacity='0.46'/><ellipse cx='213' cy='116' rx='27' ry='10' fill='rgb(92,106,52)' opacity='0.46'/><ellipse cx='393' cy='125' rx='21' ry='6' fill='rgb(74,92,40)' opacity='0.40'/><ellipse cx='784' cy='124' rx='12' ry='3' fill='rgb(92,106,52)' opacity='0.60'/><ellipse cx='277' cy='118' rx='22' ry='5' fill='rgb(74,92,40)' opacity='0.60'/><ellipse cx='139' cy='116' rx='19' ry='6' fill='rgb(74,92,40)' opacity='0.59'/><ellipse cx='767' cy='129' rx='18' ry='6' fill='rgb(92,106,52)' opacity='0.58'/><ellipse cx='393' cy='117' rx='18' ry='4' fill='rgb(74,92,40)' opacity='0.32'/><ellipse cx='644' cy='121' rx='25' ry='5' fill='rgb(58,76,34)' opacity='0.38'/><ellipse cx='232' cy='236' rx='18' ry='7' fill='rgb(74,92,40)' opacity='0.51'/><ellipse cx='117' cy='245' rx='13' ry='3' fill='rgb(74,92,40)' opacity='0.61'/><ellipse cx='421' cy='233' rx='25' ry='9' fill='rgb(74,92,40)' opacity='0.42'/><ellipse cx='123' cy='245' rx='17' ry='5' fill='rgb(58,76,34)' opacity='0.57'/><ellipse cx='246' cy='237' rx='21' ry='4' fill='rgb(92,106,52)' opacity='0.52'/><ellipse cx='763' cy='242' rx='10' ry='3' fill='rgb(92,106,52)' opacity='0.61'/><ellipse cx='337' cy='245' rx='24' ry='5' fill='rgb(74,92,40)' opacity='0.33'/><ellipse cx='75' cy='240' rx='11' ry='2' fill='rgb(74,92,40)' opacity='0.34'/><ellipse cx='225' cy='248' rx='16' ry='5' fill='rgb(58,76,34)' opacity='0.37'/><ellipse cx='133' cy='359' rx='14' ry='5' fill='rgb(92,106,52)' opacity='0.54'/><ellipse cx='483' cy='365' rx='20' ry='7' fill='rgb(74,92,40)' opacity='0.30'/><ellipse cx='371' cy='365' rx='11' ry='4' fill='rgb(74,92,40)' opacity='0.37'/><ellipse cx='771' cy='365' rx='22' ry='6' fill='rgb(74,92,40)' opacity='0.40'/><ellipse cx='721' cy='361' rx='16' ry='5' fill='rgb(92,106,52)' opacity='0.48'/><ellipse cx='436' cy='363' rx='11' ry='4' fill='rgb(58,76,34)' opacity='0.40'/><ellipse cx='560' cy='362' rx='21' ry='6' fill='rgb(74,92,40)' opacity='0.40'/><ellipse cx='161' cy='364' rx='11' ry='2' fill='rgb(58,76,34)' opacity='0.32'/><ellipse cx='59' cy='365' rx='26' ry='8' fill='rgb(58,76,34)' opacity='0.60'/><ellipse cx='544' cy='481' rx='24' ry='7' fill='rgb(92,106,52)' opacity='0.43'/><ellipse cx='180' cy='480' rx='11' ry='3' fill='rgb(74,92,40)' opacity='0.49'/><ellipse cx='324' cy='486' rx='19' ry='5' fill='rgb(58,76,34)' opacity='0.46'/><ellipse cx='505' cy='474' rx='29' ry='7' fill='rgb(58,76,34)' opacity='0.42'/><ellipse cx='484' cy='480' rx='14' ry='5' fill='rgb(92,106,52)' opacity='0.51'/><ellipse cx='687' cy='484' rx='24' ry='7' fill='rgb(74,92,40)' opacity='0.46'/><ellipse cx='245' cy='481' rx='18' ry='7' fill='rgb(92,106,52)' opacity='0.30'/><ellipse cx='250' cy='479' rx='16' ry='4' fill='rgb(74,92,40)' opacity='0.36'/><ellipse cx='418' cy='479' rx='22' ry='6' fill='rgb(92,106,52)' opacity='0.33'/></g></svg>. Elle pousse dans les joints, jamais au milieu d'une pierre :
        c'est ce detail qui separe un mur sale d'un mur abandonne. Et elle
        reste basse -- elle souligne l'appareil, elle ne le noie pas. */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='480' opacity='.42'><defs><filter id='b' x='-40%' y='-40%' width='180%' height='180%'><feGaussianBlur stdDeviation='4'/></filter></defs><g filter='url(%23b)'><ellipse cx='132' cy='3' rx='24' ry='8' fill='rgb(58,76,34)' opacity='0.62'/><ellipse cx='380' cy='-4' rx='29' ry='7' fill='rgb(92,106,52)' opacity='0.30'/><ellipse cx='297' cy='-6' rx='22' ry='8' fill='rgb(74,92,40)' opacity='0.52'/><ellipse cx='349' cy='5' rx='30' ry='9' fill='rgb(58,76,34)' opacity='0.31'/><ellipse cx='263' cy='-5' rx='20' ry='4' fill='rgb(58,76,34)' opacity='0.54'/><ellipse cx='71' cy='-7' rx='26' ry='8' fill='rgb(74,92,40)' opacity='0.41'/><ellipse cx='388' cy='-6' rx='14' ry='3' fill='rgb(74,92,40)' opacity='0.36'/><ellipse cx='539' cy='4' rx='26' ry='10' fill='rgb(92,106,52)' opacity='0.32'/><ellipse cx='448' cy='-1' rx='21' ry='8' fill='rgb(58,76,34)' opacity='0.58'/><ellipse cx='328' cy='120' rx='17' ry='4' fill='rgb(58,76,34)' opacity='0.46'/><ellipse cx='213' cy='116' rx='27' ry='10' fill='rgb(92,106,52)' opacity='0.46'/><ellipse cx='393' cy='125' rx='21' ry='6' fill='rgb(74,92,40)' opacity='0.40'/><ellipse cx='784' cy='124' rx='12' ry='3' fill='rgb(92,106,52)' opacity='0.60'/><ellipse cx='277' cy='118' rx='22' ry='5' fill='rgb(74,92,40)' opacity='0.60'/><ellipse cx='139' cy='116' rx='19' ry='6' fill='rgb(74,92,40)' opacity='0.59'/><ellipse cx='767' cy='129' rx='18' ry='6' fill='rgb(92,106,52)' opacity='0.58'/><ellipse cx='393' cy='117' rx='18' ry='4' fill='rgb(74,92,40)' opacity='0.32'/><ellipse cx='644' cy='121' rx='25' ry='5' fill='rgb(58,76,34)' opacity='0.38'/><ellipse cx='232' cy='236' rx='18' ry='7' fill='rgb(74,92,40)' opacity='0.51'/><ellipse cx='117' cy='245' rx='13' ry='3' fill='rgb(74,92,40)' opacity='0.61'/><ellipse cx='421' cy='233' rx='25' ry='9' fill='rgb(74,92,40)' opacity='0.42'/><ellipse cx='123' cy='245' rx='17' ry='5' fill='rgb(58,76,34)' opacity='0.57'/><ellipse cx='246' cy='237' rx='21' ry='4' fill='rgb(92,106,52)' opacity='0.52'/><ellipse cx='763' cy='242' rx='10' ry='3' fill='rgb(92,106,52)' opacity='0.61'/><ellipse cx='337' cy='245' rx='24' ry='5' fill='rgb(74,92,40)' opacity='0.33'/><ellipse cx='75' cy='240' rx='11' ry='2' fill='rgb(74,92,40)' opacity='0.34'/><ellipse cx='225' cy='248' rx='16' ry='5' fill='rgb(58,76,34)' opacity='0.37'/><ellipse cx='133' cy='359' rx='14' ry='5' fill='rgb(92,106,52)' opacity='0.54'/><ellipse cx='483' cy='365' rx='20' ry='7' fill='rgb(74,92,40)' opacity='0.30'/><ellipse cx='371' cy='365' rx='11' ry='4' fill='rgb(74,92,40)' opacity='0.37'/><ellipse cx='771' cy='365' rx='22' ry='6' fill='rgb(74,92,40)' opacity='0.40'/><ellipse cx='721' cy='361' rx='16' ry='5' fill='rgb(92,106,52)' opacity='0.48'/><ellipse cx='436' cy='363' rx='11' ry='4' fill='rgb(58,76,34)' opacity='0.40'/><ellipse cx='560' cy='362' rx='21' ry='6' fill='rgb(74,92,40)' opacity='0.40'/><ellipse cx='161' cy='364' rx='11' ry='2' fill='rgb(58,76,34)' opacity='0.32'/><ellipse cx='59' cy='365' rx='26' ry='8' fill='rgb(58,76,34)' opacity='0.60'/><ellipse cx='544' cy='481' rx='24' ry='7' fill='rgb(92,106,52)' opacity='0.43'/><ellipse cx='180' cy='480' rx='11' ry='3' fill='rgb(74,92,40)' opacity='0.49'/><ellipse cx='324' cy='486' rx='19' ry='5' fill='rgb(58,76,34)' opacity='0.46'/><ellipse cx='505' cy='474' rx='29' ry='7' fill='rgb(58,76,34)' opacity='0.42'/><ellipse cx='484' cy='480' rx='14' ry='5' fill='rgb(92,106,52)' opacity='0.51'/><ellipse cx='687' cy='484' rx='24' ry='7' fill='rgb(74,92,40)' opacity='0.46'/><ellipse cx='245' cy='481' rx='18' ry='7' fill='rgb(92,106,52)' opacity='0.30'/><ellipse cx='250' cy='479' rx='16' ry='4' fill='rgb(74,92,40)' opacity='0.36'/><ellipse cx='418' cy='479' rx='22' ry='6' fill='rgb(92,106,52)' opacity='0.33'/></g></svg>"),
    /*  LE LIT DE PIERRE. Blocs de largeurs inegales, joints qui tremblent,
        eclats aux aretes, fissures, et chaque pierre sa propre teinte. */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='480'><rect x='0' y='0' width='120' height='120' fill='rgba(255,240,214,0.042)'/><rect x='120' y='0' width='240' height='120' fill='rgba(255,240,214,0.001)'/><rect x='360' y='0' width='150' height='120' fill='rgba(255,240,214,0.031)'/><rect x='510' y='0' width='150' height='120' fill='rgba(255,240,214,0.010)'/><rect x='660' y='0' width='140' height='120' fill='rgba(0,0,0,0.050)'/><rect x='0' y='120' width='150' height='120' fill='rgba(0,0,0,0.045)'/><rect x='150' y='120' width='180' height='120' fill='rgba(0,0,0,0.043)'/><rect x='330' y='120' width='180' height='120' fill='rgba(0,0,0,0.029)'/><rect x='510' y='120' width='180' height='120' fill='rgba(0,0,0,0.028)'/><rect x='690' y='120' width='110' height='120' fill='rgba(255,240,214,0.030)'/><rect x='0' y='240' width='130' height='120' fill='rgba(255,240,214,0.024)'/><rect x='130' y='240' width='240' height='120' fill='rgba(0,0,0,0.040)'/><rect x='370' y='240' width='240' height='120' fill='rgba(0,0,0,0.023)'/><rect x='610' y='240' width='150' height='120' fill='rgba(255,240,214,0.030)'/><rect x='760' y='240' width='40' height='120' fill='rgba(0,0,0,0.057)'/><rect x='0' y='360' width='180' height='120' fill='rgba(255,240,214,0.028)'/><rect x='180' y='360' width='180' height='120' fill='rgba(0,0,0,0.063)'/><rect x='360' y='360' width='260' height='120' fill='rgba(255,240,214,0.048)'/><rect x='620' y='360' width='180' height='120' fill='rgba(0,0,0,0.060)'/><g fill='none' stroke='rgba(0,0,0,.62)' stroke-width='4'><path d='M0.0 120.0 L77.9 120.4 L162.1 118.5 L237.8 119.6 L318.7 120.3 L397.7 120.3 L482.3 120.7 L560.4 117.7 L640.4 117.7 L718.5 120.3 L800.0 120.0'/><path d='M120.0 2.0 L118.5 24.9 L120.2 48.7 L120.2 72.3 L118.4 95.1 L120.0 118.0'/><path d='M360.0 2.0 L358.8 23.6 L360.8 48.7 L360.5 71.6 L360.1 95.9 L360.0 118.0'/><path d='M510.0 2.0 L509.9 26.9 L509.4 47.4 L508.7 72.7 L508.3 94.0 L510.0 118.0'/><path d='M660.0 2.0 L660.0 24.6 L659.8 48.8 L658.3 71.6 L658.7 94.2 L660.0 118.0'/><path d='M0.0 240.0 L77.5 241.7 L158.3 238.9 L238.2 240.2 L320.6 239.1 L398.1 241.9 L482.3 240.8 L561.2 239.8 L641.9 242.3 L720.9 240.3 L800.0 240.0'/><path d='M150.0 122.0 L149.6 144.8 L149.9 168.0 L148.8 193.5 L149.8 213.2 L150.0 238.0'/><path d='M330.0 122.0 L330.4 143.6 L330.3 168.5 L331.8 192.1 L328.3 213.6 L330.0 238.0'/><path d='M510.0 122.0 L509.5 145.7 L511.8 168.8 L509.9 190.1 L510.0 216.7 L510.0 238.0'/><path d='M690.0 122.0 L689.9 144.4 L688.6 169.4 L691.0 191.5 L690.8 214.9 L690.0 238.0'/><path d='M0.0 360.0 L78.3 358.1 L158.2 362.1 L241.6 358.2 L321.7 362.5 L400.8 359.2 L480.3 358.1 L557.5 362.4 L640.8 360.1 L722.3 359.7 L800.0 360.0'/><path d='M130.0 242.0 L131.5 266.5 L128.8 287.4 L129.2 310.6 L130.3 333.8 L130.0 358.0'/><path d='M370.0 242.0 L369.7 263.7 L371.6 287.8 L369.8 311.9 L371.6 334.5 L370.0 358.0'/><path d='M610.0 242.0 L611.7 265.2 L610.1 288.5 L608.1 311.4 L608.7 332.8 L610.0 358.0'/><path d='M760.0 242.0 L761.2 263.9 L759.9 289.3 L760.2 310.9 L760.1 335.0 L760.0 358.0'/><path d='M0.0 480.0 L80.4 481.0 L157.9 477.7 L241.0 479.6 L317.8 482.3 L400.7 481.6 L477.8 481.9 L557.7 481.9 L639.8 479.2 L720.3 482.2 L800.0 480.0'/><path d='M180.0 362.0 L179.1 383.7 L180.1 407.4 L178.4 430.2 L178.2 453.6 L180.0 478.0'/><path d='M360.0 362.0 L359.2 384.4 L361.0 407.6 L360.0 430.3 L359.4 452.9 L360.0 478.0'/><path d='M620.0 362.0 L619.0 383.3 L620.9 408.6 L618.8 431.5 L621.7 453.2 L620.0 478.0'/></g><g fill='none' stroke='rgba(255,238,209,.09)' stroke-width='2' transform='translate(1,3)'><path d='M0.0 120.0 L77.9 120.4 L162.1 118.5 L237.8 119.6 L318.7 120.3 L397.7 120.3 L482.3 120.7 L560.4 117.7 L640.4 117.7 L718.5 120.3 L800.0 120.0'/><path d='M120.0 2.0 L118.5 24.9 L120.2 48.7 L120.2 72.3 L118.4 95.1 L120.0 118.0'/><path d='M360.0 2.0 L358.8 23.6 L360.8 48.7 L360.5 71.6 L360.1 95.9 L360.0 118.0'/><path d='M510.0 2.0 L509.9 26.9 L509.4 47.4 L508.7 72.7 L508.3 94.0 L510.0 118.0'/><path d='M660.0 2.0 L660.0 24.6 L659.8 48.8 L658.3 71.6 L658.7 94.2 L660.0 118.0'/><path d='M0.0 240.0 L77.5 241.7 L158.3 238.9 L238.2 240.2 L320.6 239.1 L398.1 241.9 L482.3 240.8 L561.2 239.8 L641.9 242.3 L720.9 240.3 L800.0 240.0'/><path d='M150.0 122.0 L149.6 144.8 L149.9 168.0 L148.8 193.5 L149.8 213.2 L150.0 238.0'/><path d='M330.0 122.0 L330.4 143.6 L330.3 168.5 L331.8 192.1 L328.3 213.6 L330.0 238.0'/><path d='M510.0 122.0 L509.5 145.7 L511.8 168.8 L509.9 190.1 L510.0 216.7 L510.0 238.0'/><path d='M690.0 122.0 L689.9 144.4 L688.6 169.4 L691.0 191.5 L690.8 214.9 L690.0 238.0'/><path d='M0.0 360.0 L78.3 358.1 L158.2 362.1 L241.6 358.2 L321.7 362.5 L400.8 359.2 L480.3 358.1 L557.5 362.4 L640.8 360.1 L722.3 359.7 L800.0 360.0'/><path d='M130.0 242.0 L131.5 266.5 L128.8 287.4 L129.2 310.6 L130.3 333.8 L130.0 358.0'/><path d='M370.0 242.0 L369.7 263.7 L371.6 287.8 L369.8 311.9 L371.6 334.5 L370.0 358.0'/><path d='M610.0 242.0 L611.7 265.2 L610.1 288.5 L608.1 311.4 L608.7 332.8 L610.0 358.0'/><path d='M760.0 242.0 L761.2 263.9 L759.9 289.3 L760.2 310.9 L760.1 335.0 L760.0 358.0'/><path d='M0.0 480.0 L80.4 481.0 L157.9 477.7 L241.0 479.6 L317.8 482.3 L400.7 481.6 L477.8 481.9 L557.7 481.9 L639.8 479.2 L720.3 482.2 L800.0 480.0'/><path d='M180.0 362.0 L179.1 383.7 L180.1 407.4 L178.4 430.2 L178.2 453.6 L180.0 478.0'/><path d='M360.0 362.0 L359.2 384.4 L361.0 407.6 L360.0 430.3 L359.4 452.9 L360.0 478.0'/><path d='M620.0 362.0 L619.0 383.3 L620.9 408.6 L618.8 431.5 L621.7 453.2 L620.0 478.0'/></g><path d='M96 4 l22 1 l8 10 Z' fill='rgba(0,0,0,.34)'/><path d='M603 114 l14 -2 l5 7 Z' fill='rgba(0,0,0,.34)'/><path d='M673 114 l11 -5 l0 15 Z' fill='rgba(0,0,0,.34)'/><path d='M720.4 64.9 L730.3 76.8 L735.3 90.5 L745.7 107.3 L751.1 117.7' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M89.0 221.4 L95.0 226.9 L101.4 237.5 L106.9 244.5 L109.7 253.3' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M233 124 l19 5 l6 9 Z' fill='rgba(0,0,0,.34)'/><path d='M222.1 210.3 L217.5 223.2 L211.8 230.0 L202.2 240.7 L198.1 250.0' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M543.3 177.0 L542.9 187.5 L533.8 199.1 L532.6 207.3 L530.3 216.3' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M729 124 l17 -6 l7 10 Z' fill='rgba(0,0,0,.34)'/><path d='M64 244 l12 -8 l-4 11 Z' fill='rgba(0,0,0,.34)'/><path d='M91.5 256.3 L88.7 269.3 L83.2 285.9 L82.9 300.6 L77.6 315.3' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M323 354 l25 7 l-3 11 Z' fill='rgba(0,0,0,.34)'/><path d='M520 354 l10 3 l7 15 Z' fill='rgba(0,0,0,.34)'/><path d='M526.1 316.0 L521.7 328.2 L514.5 343.1 L504.6 360.4 L497.5 371.3' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M670 354 l15 -5 l-1 13 Z' fill='rgba(0,0,0,.34)'/><path d='M685.4 294.0 L676.5 302.4 L663.5 313.6 L658.2 321.8 L646.9 327.3' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M767 244 l14 -7 l1 15 Z' fill='rgba(0,0,0,.34)'/><path d='M82 474 l25 -3 l-3 9 Z' fill='rgba(0,0,0,.34)'/><path d='M134.7 442.9 L130.3 459.8 L117.3 473.4 L115.3 487.2 L105.8 502.5' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M265.8 467.1 L265.0 477.1 L268.3 488.0 L270.9 501.8 L273.7 514.8' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/><path d='M374 474 l13 -6 l-1 8 Z' fill='rgba(0,0,0,.34)'/><path d='M517.8 394.8 L525.2 398.6 L529.3 406.0 L533.1 413.3 L539.9 418.5' fill='none' stroke='rgba(0,0,0,.30)' stroke-width='2'/></svg>"),
    radial-gradient(ellipse 34% 26% at 10% 64%, rgba(44, 56, 28, .22), transparent 72%),
    radial-gradient(ellipse 26% 34% at 94% 28%, rgba(42, 52, 28, .18), transparent 74%),
    radial-gradient(ellipse 90% 60% at 50% -10%, rgba(150, 128, 96, .30), transparent 70%),
    radial-gradient(ellipse 70% 50% at 88% 78%, rgba(104, 90, 70, .22), transparent 74%),
    linear-gradient(172deg, #423a2e 0%, #2f2921 46%, #1b1814 100%);
  background-size:
    1100px 1100px, 340px 1400px, 340px 1400px,
    800px 480px, 800px 480px, auto, auto, auto, auto, auto;
}
/*  L'ANCIEN MUR NE SE MONTRE PLUS. Le mur dessine ci-dessus (sceau, lierre,
    pierres) apparaissait le temps que `fonds/mur_ancien.jpg` charge : on
    voyait l'ancien fond au lancement. Dessous, il ne reste qu'un fond uni. */
body:has(#view-accueil.is-on, #view-menu.is-on) .fantasy-bg-fx {
  background: #1b1814;
}
/* Le grain du calcaire, puis l'usure : les bords et le bas sont manges. */
body:has(#view-accueil.is-on, #view-menu.is-on) .fantasy-bg-fx::before,
body:has(#view-accueil.is-on, #view-menu.is-on) .fantasy-bg-fx::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
}
body:has(#view-accueil.is-on, #view-menu.is-on) .fantasy-bg-fx::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='260'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/></filter><rect width='260' height='260' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay; opacity: .7;
}
body:has(#view-accueil.is-on, #view-menu.is-on) .fantasy-bg-fx::after {
  z-index: 2;
  background:
    radial-gradient(ellipse 140% 110% at 50% 34%, transparent 62%, rgba(0, 0, 0, .45) 100%),
    linear-gradient(0deg, rgba(0, 0, 0, .34), transparent 26%);
}
/* Les orbes deviennent une lueur de torche : basses, chaudes, lointaines. */
body:has(#view-accueil.is-on, #view-menu.is-on) .fx-orb { opacity: .07; filter: blur(110px); }

/*  LE MUR PEINT.
    Un mur dessine en gradients reste un mur dessine en gradients : il n'a ni
    la mousse qui deborde, ni les racines, ni la fatigue d'une vraie pierre.
    Des qu'une image est posee dans `fonds/`, elle passe devant le mur CSS --
    qui reste dessous, intact, comme filet. L'image est FIXE : la page glisse
    devant le mur, le mur ne bouge pas. C'est ce qui donne l'impression
    d'etre dans la salle plutot que de faire defiler une affiche. */
.mur-photo { display: none; }
body:has(#view-accueil.is-on, #view-menu.is-on) .mur-photo {
  display: block; position: absolute; inset: 0;
  /*  L'image est tres haute (1280 x 3017) : en `cover` sur un ecran large,
      on en voit une tranche. On la cale au centre, la ou la gravure est la
      plus dense -- la canopee du haut et le sol du bas sortent du cadre. */
  background: url('https://medias.kairostcg.com/fonds/mur_ancien.jpg') center center / cover no-repeat;
  filter: brightness(1.10) saturate(1.06);
}
/*  On assombrit et on rechauffe : brute, la photo mange le texte. Le voile
    des panneaux fait le reste. */
body:has(#view-accueil.is-on, #view-menu.is-on) .mur-photo ~ .mur-glyphe { display: none; }
/*  LA POUSSIERE. Des grains et quelques braises qui flottent devant le mur,
    sous le voile de l'::after. Rien ailleurs que sur l'accueil. */
.poussiere-accueil { display: none; }
body:has(#view-accueil.is-on, #view-menu.is-on) .poussiere-accueil {
  display: block; position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
}
/* Les panneaux passent devant la poussiere : elle ne vit que dans le fond. */
body:has(#view-accueil.is-on, #view-menu.is-on) main { position: relative; z-index: 1; }@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) body:has(#view-accueil.is-on, #view-menu.is-on) .poussiere-accueil { display: none; }
}
body:has(#view-accueil.is-on, #view-menu.is-on) .mur-photo::after {
  content: ''; position: absolute; inset: 0;
  background:
    /*  Depuis que le mur est en cell-shading, le voile chaud d'avant le
        brunissait : la pierre grise virait au sepia et les verts plats
        mouraient. On garde l'assombrissement, on retire presque toute la
        teinte. */
    radial-gradient(ellipse 125% 95% at 50% 34%, rgba(0, 0, 0, .16) 0%, rgba(0, 0, 0, .50) 100%),
    linear-gradient(172deg, rgba(30, 24, 14, .06), rgba(0, 0, 0, .22));
}


/*  LES SIX SIGNES GRAVES DANS LE MUR.
    Pas un decor : les vraies icones du jeu, celles des cartes et du cadran.
    Elles ont la couleur de la pierre, et deux ombres opposees -- sombre en
    haut, claire en bas -- leur creusent le trait. L'usure vient du flou et
    de l'opacite basse : on les devine plus qu'on ne les lit, comme une
    gravure que six siecles ont presque effacee.
    Elles vivent dans les gouttieres, jamais derriere un texte. */
.mur-glyphe { display: none; }
body:has(#view-accueil.is-on, #view-menu.is-on) .mur-glyphe {
  display: block; position: absolute;
  left: var(--gx); top: var(--gy);
  width: var(--gs); height: var(--gs);
  transform: translate(-50%, -50%) rotate(var(--gr));
  background: #6d6351;
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
  filter:
    drop-shadow(0 -3px 0 rgba(0, 0, 0, .9))
    drop-shadow(0 3px 1px rgba(255, 238, 209, .16))
    blur(.7px);
  opacity: var(--go);
  mix-blend-mode: soft-light;
}
/*  Sous 1100px les gouttieres disparaissent : la gravure passerait derriere
    le texte. On l'efface presque plutot que de la laisser gener. */
@media (max-width: 1100px) { body:has(#view-accueil.is-on, #view-menu.is-on) .mur-glyphe { opacity: calc(var(--go) * .4); } }

body:has(#view-accueil.is-on) .fx-orb-2,
body:has(#view-accueil.is-on) .fx-orb-3 {
  background: radial-gradient(circle, #c98b3a 0%, #6d4a17 62%, transparent 100%);
}

/*  LES PANNEAUX DEVIENNENT UN VOILE, PAS UNE PLAQUE.
    Le mur ne sert a rien si six caissons opaques le recouvrent : on ne le
    voyait que dans les gouttieres. Sur l'accueil seulement, chaque bloc
    perd ses fonds bleus et devient une gaze sombre et chaude -- la pierre
    et ses joints se lisent au travers, le texte reste net grace au flou
    d'arriere-plan. Les bordures d'or, elles, ne bougent pas. */
body:has(#view-accueil.is-on) .home-hero,
body:has(#view-accueil.is-on) .home-roue,
body:has(#view-accueil.is-on) .home-codex,
body:has(#view-accueil.is-on) .home-booster-altar,
body:has(#view-accueil.is-on) .home-regles,
body:has(#view-accueil.is-on) .home-stats-wrap,
body:has(#view-accueil.is-on) .home-deck-pedestal {
  background-image:
    radial-gradient(ellipse 70% 60% at 14% 22%, rgba(245, 185, 66, .10), transparent 70%),
    linear-gradient(172deg, rgba(16, 13, 10, .60) 0%, rgba(7, 6, 5, .82) 100%);
  backdrop-filter: blur(3px) saturate(.92);
}

/* ── Éléments de formulaire & Boutons Universels ──────────────────────────── */
button, input, select {
  font-family: inherit; color: inherit;
}

button {
  background: linear-gradient(180deg, #182030 0%, #101624 100%);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 16px;
  cursor: pointer;
  font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: all .2s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
button:hover:not(:disabled) {
  background: linear-gradient(180deg, #222d42 0%, #151d2f 100%);
  border-color: rgba(245, 185, 66, 0.45);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45), 0 0 10px rgba(245, 185, 66, 0.15);
  transform: translateY(-1px);
}
button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
button:disabled { opacity: 0.45; cursor: not-allowed; }

button.primary, .btn-gilded {
  background: var(--gold-grad);
  color: #1a1202 !important;
  border-color: #ffd773 !important;
  font-weight: 750;
  letter-spacing: 0.03em;
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.4);
  box-shadow: 0 4px 14px rgba(245, 185, 66, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
button.primary:hover:not(:disabled), .btn-gilded:hover:not(:disabled) {
  background: linear-gradient(135deg, #fff5cc 0%, #ffc759 50%, #cc8e19 100%);
  box-shadow: 0 6px 20px rgba(245, 185, 66, 0.55), inset 0 1px 0 #fff;
  transform: translateY(-2px);
}

.btn-arcane {
  background: linear-gradient(180deg, #261f3d 0%, #171326 100%);
  border-color: rgba(168, 85, 247, 0.4);
  color: #e9d5ff;
}
.btn-arcane:hover:not(:disabled) {
  border-color: #c084fc;
  box-shadow: 0 0 16px rgba(168, 85, 247, 0.35);
}

.btn-heroic {
  background: linear-gradient(135deg, #059669 0%, #10b981 50%, #047857 100%) !important;
  color: #fff !important;
  border-color: #6ee7b7 !important;
  font-weight: 800;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  box-shadow: 0 4px 16px rgba(16, 185, 129, 0.4);
}
.btn-heroic:hover:not(:disabled) {
  box-shadow: 0 6px 22px rgba(16, 185, 129, 0.6);
  transform: translateY(-2px);
}

input, select {
  background: rgba(10, 14, 23, 0.85);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 9px 13px;
  color: var(--ink);
  transition: all .18s ease;
}
input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(245, 185, 66, 0.18), 0 0 12px rgba(245, 185, 66, 0.25);
  background: rgba(13, 18, 30, 0.95);
}

/* ── Barre du Haut (Header Royal) ────────────────────────────────────────── */
.topbar {
  display: flex; align-items: center; gap: 28px;
  padding: 10px 24px;
  border-bottom: 1px solid var(--line-gold);
  background: rgba(10, 13, 21, 0.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  position: sticky; top: 0; z-index: 40;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.55), inset 0 -1px 0 rgba(245, 185, 66, 0.15);
}

.brand {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; user-select: none;
  text-decoration: none;
}
.brand-crest-wrap {
  position: relative; width: 34px; height: 34px;
  display: grid; place-items: center;
}
/* LE BLASON EST NOIR, ET LA BARRE AUSSI.
   kairos-blason.png est un dessin noir sur fond transparent -- pense pour du
   papier. Pose en <img> sur la barre sombre, il disparaissait : on ne voyait
   que le halo dore qui l'entoure, un rond vide.
   On ne le repeint pas dans un second fichier, qui serait un deuxieme endroit
   ou corriger le jour ou le logo bouge. On s'en sert comme MASQUE, et c'est le
   degrade dore du titre qui le remplit -- le meme --gold-grad, donc la marque
   et le mot KAIROS ne pourront jamais diverger.

   ET C'EST LE SYMBOLE, PAS LE BLASON. Le blason porte « KAIROS » a l'interieur
   de l'anneau : a 30 px le mot devient une bouillie de trois pixels de haut
   qui encrasse le rond. kairos-symbole.png est l'anneau seul, net a cette
   taille -- et le mot est deja ecrit juste a cote, en toutes lettres. */
.brand-crest {
  width: 100%; height: 100%;
  background: var(--or-metal);
  -webkit-mask: url(https://medias.kairostcg.com/logo/kairos-symbole.png) center / contain no-repeat;
  mask: url(https://medias.kairostcg.com/logo/kairos-symbole.png) center / contain no-repeat;
  filter: drop-shadow(0 0 8px rgba(245, 185, 66, 0.45));
  transition: transform .3s ease;
}
.brand:hover .brand-crest {
  transform: scale(1.1) rotate(4deg);
}
.brand-crest-glow {
  position: absolute; inset: -4px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(245, 185, 66, 0.35) 0%, transparent 70%);
  pointer-events: none;
}

.brand-text { display: flex; flex-direction: column; }
.brand-title {
  font-family: 'Cinzel Decorative', var(--font-title);
  font-weight: 700;
  letter-spacing: 0.1em;
  font-size: 20px;
  line-height: 1.1;
  background: var(--or-metal);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 0 20px rgba(245, 185, 66, 0.3);
}
.brand-sub {
  font-size: 9px; letter-spacing: 0.16em; font-weight: 700;
  color: var(--ink-faint); margin-top: 1px;
}

.tabs { display: flex; gap: 6px; }
.tab {
  background: transparent;
  border: 1px solid transparent;
  color: var(--ink-dim);
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.03em;
  display: flex; align-items: center; gap: 7px;
  box-shadow: none;
}
.tab-glyph { font-size: 14px; opacity: 0.8; }
.tab:hover {
  color: var(--ink-bright);
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.1);
  transform: none; box-shadow: none;
}
.tab.is-on {
  color: var(--accent-light);
  background: linear-gradient(180deg, rgba(245, 185, 66, 0.14) 0%, rgba(20, 26, 40, 0.9) 100%);
  border-color: rgba(245, 185, 66, 0.45);
  box-shadow: 0 0 16px rgba(245, 185, 66, 0.18), inset 0 1px 0 rgba(255, 235, 160, 0.4);
}

.status-container, .status { display: none; }

/*  « JOUER » N'EST PAS UN ONGLET, C'EST UNE PORTE A DEUX BATTANTS.
    Solo et En ligne etaient deux onglets voisins sans lien visible ; c'est
    pourtant le meme geste, avec deux adversaires possibles. */
/*  « Jouer » faisait 34 px de haut quand les autres onglets en faisaient 58 :
    ils s'etirent dans la barre, lui etait enferme dans un conteneur qui ne
    s'etirait pas. Le groupe s'etire donc a son tour, et le bouton le remplit. */
.tab-groupe { position: relative; display: flex; align-items: stretch; }
.tab-parent { cursor: pointer; flex: 1 1 auto; }
.tab-caret { font-size: 9px; opacity: .7; transition: transform .2s ease; }
.tab-groupe.est-ouvert .tab-caret { transform: rotate(180deg); }
.tab-groupe.est-ouvert > .tab-parent {
  color: var(--accent-light);
  background: rgba(255, 255, 255, .06);
  border-color: rgba(245, 185, 66, .3);
}
.tab-menu {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 60;
  min-width: 252px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  border-radius: 12px;
  background: rgba(12, 16, 26, .97);
  border: 1px solid var(--line-gold);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 240, 180, .16);
  backdrop-filter: blur(14px);
  animation: tabMenuIn .16s cubic-bezier(.16, 1, .3, 1);
}
@keyframes tabMenuIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
/*  ALIGNES A GAUCHE, PAS CENTRES. Les boutons du jeu heritent d'un
    `justify-content: center` : dans un menu, l'entree au texte le plus court
    se retrouvait poussee vers la droite -- « Solo » etait decale de seize
    pixels par rapport a « En ligne ». Une liste s'aligne par son bord. */
.tab-menu-item {
  display: flex; align-items: center; justify-content: flex-start; gap: 11px;
  padding: 9px 11px; border-radius: 9px;
  background: transparent; border: 1px solid transparent;
  color: var(--ink-dim); text-align: left; box-shadow: none;
}
.tab-menu-item:hover {
  background: rgba(245, 185, 66, .1);
  border-color: rgba(245, 185, 66, .32);
  color: var(--ink-bright); transform: none; box-shadow: none;
}
.tmi-ico {
  flex: none; width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center; font-size: 15px;
  color: var(--accent);
  background: rgba(245, 185, 66, .1);
  border: 1px solid rgba(245, 185, 66, .26);
}
.tmi-txt { display: flex; flex-direction: column; line-height: 1.3; }
.tmi-txt b {
  font-family: var(--font-title); font-size: 13px; font-weight: 800;
  letter-spacing: .05em; color: var(--ink-bright);
}
.tmi-txt i { font-style: normal; font-size: 11px; color: var(--ink-faint); }

/* Le livre blanc vit dans le menu, pas dans un coin : c'est une page du
   site, au meme titre que l'atelier ou le cartable. */
.tab-lien { text-decoration: none; }
/* Deux libelles entiers plutot qu'un mot coupe : « White paper » ne se
   raccourcit pas comme « Livre blanc ». Le court prend le relais quand la
   place manque. */
.tab-lien .tl-court { display: none; }

/*  LE BOUTON QUI DOIT DONNER ENVIE.
    L'ancien etait une pastille grise avec un chiffre -- on la lisait comme
    un compteur, pas comme une porte. Celui-ci montre le grimoire, dit le
    geste (« ouvrir »), et respire tant qu'il reste un paquet scelle. */
.cta-booster {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 5px 16px 5px 6px;
  border-radius: 999px;
  background: linear-gradient(135deg, #4a3310 0%, #20150409 55%, #1c1204 100%);
  border: 1.5px solid var(--accent);
  color: #fff; cursor: pointer; overflow: hidden;
  box-shadow: 0 0 18px rgba(245, 185, 66, .28), inset 0 1px 0 rgba(255, 235, 160, .45);
  transition: transform .25s cubic-bezier(.16, 1, .3, 1), border-color .25s ease;
}
.cta-booster:hover {
  transform: translateY(-2px) scale(1.03);
  border-color: #ffe082;
  box-shadow: 0 0 30px rgba(245, 185, 66, .55);
}
.cta-booster-halo {
  position: absolute; inset: -40% -10%;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 240, 190, .35) 50%, transparent 65%);
  animation: ctaLustre 3.4s ease-in-out infinite;
  pointer-events: none;
}
@keyframes ctaLustre {
  0%, 70%  { transform: translateX(-120%); }
  100%     { transform: translateX(120%); }
}
.cta-booster-img {
  flex: none; width: 34px; height: 34px; object-fit: contain;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, .7));
  animation: ctaRespire 2.8s ease-in-out infinite alternate;
}
@keyframes ctaRespire {
  from { transform: scale(1) rotate(-2deg); }
  to   { transform: scale(1.07) rotate(2deg); }
}
.cta-booster-txt { display: flex; flex-direction: column; line-height: 1.2; text-align: left; }
.cta-booster-txt b {
  font-family: var(--font-title); font-size: 12px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: #ffe699;
}
.cta-booster-txt i {
  font-style: normal; font-size: 10px; font-weight: 700;
  letter-spacing: .06em; color: rgba(255, 230, 153, .62);
}
@media (max-width: 900px) {
  .cta-booster-txt i { display: none; }
}

/* ── DISCORD : un rond comme l'engrenage, le logo prend la couleur de
   Discord au survol. ──────────────────────────────────────────────────── */
.btn-discord {
  flex: none; width: 40px; height: 40px; margin-left: 10px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1.5px solid rgba(245, 185, 66, .55);
  background: rgba(20, 14, 4, .7);
  color: var(--accent-light);
  transition: color .2s ease, border-color .25s ease, box-shadow .25s ease;
}
.btn-discord:hover { color: #5865f2; border-color: #5865f2; box-shadow: 0 0 16px rgba(88, 101, 242, .45); }
/*  Le rond ouvre un petit menu (rejoindre / lier son compte), habille comme
 *  celui du portefeuille. Le bouton garde sa place dans la barre. */
button.btn-discord { padding: 0; cursor: pointer; font: inherit; }
.discord-wrap { position: relative; flex: none; display: flex; }
.discord-menu { min-width: 250px; }
.discord-note { margin: 4px 10px 6px; font-size: 11.5px; line-height: 1.4; color: #a8b0c2; }
/*  Le compte lié, en tête du menu : le bleu de Discord, le nom en clair. */
.discord-qui { margin: 2px 10px 4px; font-size: 12px; color: #a8b0c2; }
.discord-qui b { color: #b9c1ff; font-weight: 700; }
#discord-delier { color: #ffb3a6; }

/* ── PARAMETRES ─────────────────────────────────────────────────────────── */
.btn-parametres {
  flex: none; width: 40px; height: 40px; margin-left: 10px;
  border-radius: 50%;
  border: 1.5px solid rgba(245, 185, 66, .55);
  background: rgba(20, 14, 4, .7);
  color: var(--accent-light); font-size: 20px; line-height: 1;
  cursor: pointer;
  transition: transform .35s cubic-bezier(.16, 1, .3, 1), border-color .25s ease, box-shadow .25s ease;
}
.btn-parametres:hover {
  transform: rotate(60deg);
  border-color: var(--accent);
  box-shadow: 0 0 16px var(--gold-glow);
}
/* ── LA LANGUE (js/langue.js) ───────────────────────────────────────────
   Au large, un globe dans la barre, a cote de l'engrenage ; quand la place
   manque, il cede (paliers et crans plus bas) et la langue ne se choisit plus
   que dans les Parametres, ou elle est toujours. */
.langue-choix { position: relative; flex: none; margin-left: 10px; }
.btn-langue {
  display: flex; align-items: center; gap: 4px;
  height: 40px; padding: 0 11px 0 9px;
  border-radius: 999px;
  border: 1.5px solid rgba(245, 185, 66, .55);
  background: rgba(20, 14, 4, .7);
  color: var(--accent-light); cursor: pointer;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.btn-langue:hover, .btn-langue[aria-expanded="true"] {
  border-color: var(--accent); box-shadow: 0 0 16px var(--gold-glow);
}
.btn-langue-code { font-family: var(--font-title); font-size: 12px; font-weight: 800; letter-spacing: .06em; }
.langue-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 70;
  display: flex; flex-direction: column; gap: 2px; min-width: 160px; padding: 6px;
  border-radius: 12px; border: 1.5px solid var(--accent);
  background: linear-gradient(160deg, #2a1d08 0%, #120c03 100%);
  box-shadow: 0 14px 40px rgba(0, 0, 0, .6);
}
.langue-menu[hidden] { display: none; }
.langue-menu button, .langue-pastilles button {
  display: flex; align-items: center; gap: 10px;
  border: 0; background: none; color: var(--ink); cursor: pointer;
  font: inherit; font-size: 14px; text-align: left;
}
.langue-menu button { padding: 8px 10px; border-radius: 8px; }
.langue-menu button:hover { background: rgba(255, 255, 255, .07); }
.langue-menu button b, .langue-pastilles button b {
  font-family: var(--font-title); font-size: 11px; letter-spacing: .06em; color: var(--accent-dark, #b87f16);
}
.langue-menu button.est-choisie { color: #ffe699; background: rgba(245, 185, 66, .12); }
.langue-menu button.est-choisie b { color: var(--accent); }
.parametre.parametre-langue { grid-template-columns: 1fr; gap: 8px; }
.langue-pastilles { display: flex; flex-wrap: wrap; gap: 6px; }
.langue-pastilles button {
  gap: 6px; min-height: 36px; padding: 6px 11px; border-radius: 999px;
  border: 1px solid rgba(245, 185, 66, .3); background: rgba(255, 255, 255, .03);
  font-size: 13px;
}
.langue-pastilles button:hover { border-color: rgba(245, 185, 66, .6); }
.langue-pastilles button b { display: none; }
.langue-pastilles button.est-choisie {
  border-color: var(--accent); background: rgba(245, 185, 66, .14); color: #ffe699;
}
.langue-pastilles button.est-choisie b { color: var(--accent); }
@media (max-width: 1150px) { .langue-choix { display: none; } }
@media (min-width: 701px) {
  .topbar.serre-1 .btn-langue { width: 40px; padding: 0; justify-content: center; }
  .topbar.serre-1 .btn-langue-code { display: none; }
  .topbar.serre-3 .langue-choix { display: none; }
}

.parametres-voile {
  position: fixed; inset: 0; z-index: 9000;
  display: grid; place-items: center;
  background: rgba(4, 6, 12, .62);
  backdrop-filter: blur(4px);
}
.parametres-panneau {
  width: min(420px, calc(100vw - 32px));
  padding: 18px 22px 22px;
  border-radius: 14px;
  border: 1.5px solid var(--accent);
  background: linear-gradient(160deg, #2a1d08 0%, #120c03 100%);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 235, 160, .3);
  color: var(--ink);
}
.parametres-tete {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 14px;
}
.parametres-tete h2 {
  margin: 0; font-family: var(--font-title); font-size: 18px;
  letter-spacing: .1em; text-transform: uppercase; color: #ffe699;
}
.parametres-fermer {
  width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-dim); font-size: 24px; cursor: pointer;
}
.parametres-fermer:hover { color: #fff; background: rgba(255, 255, 255, .08); }
.parametre {
  /* minmax(0, 1fr) : un curseur a une largeur minimale a lui ; en 1fr, au
     telephone, il poussait le « 50 % » hors de la fenetre. */
  display: grid; grid-template-columns: 120px minmax(0, 1fr) 48px; align-items: center; gap: 12px;
  padding: 10px 0;
}
.parametre input[type="range"] { min-width: 0; width: 100%; }
.parametre-nom { font-weight: 700; font-size: 14px; }
.parametre.parametre-choix { grid-template-columns: 1fr; gap: 8px; padding: 6px 0; }
.parametres-panneau.comm-coupe .comm-detail { opacity: .4; pointer-events: none; }
.parametres-lien {
  display: block; margin-top: 12px; padding-top: 12px;
  border-top: 1px solid rgba(245, 185, 66, .25);
  color: var(--accent-light); font-size: 13px; text-decoration: none;
}
.parametres-lien:hover { color: #fff; }
.parametres-lien[hidden] { display: none; }
.parametres-abandon {
  display: block; width: 100%; margin: 0 0 14px; padding: 11px 14px;
  font: 700 13px/1.2 var(--font-body), sans-serif; letter-spacing: .02em;
  color: #ffd0c0; background: rgba(150, 40, 25, .22);
  border: 1px solid rgba(192, 112, 96, .55); border-radius: 10px; cursor: pointer;
}
.parametres-abandon:hover, .parametres-abandon:focus-visible { background: rgba(170, 50, 30, .38); border-color: #c07060; color: #fff; }
.parametres-abandon[hidden] { display: none; }
.parametre-val { text-align: right; font-family: var(--font-num); color: var(--accent-light); font-size: 13px; }
.parametre input[type="range"] {
  -webkit-appearance: none; appearance: none;
  height: 6px; border-radius: 3px; cursor: pointer;
  background: linear-gradient(90deg, var(--accent) var(--rempli, 50%), rgba(255, 255, 255, .15) var(--rempli, 50%));
}
.parametre input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--gold-grad); border: 2px solid #1c1204;
  box-shadow: 0 0 8px var(--gold-glow);
}
.parametre input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--gold-grad); border: 2px solid #1c1204;
}

/* ── Vues & Conteneur Principal ──────────────────────────────────────────── */
main {
  padding: 24px 28px 48px;
  max-width: 1720px;
  margin: 0 auto;
}
.view { display: none; }
.view.is-on {
  display: block;
  animation: viewFadeIn .28s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

body.atelier-on { overflow: hidden; }
body.atelier-on main { padding: 0; max-width: none; margin: 0; }
body.atelier-on #view-atelier.is-on { height: calc(100dvh - var(--topbar-h)); }

body.play-on { overflow: hidden; background: #060408; }
body.play-on .fantasy-bg-fx { visibility: hidden; }
body.play-on main { padding: 0; max-width: none; margin: 0; }
body.play-on #view-play.is-on {
  position: relative;
  height: calc(100dvh - var(--topbar-h));
  background: #060408;
  overflow: hidden;
}
body.play-on .match {
  height: 100%;
  gap: 0;
}
body.play-on .table3d {
  height: 100%;
  min-height: 0;
}

/* EN PARTIE, LA TABLE PREND TOUT L'ECRAN (main.js, majPleinEcranPartie).
   Plus de navigation pendant un duel : « Abandonner » est la seule sortie, et
   le rouage d'a cote ouvre les Parametres que la barre portait. Relancer le
   tutoriel en plein duel jetterait la partie : le lien attend la fin. */
body.en-partie .topbar { display: none; }
body.en-partie { --topbar-h: 0px; }
body:not(.en-partie) .arena-ctrl-reglages { display: none; }
body.en-partie #parametres-tuto { display: none; }
.arena-ctrl-reglages { flex: 0 0 auto; width: 32px; padding-inline: 0; color: #e8c56a; }
.match-actions .arena-ctrl-reglages::before { content: '⚙'; font-size: 15px; line-height: 1; letter-spacing: 0; }

/* ══ ACCUEIL : LE SITE DE KAIROS ═════════════════════════════════════════════

   Ce n'est pas un tableau de bord, c'est une page d'arrivee. Elle doit
   expliquer le jeu a quelqu'un qui ne le connait pas, montrer les cartes en
   premier, et donner trois portes : jouer, ouvrir, collectionner.
   ═══════════════════════════════════════════════════════════════════════ */
.home {
  max-width: 1280px; margin: 20px auto 60px;
  display: flex; flex-direction: column; gap: 56px;
}

/* ══ LE LEVER DE RIDEAU ═══════════════════════════════════════════════════
   Au chargement, le mur reste seul trois quarts de seconde : le temps de voir la
   Roue entiere, l'or, les racines -- tout ce que les panneaux vont recouvrir
   ensuite. Puis les blocs montent en fondu, l'un apres l'autre, du haut vers
   le bas.

   L'animation est portee par les blocs EUX-MEMES, pas par une classe posee en
   JavaScript : elle se joue donc une fois, au premier rendu, et ne rejoue pas
   quand on revient sur l'accueil depuis une autre vue -- ce qui serait vite
   agacant. `backwards` garde les blocs invisibles pendant l'attente ; sans
   lui ils apparaissent une image avant de disparaitre pour le fondu.
   ════════════════════════════════════════════════════════════════════════ */
/*  LA COURBE COMPTE PLUS QUE LA DUREE.
    Premier essai : 0,72 s en `cubic-bezier(.16, 1, .3, 1)`. Cette courbe-la
    est faite pour un objet qui arrive en glissant -- elle expedie 80 % du
    chemin dans les deux premieres images. Sur une opacite, ca ne se lit pas
    comme un fondu mais comme un allumage. On passe donc a une courbe
    symetrique, lente au depart ET a l'arrivee, et on etale : le bloc monte
    pendant que sa transparence descend, sans a-coup ni a l'un ni a l'autre
    bout. */
@keyframes lever_bloc {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.home > * {
  animation: lever_bloc 1.5s cubic-bezier(.42, 0, .58, 1) backwards;
  animation-delay: calc(.75s + var(--rang, 0) * .16s);
}
.home > *:nth-child(1) { --rang: 0; }
.home > *:nth-child(2) { --rang: 1; }
.home > *:nth-child(3) { --rang: 2; }
.home > *:nth-child(4) { --rang: 3; }
.home > *:nth-child(5) { --rang: 4; }
.home > *:nth-child(6) { --rang: 5; }
.home > *:nth-child(7) { --rang: 6; }
.home > *:nth-child(n+8) { --rang: 7; }
/* Le fond, lui, ne bouge pas : c'est justement lui qu'on vient regarder. */
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .home > * { animation: none; }
}

/*  L'ICONE D'UN ELEMENT EST TOUJOURS LA VRAIE.
    Celle de card-render/icons -- la meme que sur les cartes, sur le plateau
    et dans les filtres. Un emoji de flamme n'est pas le Feu de KAIROS : il
    ne partage ni sa forme, ni sa palette, ni sa signification. Ce masque la
    teinte a la couleur de l'element sans toucher au fichier. */
.el-ico {
  display: block; width: 22px; height: 22px;
  background: var(--el-color, var(--accent));
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
  filter: drop-shadow(0 0 5px var(--el-color, var(--accent)));
}

/* Le titre d'une section de l'accueil */
.sect-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 24px; flex-wrap: wrap;
  border-bottom: 1px solid var(--line-gold); padding-bottom: 14px;
  margin-bottom: 22px;
}
.sect-kicker {
  font-family: var(--font-title); font-size: 10px; font-weight: 800;
  letter-spacing: .24em; color: var(--accent); text-transform: uppercase;
  display: block;
}
.sect-title {
  margin: 4px 0 0; font-family: var(--font-title);
  font-size: 28px; font-weight: 800; letter-spacing: .04em;
  color: var(--ink-bright);
}
.sect-tag { color: var(--ink-dim); font-size: 14.5px; line-height: 1.65; margin: 12px 0 0; }
.sect-tag b, .sect-aside b { color: var(--accent-light); }
.sect-aside {
  flex: 1 1 320px; max-width: 480px; margin: 0;
  font-size: 13px; line-height: 1.6; color: var(--ink-faint);
}

/* ── Le bandeau d'arrivee ─────────────────────────────────────────────── */
.home-hero {
  position: relative;
  /*  LE TEXTE PREND CE QU'IL LUI FAUT, LES CARTES PRENNENT LE RESTE.
   *
   *  La regle disait `1fr 0.92fr`, un partage presque egal -- et on obtenait
   *  665 contre 171. Un `fr` ne descend pas sous le contenu minimum de sa
   *  colonne, et la rangee de trois boutons est en `nowrap` : elle exigeait
   *  665 px, les prenait, et le rapport ecrit ne voulait plus rien dire. Les
   *  cartes se retrouvaient dans un mouchoir et l'eventail sortait de la
   *  tuile pour ressembler a quelque chose.
   *
   *  Le rapport est choisi pour que la rangee de boutons tienne sur une ligne
   *  -- c'est elle la vraie contrainte -- et `minmax(0, ...)` des deux cotes
   *  pour que le rapport soit respecte au lieu d'etre ecrase par le contenu.
   *  (`auto` a ete essaye et rejete : il prend le MAXIMUM du contenu, et le
   *  paragraphe s'octroyait alors 753 px sur 980.)
   *
   *  LA COLONNE DES CARTES EST ETROITE, ET C'EST VOULU : l'eventail n'y tient
   *  pas et n'a pas a y tenir. Il deborde vers la GAUCHE, sous le texte. Six
   *  cartes serrees dans 300 px faisaient un tas ; six cartes etalees sur
   *  550 px derriere le titre font un eventail. */
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
  gap: 24px; align-items: center;
  padding: 44px 44px 40px;
  border-radius: 26px;
  background:
    radial-gradient(ellipse 760px 420px at 12% 25%, rgba(245, 185, 66, .13), transparent 72%),
    radial-gradient(circle at 88% 72%, rgba(168, 85, 247, .16), transparent 58%),
    linear-gradient(175deg, rgba(22, 30, 48, .84) 0%, rgba(9, 12, 21, .97) 100%);
  border: 1px solid var(--line-gold);
  box-shadow:
    0 24px 70px rgba(0, 0, 0, .78),
    inset 0 1px 0 rgba(255, 240, 180, .25),
    0 0 48px rgba(245, 185, 66, .08);
  overflow: hidden;
  /*  Rien ne doit rogner l'eventail : il sort de sa colonne expres. */
  overflow: visible;
}
.home-hero::after {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, .08) 1px, transparent 1px);
  background-size: 28px 28px; opacity: .22; pointer-events: none;
}

/*  LE TEXTE PASSE DEVANT LES CARTES.
    L'eventail vient mourir sous le titre et le paragraphe -- c'est ce qui
    donne la profondeur. Il faut donc que le texte soit au-dessus, et qu'il
    reste lisible : le fond du panneau est sombre et les cartes s'effacent
    a mesure qu'elles s'enfoncent vers la gauche. */
.hero-text-col {
  position: relative; z-index: 3;
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start;
}
.home-kicker {
  font-family: var(--font-title);
  font-size: 11px; letter-spacing: .3em; font-weight: 800;
  color: var(--accent); margin-bottom: 6px;
  text-shadow: 0 0 12px rgba(245, 185, 66, .4);
}
.hero-title {
  margin: 0; font-size: clamp(46px, 5.4vw, 68px);
  letter-spacing: .04em; font-weight: 700;
  font-family: 'Cinzel Decorative', var(--font-title); line-height: 1.05;
  background: var(--or-metal);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 4px 22px rgba(245, 185, 66, .42));
}
.home-tag {
  color: var(--ink-dim); margin: 16px 0 24px;
  font-size: 15px; line-height: 1.7; max-width: 540px;
}
.home-tag b { color: var(--accent-light); }

.hero-cta-group { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-hero-cta {
  padding: 12px 22px; font-size: 13.5px; font-weight: 750; letter-spacing: .04em;
}

.hero-chips {
  margin-top: 22px; display: flex; gap: 10px; flex-wrap: wrap;
}
.hchip {
  font-size: 11.5px; letter-spacing: .06em; color: var(--ink-faint);
  padding: 5px 12px; border-radius: 999px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid var(--line);
}
.hchip b {
  font-family: var(--font-num); font-size: 14px;
  color: var(--accent); margin-right: 4px;
}

/* ── L'eventail : les cartes passent devant ───────────────────────────── */
.hero-cards-stage {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  perspective: 1400px;
}
.hero-cards-fan {
  /*  L'EVENTAIL SE MESURE A SA BOITE, PAS EN PIXELS FIXES.
   *
   *  Les cartes faisaient 158 px et s'ecartaient de 150 : 469 px d'envergure
   *  dans un panneau qui en fait 300. Elles sortaient de la tuile des deux
   *  cotes, et personne ne pouvait le voir en lisant la regle -- la largeur
   *  du panneau est decidee ailleurs, par la colonne de texte.
   *
   *  Tout descend donc d'une seule valeur, la largeur de carte, elle-meme
   *  bornee par la place disponible. L'envergure vaut `--carte-w` fois 2,56
   *  (une carte, plus deux ecarts de 0,78) : a 38 % la somme fait 97 % de la
   *  boite, et il reste une marge des deux cotes a toute taille. */
  /*  Plus petite que la place disponible, EXPRES. Un eventail de six ne se
      lit que si les cartes se decalent d'au moins un tiers de leur largeur :
      a 38 % elles se recouvraient aux neuf dixiemes et faisaient un tas. */
  /*  ANCRE A DROITE, DEPLOYE VERS LA GAUCHE.
   *
   *  Les cartes ne sont plus centrees sur leur colonne : elles partent du
   *  bord droit et s'enfoncent sous le texte. C'est la seule facon d'avoir
   *  un vrai eventail ici -- centre, il debordait des DEUX cotes et sortait
   *  de la tuile a droite, ce qui est le seul bord qu'on ne peut pas
   *  franchir. A gauche il n'y a que du panneau, et le texte par-dessus. */
  /*  EVENTAIL EN ARC, DANS SA PROPRE COLONNE (sept. 2026).
   *  Il ne glisse plus sous le texte : les cartes palies et recouvertes par
   *  le paragraphe faisaient brouillon. Toutes pivotent autour d'un meme
   *  point sous la main, comme une main de cartes tenue -- l'axe passe entre
   *  la troisieme et la quatrieme, les angles se repondent deux a deux. */
  --carte-w: clamp(100px, 9.2vw, 146px);
  --carte-h: calc(var(--carte-w) / .637);
  position: relative; width: 100%; height: calc(var(--carte-h) * 1.55);
  overflow: visible;
}
.stage-card {
  position: absolute;
  left: 50%; bottom: 4%; margin-left: calc(var(--carte-w) / -2);
  width: var(--carte-w, 158px); height: var(--carte-h, 248px);
  transform-origin: 50% 240%;
  /*  PAS DE CONTOUR. Le rendu de la carte porte une marge noire autour du
      cadre : on la rogne sur l'image (clip-path), et l'ombre suit la forme
      rognee grace a drop-shadow -- une box-shadow redessinait un rectangle. */
  filter: drop-shadow(0 14px 22px rgba(0, 0, 0, .7));
  transition: transform .38s cubic-bezier(.16, 1, .3, 1), filter .3s ease;
  cursor: pointer;
}
.stage-card img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  clip-path: inset(1.4% 1.3% round 5% / 3.2%);
}

/*  Le survol ne fait que soulever la carte le long de son rayon : la
    position vit dans des variables, jamais remplacee. */
.stage-card {
  --x: 0px; --y: 0px; --r: 0deg; --s: 1;
  transform: translateX(var(--x)) translateY(var(--y)) rotate(var(--r)) scale(var(--s));
}
.stage-card-1 { --r: -20deg; z-index: 1; }
.stage-card-2 { --r: -12deg; z-index: 2; }
.stage-card-3 { --r:  -4deg; z-index: 3; }
.stage-card-4 { --r:   4deg; z-index: 4; }
.stage-card-5 { --r:  12deg; z-index: 5; }
.stage-card-6 { --r:  20deg; z-index: 6; }

.stage-card:hover {
  transform: translateX(var(--x)) translateY(var(--y)) rotate(var(--r)) translateY(-22px) scale(calc(var(--s) + .08)) !important;
  z-index: 20 !important;
  filter: drop-shadow(0 26px 30px rgba(0, 0, 0, .85)) drop-shadow(0 0 18px rgba(245, 185, 66, .45));
}

.card-foil-sheen {
  position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, .24) 0%, transparent 45%, rgba(245, 185, 66, .2) 100%);
  mix-blend-mode: overlay; pointer-events: none;
  clip-path: inset(1.4% 1.3% round 5% / 3.2%);
}
.card-element-badge {
  position: absolute; bottom: 8px; left: 8px;
  display: flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 800; letter-spacing: .06em;
  padding: 4px 8px; border-radius: 7px;
  background: rgba(10, 14, 23, .86);
  border: 1px solid var(--el, var(--accent)); color: #fff;
  backdrop-filter: blur(4px);
}
.card-element-badge .el-ico { width: 13px; height: 13px; }

.hero-cards-caption {
  margin-top: 30px; font-family: var(--font-title);
  font-size: 11.5px; font-weight: 750; letter-spacing: .12em;
  color: var(--accent-light); text-transform: uppercase;
  display: flex; align-items: center; gap: 8px; text-align: center;
}
.caption-sparkle { color: var(--accent); font-size: 13px; }

/* ══ LA ROUE ═══════════════════════════════════════════════════════════════
   C'est la piece maitresse du jeu, et l'accueil la disait faux : un disque
   qui tournait sur lui-meme, les six elements accroches dessus. Deux erreurs
   dans une seule image. Le cadran est FIXE -- les six pieces y sont serties
   dans un ordre qui ne bouge jamais -- et c'est la SURBRILLANCE qui passe de
   l'une a l'autre, d'un cran par MANCHE.
   ════════════════════════════════════════════════════════════════════════ */
.home-roue {
  display: grid; grid-template-columns: 1fr 0.85fr;
  gap: 48px; align-items: center;
  padding: 40px 44px;
  border-radius: 24px;
  background:
    radial-gradient(ellipse 640px 380px at 82% 50%, rgba(168, 85, 247, .1), transparent 70%),
    linear-gradient(170deg, rgba(20, 26, 44, .8) 0%, rgba(9, 12, 20, .95) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .6);
}
.roue-intro .sect-kicker { margin-bottom: 2px; }
.roue-lois {
  list-style: none; padding: 0; margin: 24px 0 0;
  display: flex; flex-direction: column; gap: 15px;
}
.roue-lois li {
  display: flex; gap: 14px; align-items: flex-start;
  font-size: 13.5px; line-height: 1.6; color: var(--ink-dim);
}
.roue-lois b { color: var(--ink-bright); }
.loi-num {
  flex: none; width: 27px; height: 27px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-num); font-size: 13px; font-weight: 800;
  color: var(--accent);
  background: rgba(245, 185, 66, .1);
  border: 1px solid rgba(245, 185, 66, .38);
}
.roue-conclu {
  margin: 24px 0 0; padding: 13px 16px; border-radius: 11px;
  font-size: 13px; line-height: 1.6; color: var(--accent-light);
  background: rgba(245, 185, 66, .06);
  border-left: 2px solid var(--accent);
}

.roue-scene { display: flex; flex-direction: column; align-items: center; gap: 20px; }
.roue-cadran {
  position: relative;
  width: min(380px, 78vw); aspect-ratio: 1;
}
/* L'anneau : le meuble dans lequel les pieces sont serties. Il ne tourne pas. */
.roue-anneau {
  position: absolute; inset: 0; border-radius: 50%;
  background:
    radial-gradient(circle at 42% 34%, rgba(48, 38, 62, .9) 0%, rgba(14, 18, 30, .96) 58%, #06080e 100%);
  border: 2px solid rgba(245, 185, 66, .45);
  box-shadow:
    0 0 46px rgba(245, 185, 66, .16),
    inset 0 2px 10px rgba(255, 255, 255, .14),
    inset 0 -4px 18px rgba(0, 0, 0, .9);
}
.roue-anneau::after {
  content: ""; position: absolute; inset: 13%;
  border-radius: 50%; border: 1px dashed rgba(245, 185, 66, .22);
}

.roue-piece {
  position: absolute; top: 50%; left: 50%;
  width: 23%; aspect-ratio: 1; margin: 0;
  transform: translate(-50%, -50%) translate(var(--x), var(--y));
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 32%, #1a2133 0%, #0a0d16 100%);
  border: 1.5px solid color-mix(in srgb, var(--el-color) 45%, transparent);
  box-shadow: inset 0 0 10px rgba(0, 0, 0, .85);
  cursor: pointer; padding: 0;
  transition: box-shadow .3s ease, border-color .3s ease, filter .3s ease;
  filter: saturate(.35) brightness(.72);
}
.roue-piece .el-ico { width: 40%; height: 40%; }
.piece-nom {
  font-family: var(--font-title); font-size: 9.5px; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint);
}
/*  `button:hover:not(:disabled)` (0,2,1) passait devant `.roue-piece:hover`
    et remplacait le transform par translateY(-1px) : la piece quittait son
    cran et sautait au centre. Meme poids + une classe pour gagner. */
.roue-piece:active:not(:disabled) {
  transform: translate(-50%, -50%) translate(var(--x), var(--y));
}
.roue-piece:hover:not(:disabled) {
  background: radial-gradient(circle at 40% 32%, #1a2133 0%, #0a0d16 100%);
  box-shadow: inset 0 0 10px rgba(0, 0, 0, .85);
  filter: saturate(.8) brightness(1);
  border-color: var(--el-color);
  transform: translate(-50%, -50%) translate(var(--x), var(--y)) scale(1.08);
}

/*  LA LUMIERE, ET RIEN D'AUTRE, SE DEPLACE.
    La piece reste exactement ou elle est sertie : seule sa mise en lumiere
    change. C'est la meme regle qu'a la table de jeu -- si les deux ne
    disent pas la meme chose, l'une des deux ment. */
.roue-piece.is-on,
.roue-piece.is-on:hover:not(:disabled) {
  filter: none;
  border-color: var(--el-color);
  box-shadow:
    0 0 26px var(--el-glow),
    0 0 0 3px color-mix(in srgb, var(--el-color) 35%, transparent),
    inset 0 0 16px color-mix(in srgb, var(--el-color) 30%, transparent);
  background: radial-gradient(circle at 40% 32%,
              color-mix(in srgb, var(--el-color) 26%, #141b2b) 0%, #0a0d16 100%);
}
.roue-piece.is-on .piece-nom { color: #fff; }
.roue-piece.is-on .el-ico { filter: drop-shadow(0 0 10px var(--el-color)); }

/* Position des six crans : Feu en haut, puis dans le sens du cadran. */
.piece-0 { --x:    0%; --y: -158%; }
.piece-1 { --x:  137%; --y:  -79%; }
.piece-2 { --x:  137%; --y:   79%; }
.piece-3 { --x:    0%; --y:  158%; }
.piece-4 { --x: -137%; --y:   79%; }
.piece-5 { --x: -137%; --y:  -79%; }

.roue-coeur {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44%; aspect-ratio: 1; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  background: radial-gradient(circle, #161d2e 0%, #080b12 100%);
  border: 1px solid rgba(245, 185, 66, .4);
  box-shadow: inset 0 0 18px rgba(0, 0, 0, .9);
  pointer-events: none; text-align: center; padding: 6px;
}
.roue-coeur::before {
  content: ""; position: absolute; inset: 7%;
  border-radius: 50%; border: 1px solid rgba(245, 185, 66, .16);
  pointer-events: none;
}
.roue-coeur-lbl {
  font-family: var(--font-title); font-size: 8px; font-weight: 800;
  letter-spacing: .2em; color: var(--ink-faint);
}
.roue-coeur-el {
  font-family: var(--font-title); font-size: 20px; font-weight: 900;
  letter-spacing: .04em; color: var(--el-actif, var(--accent));
  text-shadow: 0 0 16px var(--el-actif, var(--accent));
  transition: color .45s ease, text-shadow .45s ease;
  line-height: 1.1;
}
.roue-coeur-bonus {
  font-size: 9px; font-weight: 700; letter-spacing: .06em; color: var(--ink-faint);
}

/*  LE POUVOIR, SOUS LE CADRAN.
    Il change a chaque cran ; le bloc garde donc une hauteur fixe, sinon la
    page saute de deux lignes toutes les deux secondes. */
.roue-pouvoir {
  width: min(380px, 82vw); min-height: 74px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 13px 18px; border-radius: 14px; text-align: center;
  background: linear-gradient(170deg, rgba(255, 255, 255, .045), rgba(0, 0, 0, .25));
  border: 1px solid var(--line);
  border-top: 1px solid color-mix(in srgb, var(--el-actif, var(--accent)) 40%, transparent);
}
.rp-kicker {
  font-family: var(--font-title); font-size: 8.5px; font-weight: 800;
  letter-spacing: .22em; color: var(--ink-faint);
}
.rp-nom {
  font-family: var(--font-title); font-size: 17px; font-weight: 800;
  letter-spacing: .04em; color: var(--el-actif, var(--accent));
  text-shadow: 0 0 14px var(--el-actif, var(--accent));
  transition: color .45s ease, text-shadow .45s ease;
}
.rp-ligne { font-size: 12px; line-height: 1.5; color: var(--ink-dim); }

/* La meme chose, en petit, sur la tuile de chaque element. */
.el-pouvoir {
  display: flex; flex-direction: column; gap: 2px;
  /*  Le Pouvoir occupe la derniere ligne de la grille commune (voir
      `.el-grid`), donc les six blocs demarrent au meme pixel et se
      comparent d'un coup d'oeil -- ce qui est tout leur objet. */
  padding-top: 9px;
}
.el-pouvoir b {
  font-family: var(--font-title); font-size: 12px; font-weight: 800;
  letter-spacing: .03em; color: var(--el-color);
}
.el-pouvoir span { font-size: 11px; line-height: 1.45; color: var(--ink-faint); }

.roue-legende {
  display: flex; align-items: center; gap: 12px;
  font-size: 12px; letter-spacing: .08em; color: var(--ink-faint);
  text-transform: uppercase; font-weight: 700;
}
.roue-legende b { color: var(--accent-light); font-family: var(--font-num); font-size: 14px; }
.roue-fleche { color: var(--accent); }

/* ══ LES SIX ELEMENTS : LE MUR ════════════════════════════════════════════
   Six tuiles de verre posees sur du noir, ca ressemblait a un menu. Or ce
   rappel-la ne presente pas six options : il rappelle une loi plus vieille
   que le joueur. Alors c'est un mur -- une pierre usee, mangee par le sel,
   ou un peuple disparu a grave ses six signes. Rien n'y brille par defaut.
   La couleur d'un element ne revient que quand la main s'en approche : le
   glyphe se rallume, comme si la pierre se souvenait.
   Tout est en CSS : le grain vient d'un bruit fractal SVG en data-URI, la
   gravure de deux ombres internes opposees (sombre en haut, claire en bas
   -- l'inverse d'un relief). Aucune image a charger.
   ════════════════════════════════════════════════════════════════════════ */
.home-elements {
  position: relative; isolation: isolate;
  padding: 34px 38px 38px; border-radius: 10px;
  /* La pierre : trois passes de teinte + le grain, et des joints de
     mortier horizontaux qui coupent le bloc en assises. */
  background:
    repeating-linear-gradient(180deg,
      transparent 0 118px,
      rgba(0, 0, 0, .40) 118px 120px,
      rgba(255, 240, 214, .045) 120px 122px,
      transparent 122px 240px),
    radial-gradient(ellipse 70% 55% at 22% 12%, rgba(120, 104, 82, .34), transparent 72%),
    radial-gradient(ellipse 60% 60% at 84% 86%, rgba(96, 86, 72, .30), transparent 74%),
    linear-gradient(168deg, #4a4338 0%, #37312a 46%, #26221c 100%);
  border: 1px solid rgba(0, 0, 0, .65);
  box-shadow:
    inset 0 2px 0 rgba(255, 238, 209, .07),
    inset 0 -26px 46px rgba(0, 0, 0, .55),
    0 22px 54px rgba(0, 0, 0, .55);
}
/* Le grain de la pierre et les auréoles d'humidite. */
.home-elements::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='260'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/></filter><rect width='260' height='260' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay; opacity: .85;
}
/* L'usure : le bas et les bords sont plus manges que le centre. */
.home-elements::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 3;
  background:
    radial-gradient(ellipse 130% 100% at 50% 40%, transparent 52%, rgba(0, 0, 0, .58) 100%),
    linear-gradient(0deg, rgba(0, 0, 0, .38), transparent 30%);
}
/* Le titre grave dans la meme pierre, pas pose dessus. */
.home-elements .sect-head { position: relative; z-index: 1; border-bottom-color: rgba(0, 0, 0, .55); }
.home-elements .sect-title,
.home-elements .sect-kicker {
  color: #cdbb99;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .85), 0 1px 0 rgba(255, 240, 214, .16);
}
.home-elements .sect-aside { color: #9c8f79; }

/*  LES SIX TUILES SE LISENT EN LIGNES, PAS EN COLONNES.
    Chaque tuile partage les lignes de la grille (`subgrid`) : glyphe, nom,
    compte et Pouvoir tombent donc a la MEME hauteur d'une tuile a l'autre,
    quel que soit le nombre de lignes que prend le texte du Pouvoir. C'est
    ce qu'un simple `margin-top: auto` ne savait pas faire : il collait
    chaque Pouvoir au bas de SA tuile, sans rien accorder aux voisines. */
.el-grid {
  display: grid; grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(4, auto);
  column-gap: 14px; row-gap: 7px;
  position: relative; z-index: 1;
}

/*  UNE TUILE EST UN CREUX, PAS UNE PLAQUE.
    D'ou les ombres internes inversees : sombre en haut, clair en bas. */
.el-tuile {
  position: relative; overflow: hidden;
  display: grid; grid-row: span 4; grid-template-rows: subgrid;
  /*  `start` sur les deux axes : un bouton en grille est centre par defaut,
      et le bloc du Pouvoir retombait alors au bas de sa ligne au lieu d'en
      epouser le haut -- les six textes repartaient a six hauteurs. */
  justify-items: start; align-items: start;
  padding: 18px 15px 16px; border-radius: 4px; text-align: left;
  background:
    linear-gradient(170deg, rgba(0, 0, 0, .34) 0%, rgba(0, 0, 0, .12) 40%, rgba(0, 0, 0, .30) 100%),
    /* Fond plein : le joint de mortier de la section ne traverse pas la tuile. */
    #3a342c;
  border: 0;
  box-shadow:
    inset 0 3px 5px rgba(0, 0, 0, .72),
    inset 0 -2px 0 rgba(255, 240, 214, .10),
    inset 2px 0 4px rgba(0, 0, 0, .40),
    inset -2px 0 3px rgba(255, 240, 214, .05);
  cursor: pointer;
  transition: box-shadow .4s ease, background .4s ease, transform .4s cubic-bezier(.16, 1, .3, 1);
}
/*  La lueur qui remonte du creux quand on approche. Elle vit sous le texte
    et ne teinte jamais ce qui se lit. */
.el-tuile::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 110% 70% at 50% 118%,
    color-mix(in srgb, var(--el-color) 42%, transparent), transparent 72%);
  opacity: 0; transition: opacity .45s ease;
}
.home-elements .el-tuile:hover,
.home-elements .el-tuile:focus-visible {
  /*  `button:hover:not(:disabled)`, plus haut, repeint le fond en bleu de
      l'interface et pese plus lourd qu'une simple classe : on passe par le
      mur pour reprendre la main sans toucher au bouton generique. */
  transform: none; background:
    linear-gradient(170deg, rgba(0, 0, 0, .34) 0%, rgba(0, 0, 0, .12) 40%, rgba(0, 0, 0, .30) 100%),
    #3a342c;
  box-shadow:
    inset 0 3px 5px rgba(0, 0, 0, .72),
    inset 0 -2px 0 rgba(255, 240, 214, .10),
    inset 0 0 30px color-mix(in srgb, var(--el-color) 26%, transparent),
    0 0 22px -4px var(--el-glow);
}
.el-tuile:hover::before, .el-tuile:focus-visible::before { opacity: 1; }

/*  LE GLYPHE EST GRAVE, PAS ALLUME.
    Au repos il a la couleur de la pierre et deux ombres opposees qui lui
    donnent son creux ; la teinte de l'element ne revient qu'au survol. */
.el-tuile .el-ico {
  width: 38px; height: 38px;
  background: #6c6250;
  filter:
    drop-shadow(0 -1px 0 rgba(0, 0, 0, .9))
    drop-shadow(0 1px 0 rgba(255, 240, 214, .16));
  opacity: .85;
  transition: background .45s ease, filter .45s ease, opacity .45s ease;
}
.el-tuile:hover .el-ico, .el-tuile:focus-visible .el-ico {
  background: var(--el-color); opacity: 1;
  filter: drop-shadow(0 0 9px var(--el-glow)) drop-shadow(0 1px 0 rgba(0, 0, 0, .7));
}

/* Tout le texte est burine : creux sombre au-dessus, arete claire dessous. */
.el-rang {
  font-family: var(--font-title); font-size: 9px; font-weight: 800;
  letter-spacing: .18em; text-transform: uppercase; color: #8d8068;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .8), 0 1px 0 rgba(255, 240, 214, .10);
}
.el-nom {
  font-family: var(--font-title); font-size: 17px; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase; color: #c3b191;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .9), 0 1px 0 rgba(255, 240, 214, .18);
  transition: color .45s ease;
}
.el-tuile:hover .el-nom { color: color-mix(in srgb, var(--el-color) 45%, #e6d9bd); }
.el-desc {
  font-size: 12px; line-height: 1.5; color: #93866f;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .55);
}
.el-compte {
  font-family: var(--font-num); font-size: 11.5px; font-weight: 700;
  color: #7d7157; text-shadow: 0 1px 0 rgba(0, 0, 0, .55);
}
.el-pouvoir { border-top-color: rgba(0, 0, 0, .5); }
.el-pouvoir b { color: color-mix(in srgb, var(--el-color) 40%, #bda986); }
.el-pouvoir span { color: #8b7f69; }
.el-go {
  font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: color-mix(in srgb, var(--el-color) 60%, #e6d9bd);
  opacity: 0; transform: translateX(-4px);
  transition: opacity .22s ease, transform .22s ease;
}
.el-tuile:hover .el-go, .el-tuile:focus-visible .el-go { opacity: 1; transform: none; }

/* ══ LA JAUGE DE COLLECTION ════════════════════════════════════════════════
   Dans la barre du haut, « 12 / 1374 (1 %) » se lisait comme un detail
   d'interface -- un chiffre a cote d'un autre chiffre. Une barre qui se
   remplit dit la meme chose et donne envie de la remplir.
   ════════════════════════════════════════════════════════════════════════ */
.home-codex {
  padding: 34px 40px 30px; border-radius: 22px;
  background: linear-gradient(170deg, rgba(20, 26, 42, .82) 0%, rgba(9, 12, 20, .95) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
}
.codex-rang {
  font-family: var(--font-title); font-size: 14px; font-weight: 800;
  letter-spacing: .08em; color: var(--accent-light);
  padding: 7px 16px; border-radius: 999px;
  background: rgba(245, 185, 66, .08);
  border: 1px solid var(--line-gold);
  white-space: nowrap;
}

.codex-jauge-wrap { display: flex; flex-direction: column; gap: 9px; }
.codex-jauge {
  position: relative; height: 26px; border-radius: 999px; overflow: hidden;
  background: rgba(6, 8, 14, .9);
  border: 1px solid var(--line);
  box-shadow: inset 0 2px 10px rgba(0, 0, 0, .85);
}
.codex-jauge-fill {
  position: absolute; inset: 0 auto 0 0;
  border-radius: 999px;
  background: linear-gradient(90deg, #b87f16 0%, #f5b942 55%, #fff0b3 100%);
  box-shadow: 0 0 22px rgba(245, 185, 66, .55);
  transition: width .7s cubic-bezier(.16, 1, .3, 1);
  min-width: 3px;
}
.codex-jauge-fill::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .45) 50%, transparent 60%);
  animation: ctaLustre 3.2s ease-in-out infinite;
}
/* Les crans du dixieme : sans eux la barre n'a pas d'echelle, et 12 % se lit
   comme 20 %. */
.codex-jauge-grad {
  position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(90deg,
    transparent 0 calc(10% - 1px), rgba(255, 255, 255, .12) calc(10% - 1px) 10%);
}
.codex-jauge-legende {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12.5px; color: var(--ink-dim);
}
.codex-jauge-legende b { font-family: var(--font-num); color: var(--accent); font-size: 15px; }
.codex-jauge-pct {
  font-family: var(--font-num); font-size: 20px; font-weight: 800;
  color: var(--accent-light);
}

.codex-raretes {
  margin-top: 22px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 26px;
}
.rm-ligne { display: flex; align-items: center; gap: 10px; font-size: 11.5px; }
.rm-lbl {
  flex: 0 0 92px; font-weight: 700; letter-spacing: .02em;
  white-space: nowrap; color: var(--rc, var(--ink-dim));
}
.rm-barre {
  flex: 1; height: 7px; border-radius: 999px; overflow: hidden;
  background: rgba(255, 255, 255, .06);
}
.rm-barre i {
  display: block; height: 100%; border-radius: 999px;
  background: var(--rc, var(--accent));
  box-shadow: 0 0 10px var(--rc, var(--accent));
  transition: width .6s cubic-bezier(.16, 1, .3, 1);
}
.rm-count {
  flex: 0 0 62px; text-align: right;
  font-family: var(--font-num); color: var(--ink-faint);
}
/* Les couleurs de rarete viennent de rules.js -- on les recopie ici parce
   que le CSS ne peut pas les lire, et nulle part ailleurs. */
.rm-commune     { --rc: #c9ccd4; }
.rm-peu-commune { --rc: #eb2b2b; }
.rm-rare        { --rc: #32feff; }
.rm-epique      { --rc: #aa94ff; }
.rm-legendaire  { --rc: #ffbe4d; }
.rm-mythique    { --rc: #81fe97; }

.codex-actions {
  margin-top: 24px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.codex-hint { font-size: 12.5px; color: var(--ink-faint); }

/* ══ LES REGLES & LE LIVRE BLANC ═══════════════════════════════════════ */
.regles-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 34px; }
.regle-bloc h4 {
  margin: 0 0 16px; font-family: var(--font-title); font-size: 14px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent);
}

/*  LE LIVRE BLANC N'EST PAS UNE NOTE DE BAS DE PAGE.
    C'est la piece qui dit ce que l'edition frappe vraiment, et c'est
    exactement la question que se pose quelqu'un a qui l'on vend des paquets.
    Il a donc une bande a lui. */
.bande-blanc {
  margin-top: 34px;
  display: grid; grid-template-columns: auto 1fr auto;
  grid-template-areas: "kicker titre go" "kicker desc go";
  gap: 4px 22px; align-items: center;
  padding: 24px 28px; border-radius: 18px; text-decoration: none;
  background:
    radial-gradient(ellipse 500px 200px at 8% 50%, rgba(245, 185, 66, .14), transparent 70%),
    linear-gradient(100deg, rgba(30, 24, 12, .92) 0%, rgba(10, 13, 21, .96) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .5);
  transition: transform .25s cubic-bezier(.16, 1, .3, 1), border-color .25s ease;
}
.bande-blanc:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .62), 0 0 26px rgba(245, 185, 66, .2);
}
.bb-kicker {
  grid-area: kicker; align-self: center;
  font-family: var(--font-title); font-size: 10px; font-weight: 800;
  letter-spacing: .2em; color: var(--accent);
  writing-mode: vertical-rl; transform: rotate(180deg);
  border-right: 1px solid var(--line-gold); padding-right: 14px;
}
.bb-titre {
  grid-area: titre; font-family: var(--font-title);
  font-size: 17px; font-weight: 800; color: var(--ink-bright);
}
.bb-desc { grid-area: desc; font-size: 12.5px; color: var(--ink-dim); line-height: 1.55; }
.bb-go {
  grid-area: go; align-self: center; white-space: nowrap;
  font-size: 12px; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent-light);
}

/* ── Ce que la fenetre etroite fait de tout ca ────────────────────────── */
@media (max-width: 1100px) {
  .home-hero, .home-roue { grid-template-columns: 1fr; }
  .home-hero { padding: 32px 24px; }
  .home-roue { padding: 30px 24px; gap: 32px; }
  .hero-text-col { align-items: center; text-align: center; }
  .hero-cta-group, .hero-chips { justify-content: center; }
  .el-grid { grid-template-columns: repeat(3, 1fr); }
  .codex-raretes { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  .home { gap: 40px; }
  .hero-title { letter-spacing: .12em; }
  .hero-cards-fan { height: 250px; }
  .el-grid { grid-template-columns: repeat(2, 1fr); }
  .codex-raretes { grid-template-columns: 1fr; }
  .regles-grid { grid-template-columns: 1fr; }
  .home-codex { padding: 24px 20px; }
  .bande-blanc {
    grid-template-columns: 1fr; grid-template-areas: "kicker" "titre" "desc" "go";
    gap: 8px;
  }
  .bb-kicker {
    writing-mode: horizontal-tb; transform: none;
    border-right: none; border-bottom: 1px solid var(--line-gold);
    padding: 0 0 8px;
  }
}

/* ── Portails de Navigation Rapide ───────────────────────────────────────── */
.home-menu {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px;
}
@media (max-width: 1100px) { .home-menu { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .home-menu { grid-template-columns: 1fr; } }
.home-card {
  position: relative;
  text-align: left; padding: 26px 24px; border-radius: 16px;
  background: linear-gradient(165deg, rgba(22, 30, 48, 0.88) 0%, rgba(12, 16, 26, 0.95) 100%);
  border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 8px;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  transition: all .28s cubic-bezier(0.16, 1, 0.3, 1);
}
.hc-glow {
  position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;
  background: radial-gradient(circle at center, rgba(245, 185, 66, 0.12), transparent 60%);
  opacity: 0; transition: opacity .3s ease;
  pointer-events: none;
}
.home-card:hover:not(:disabled) {
  transform: translateY(-5px);
  border-color: rgba(245, 185, 66, 0.55);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.6), 0 0 24px rgba(245, 185, 66, 0.18);
}
.home-card:hover .hc-glow { opacity: 1; }

.hc-badge {
  font-size: 9px; font-weight: 800; letter-spacing: 0.18em;
  color: var(--accent); text-transform: uppercase;
  margin-bottom: 2px;
}
.hc-ico { font-size: 30px; color: var(--accent); line-height: 1; margin-bottom: 4px; }
.hc-t {
  font-family: var(--font-title);
  font-size: 18px; font-weight: 800; letter-spacing: 0.04em;
  color: var(--ink-bright);
}
.hc-d { font-size: 13px; color: var(--ink-dim); line-height: 1.5; flex: 1; }
.hc-action-hint {
  font-size: 11px; font-weight: 750; letter-spacing: 0.1em;
  color: var(--accent); margin-top: 10px;
  display: flex; align-items: center; gap: 4px;
  transition: transform .2s ease;
}
.home-card:hover .hc-action-hint { transform: translateX(2px); color: #fff; }

.home-card--go {
  background: linear-gradient(165deg, rgba(46, 34, 10, 0.92) 0%, rgba(18, 14, 8, 0.96) 100%);
  border-color: rgba(245, 185, 66, 0.6);
  box-shadow: 0 12px 34px rgba(245, 185, 66, 0.16);
}
.home-card--go .hc-t {
  background: var(--gold-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.home-card--go .hc-badge { color: #ffe180; }



/* Présentoir du Deck Actif & Decks Enregistrés */
.home-deck-pedestal {
  padding: 20px 24px; border-radius: 16px;
  background: linear-gradient(180deg, rgba(18, 24, 38, 0.8) 0%, rgba(11, 15, 24, 0.9) 100%);
  border: 1px solid var(--line-gold);
  display: flex; flex-direction: column; gap: 14px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
}
.pedestal-head {
  display: flex; justify-content: space-between; align-items: center;
  border-bottom: 1px solid var(--line); padding-bottom: 10px;
}
.pedestal-title {
  font-family: var(--font-title);
  font-weight: 800; font-size: 14px; letter-spacing: 0.12em;
  color: var(--accent-light); text-transform: uppercase;
}
.pedestal-score {
  font-family: var(--font-num);
  font-weight: 800; font-size: 18px; color: var(--accent);
}
.pedestal-body {
  display: flex; justify-content: space-between; align-items: baseline;
}
.pedestal-deck-name {
  font-family: var(--font-title);
  font-size: 20px; font-weight: 700; color: var(--ink-bright);
}
.pedestal-deck-stats { color: var(--ink-dim); font-size: 13px; }

.home-decks { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.home-decks button {
  background: rgba(10, 14, 23, 0.8);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font-size: 12px; padding: 6px 12px; border-radius: 999px;
}
.home-decks button:hover {
  border-color: var(--accent); color: var(--ink-bright);
  background: rgba(245, 185, 66, 0.1);
}

/* Statistiques du Royaume */
.home-stats-wrap {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.home-stats-label {
  font-family: var(--font-title);
  font-size: 10px; letter-spacing: 0.25em; font-weight: 800;
  color: var(--ink-faint); text-transform: uppercase;
}
.home-stats {
  display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; width: 100%;
}
.home-stats div {
  flex: 1; min-width: 140px; text-align: center;
  padding: 16px 14px; border-radius: 12px;
  background: linear-gradient(180deg, rgba(20, 26, 42, 0.7) 0%, rgba(10, 13, 22, 0.85) 100%);
  border: 1px solid var(--line);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
  transition: transform .2s ease, border-color .2s ease;
}
.home-stats div:hover {
  transform: translateY(-2px); border-color: rgba(245, 185, 66, 0.4);
}
.home-stats b {
  display: block; font-family: var(--font-num);
  font-size: 28px; font-weight: 700; color: var(--accent); line-height: 1.1;
  text-shadow: 0 0 14px rgba(245, 185, 66, 0.3);
}
.home-stats span {
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-dim); font-weight: 700; margin-top: 4px; display: block;
}

/* Règles & Lore */
.home-help {
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(16, 21, 34, 0.7) 0%, rgba(10, 13, 22, 0.85) 100%);
  border: 1px solid var(--line);
  padding: 16px 20px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.home-help summary {
  cursor: pointer; display: flex; justify-content: space-between; align-items: center;
  font-family: var(--font-title); font-size: 15px; font-weight: 700;
  color: var(--accent-light); list-style: none; user-select: none;
}
.home-help summary::-webkit-details-marker { display: none; }
.help-arrow { transition: transform .2s ease; color: var(--accent); }
.home-help[open] .help-arrow { transform: rotate(180deg); }

.help-content {
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line);
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px;
}
.help-section h4 {
  margin: 0 0 14px; font-family: var(--font-title); font-size: 14px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent);
}
.help-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 12px;
}
.help-list li {
  display: flex; gap: 12px; align-items: flex-start;
  font-size: 13px; color: var(--ink-dim); line-height: 1.5;
}
.step-num {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: rgba(245, 185, 66, 0.12); border: 1px solid rgba(245, 185, 66, 0.35);
  color: var(--accent); font-weight: 800; font-size: 11px;
  display: grid; place-items: center;
}
.help-list b { color: var(--ink-bright); }

@media (max-width: 900px) {
  .home-menu { grid-template-columns: 1fr; }
  .help-content { grid-template-columns: 1fr; }
}

.atelier {
  /* La colonne est declaree, et bornee a zero en minimum. Sans elle, la grille
     cree une colonne implicite dimensionnee sur le CONTENU : la galerie
     reclamait ses huit cent soixante-dix-huit pixels naturels et debordait de
     la fenetre, en emportant les filtres avec elle. Invisible au large, ou
     tout tient ; fatal sur un telephone. */
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr;
  height: 100%; min-height: 0;
}

body.collection-mode .deck-rail {
  display: none !important;
}

.deck-rail {
  padding: 12px 24px 10px;
  background: linear-gradient(180deg, rgba(18, 24, 38, 0.95) 0%, rgba(10, 14, 23, 0.98) 100%);
  border-bottom: 1px solid var(--line-gold);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}

.deck-meta {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}

.deck-name-group {
  display: flex; align-items: center; gap: 6px;
  background: rgba(8, 11, 18, 0.6);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 2px 8px;
}
.deck-name-icon { font-size: 14px; opacity: 0.7; }
.deck-name {
  font-family: var(--font-title);
  font-size: 20px; font-weight: 700;
  background: transparent; border: none;
  color: var(--ink-bright); width: 220px;
  padding: 4px 6px;
}
.deck-name:focus { outline: none; }

.deck-score {
  display: flex; flex-direction: column; align-items: center;
  padding: 4px 12px; border-radius: 8px;
  background: rgba(245, 185, 66, 0.08);
  border: 1px solid rgba(245, 185, 66, 0.3);
}
.score-label { font-size: 8px; letter-spacing: 0.15em; font-weight: 800; color: var(--accent); }
.deck-score b {
  font-family: var(--font-num);
  font-size: 22px; font-weight: 800; color: var(--accent); line-height: 1;
}
.score-unit { font-size: 8px; letter-spacing: 0.1em; color: var(--ink-faint); font-weight: 700; }

.reqs { display: flex; flex-wrap: wrap; gap: 6px; }
.req {
  font-size: 11px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  background: rgba(14, 18, 28, 0.85); border: 1px solid var(--line);
  color: var(--ink-dim); white-space: nowrap;
}
.req.is-ok {
  border-color: var(--ok); color: #6ee7b7;
  background: rgba(16, 185, 129, 0.12);
  box-shadow: 0 0 10px rgba(16, 185, 129, 0.2);
}
.req.is-bad {
  border-color: var(--bad); color: #fca5a5;
  background: rgba(248, 113, 113, 0.12);
}

.deck-els-wrap {
  display: flex; align-items: center; gap: 6px;
}
.deck-els-lbl { font-size: 11px; color: var(--ink-faint); font-weight: 600; }
.deck-els { display: flex; gap: 4px; }
.el-chip {
  font-size: 11px; font-weight: 700; padding: 4px 9px; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(10, 14, 22, 0.7);
  color: var(--ink-dim); cursor: pointer; transition: all .16s ease;
}
.el-chip:hover { border-color: var(--accent); color: var(--ink-bright); }
.el-chip.is-on {
  font-weight: 800; box-shadow: 0 0 12px currentColor;
}
.el-note { font-size: 11px; color: var(--ink-dim); margin-left: 4px; }
.el-note b { color: var(--accent); }

.deck-actions { display: flex; gap: 8px; margin-left: auto; }
.deck-actions button { padding: 8px 14px; font-size: 12px; }
.play-why { width: 100%; font-size: 12px; color: var(--ink-faint); text-align: right; }

/* Éventail de cartes (Deck Fan) */
.fan-container {
  width: 100%; margin-top: 10px;
  background: radial-gradient(ellipse at 50% 100%, rgba(245, 185, 66, 0.06), transparent 70%);
}
.fan {
  /* La largeur d'une carte de l'eventail est declaree ICI, pas seulement dans
     `.fan-card` : `renderFan()` doit la connaitre pour calculer le pas de
     chevauchement, et elle change sur telephone. Une valeur recopiee dans le
     JS aurait menti des le premier ecran etroit. */
  --fan-card-w: 108px;
  position: relative;
  display: flex; align-items: flex-end;
  height: 168px; padding: 10px 12px 0;
}
.fan.is-idle {
  align-items: center; justify-content: center;
  color: var(--ink-faint); font-size: 14px;
  border: 1px dashed var(--line); border-radius: 12px;
}
.fan.is-idle em { font-style: normal; color: var(--ink-dim); font-weight: 600; }
.fan-card {
  position: relative; flex: none;
  width: var(--fan-card-w); height: 168px; padding: 0;
  border: none; border-radius: 10px; overflow: hidden;
  background: #111520;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.65);
  cursor: pointer;
  transition: transform .2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow .2s ease;
}
.fan-card img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fan-card:hover, .fan-card.is-hot {
  transform: translateY(-22px) scale(1.06);
  z-index: 50 !important;
  box-shadow: 0 20px 42px rgba(0, 0, 0, 0.85), 0 0 16px rgba(245, 185, 66, 0.4);
}
.fan-peek {
  position: fixed; z-index: 60; width: 240px;
  pointer-events: none;
  filter: drop-shadow(0 24px 50px rgba(0, 0, 0, 0.85));
}
.fan-peek img { display: block; width: 100%; border-radius: 14px; }

/* Decks sauvegardés */
.saved-decks-bar {
  display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap;
}
.saved-decks-lbl { font-size: 11px; font-weight: 700; color: var(--ink-faint); text-transform: uppercase; }
.saved { display: flex; gap: 6px; flex-wrap: wrap; }
.saved:empty { display: none; }
.saved-deck {
  display: flex; align-items: center; gap: 8px;
  background: rgba(14, 19, 30, 0.85);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 10px 4px 14px; cursor: pointer;
  transition: all .16s ease;
}
.saved-deck:hover {
  border-color: var(--accent); background: rgba(245, 185, 66, 0.1);
}
.saved-deck.is-on {
  border-color: var(--accent); background: rgba(245, 185, 66, 0.18);
  box-shadow: 0 0 12px rgba(245, 185, 66, 0.25);
}
.saved-deck .sd-name { font-weight: 750; font-size: 12px; color: var(--ink-bright); }
.saved-deck .sd-meta { font-size: 11px; color: var(--ink-faint); }
.saved-deck .sd-pts { font-weight: 800; color: var(--accent); font-size: 12px; font-family: var(--font-num); }
.saved-deck .sd-x {
  padding: 0 6px; font-size: 14px; border: none; background: transparent;
  color: var(--ink-faint); box-shadow: none;
}
.saved-deck .sd-x:hover { color: var(--bad); }

/* Corps de l'Atelier (Filtres + Galerie) */
.atelier-body {
  display: grid; grid-template-columns: 248px minmax(0, 1fr);
  min-height: 0; overflow: hidden;
}

.filters {
  padding: 18px 16px 24px;
  overflow-y: auto;
  background: rgba(12, 16, 26, 0.75);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 16px;
}
.filter-header {
  display: flex; justify-content: space-between; align-items: center;
}
.filter-title {
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: 0.16em; color: var(--accent-light); text-transform: uppercase;
}
.count-badge {
  font-size: 11px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
  background: rgba(245, 185, 66, 0.15); border: 1px solid rgba(245, 185, 66, 0.3);
  color: var(--accent);
}

.search-box {
  position: relative; display: flex; align-items: center;
}
.search-icon { position: absolute; left: 10px; font-size: 12px; opacity: 0.6; pointer-events: none; }
.search-box input { width: 100%; padding-left: 30px; border-radius: 999px; font-size: 13px; }

.filter-group { display: flex; flex-direction: column; gap: 6px; }
.filter-lbl {
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 800;
}
.f-els, .f-rars, .seg { display: flex; flex-direction: column; gap: 4px; }
.f-el, .f-rar, .seg button {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left;
  background: rgba(16, 22, 34, 0.5);
  border: 1px solid transparent; border-radius: 8px;
  padding: 7px 10px; color: var(--ink-dim);
  box-shadow: none; font-size: 13px;
}
.f-el:hover, .f-rar:hover, .seg button:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.05); color: var(--ink-bright);
  border-color: rgba(255, 255, 255, 0.1); transform: none; box-shadow: none;
}
.f-el.is-on, .f-rar.is-on, .seg button.is-on {
  background: rgba(245, 185, 66, 0.14); color: var(--ink-bright); font-weight: 700;
  border-color: rgba(245, 185, 66, 0.45);
  box-shadow: 0 0 12px rgba(245, 185, 66, 0.12);
}
.f-el i {
  display: block; width: 18px; height: 18px; flex: none;
  background: #8a9cb5;
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
}
.f-el.is-on i { background: var(--el, var(--accent)); }
.f-swatch {
  width: 12px; height: 12px; border-radius: 50%; flex: none;
  background: var(--rc); box-shadow: 0 0 8px var(--rc);
}
.f-rar small {
  margin-left: auto; color: var(--ink-faint); font-size: 11px; font-family: var(--font-num);
}

.filter-toggles { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.ico-check {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-dim); cursor: pointer;
}
.seed-adv { color: var(--ink-faint); font-size: 12px; margin-top: auto; padding-top: 12px; }
.seed-adv summary { cursor: pointer; }
.seed-line { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.seed-line input { flex: 1; min-width: 0; }

/* Galerie de Cartes */
.gal {
  min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.gallery {
  flex: 1; overflow-y: auto;
  display: grid; align-content: start;
  gap: 24px 18px;
  padding: 24px 28px 48px;
  grid-template-columns: repeat(auto-fill, minmax(188px, 1fr));
}
.gal-more { padding: 0 20px 28px; text-align: center; color: var(--ink-faint); font-size: 13px; }

/* Carte dans la Galerie (Slot) */
.slot { position: relative; }
.slot .cf {
  cursor: pointer;
  transform: perspective(1000px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  transition: transform .18s cubic-bezier(0.16, 1, 0.3, 1), box-shadow .25s ease;
}
.slot:hover .cf {
  transform: perspective(1000px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateY(-8px) scale(1.03);
  box-shadow:
    0 0 0 1px var(--rc, var(--accent)),
    0 18px 38px rgba(0, 0, 0, 0.75),
    0 0 20px color-mix(in srgb, var(--rc, var(--accent)) 35%, transparent);
  z-index: 10;
}
.slot.is-out .cf { opacity: 0.4; filter: grayscale(0.6); }
.slot.has-cards .cf {
  box-shadow: 0 0 0 2px var(--accent), 0 12px 28px rgba(0, 0, 0, 0.6);
}
.slot-qty {
  position: absolute; top: -8px; right: -8px; z-index: 12;
  min-width: 28px; height: 26px; padding: 0 7px;
  border-radius: 13px; display: grid; place-items: center;
  background: var(--gold-grad); color: #1a1202;
  font-weight: 800; font-size: 12px; font-family: var(--font-num);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.7);
  pointer-events: none;
}
.slot-actions {
  position: absolute; right: 8px; bottom: 8px;
  display: flex; gap: 5px;
  opacity: 0; transition: opacity .18s ease; pointer-events: none;
  z-index: 12;
}
.slot:hover .slot-actions, .slot.has-cards .slot-actions { opacity: 1; pointer-events: auto; }
.slot-actions button {
  width: 28px; height: 28px; padding: 0; border-radius: 50%;
  font-size: 16px; font-weight: 800;
}
.slot-actions button.add {
  background: var(--gold-grad); color: #1a1202; border-color: #ffe082;
}
/*  LE « + » SE VOIT SANS SURVOL, tant qu'il reste de la place. Il n'apparaissait
    qu'a la souris : au doigt, rien ne disait qu'une carte s'ajoutait. Un bouton
    grise n'apprend rien -- il disparait, et la loupe dit pourquoi. */
#view-atelier .slot-actions { opacity: 1; pointer-events: auto; }
#view-atelier .slot-actions button:disabled { display: none; }

/* ══ LA CARTE RENDUE & ZOOM MODAL ═══════════════════════════════════════════ */
.cf {
  --cf-w: 208px;
  width: var(--cf-w);
  background: linear-gradient(170deg, #1b2234 0%, #101522 45%, #0a0d15 100%);
  border: 1px solid rgba(70, 85, 115, 0.4);
  border-top: 3px solid var(--rc, #c9ccd4);
  border-radius: 12px;
  padding: 9px;
  display: flex; flex-direction: column; gap: 7px;
  position: relative;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.55);
}
.cf-head { display: flex; align-items: center; gap: 6px; }
.cf-name {
  margin: 0; font-family: var(--font-title);
  font-size: calc(var(--cf-w) * 0.068); font-weight: 700;
  letter-spacing: 0.01em; line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--ink-bright);
}
.cf-el {
  margin-left: auto; flex: none;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; font-size: 12px;
  color: var(--el-accent); background: color-mix(in srgb, var(--el) 22%, transparent);
  border: 1px solid color-mix(in srgb, var(--el) 55%, transparent);
}
.cf-art {
  border-radius: 8px; overflow: hidden;
  border: 1px solid rgba(70, 85, 115, 0.35);
  aspect-ratio: 4 / 3; background: #06080e;
}
.cf-art svg { display: block; width: 100%; height: 100%; }
.cf-art--energy { aspect-ratio: 16 / 9; }
.cf-band {
  display: flex; justify-content: space-between; align-items: center;
  font-size: calc(var(--cf-w) * 0.048); letter-spacing: 0.06em; text-transform: uppercase;
}
.cf-rarity { color: var(--rc); font-weight: 750; }
.cf-num { color: var(--ink-faint); font-family: var(--font-num); }
.cf-stats {
  display: flex; gap: 6px;
  background: rgba(8, 11, 18, 0.85); border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 8px;
}
.cf-stats span { display: flex; align-items: baseline; gap: 4px; }
.cf-stats b { font-family: var(--font-num); font-size: calc(var(--cf-w) * 0.088); line-height: 1; }
.cf-stats small { font-size: 9px; color: var(--ink-faint); letter-spacing: 0.08em; }
.cf-atk { color: var(--bad); }
.cf-hp { color: var(--ok); margin-left: auto; }
.cf-energy { color: var(--energy); }
.cf-stats--energy { justify-content: center; }

.cf.cf--print {
  --cf-w: 100%;
  width: 100%; padding: 0; gap: 0;
  background: #07070a; border: none; border-radius: 14px;
  overflow: hidden;
  aspect-ratio: 1024 / 1610;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.08),
    0 14px 34px rgba(0, 0, 0, 0.7);
}
.cf-print { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Fenêtre de Détail (Card Zoom Modal) */
.card-zoom[hidden] {
  display: none !important;
}
/*  LA LOUPE PASSE AU-DESSUS DE TOUT CE QUI PEUT L'OUVRIR.
 *
 *  Elle etait a 80. Le classeur est une vue normale, donc ca marchait -- et
 *  c'est ce qui a cache le defaut pendant longtemps. Mais la LOUPE S'OUVRE
 *  AUSSI DEPUIS DES NAPPES : le booster (`.booster-modal`, z-index 120) et la
 *  ceremonie du deck offert (`.dg-fond`, 3000). Depuis ces deux ecrans, le
 *  clic fonctionnait parfaitement, `openCard` montait la carte pleine, sa
 *  rotation, son filigrane... derriere la nappe. Rien ne s'affichait, et rien
 *  ne pouvait recevoir le glisser qui fait tourner la carte.
 *
 *  La regle n'est donc pas un nombre choisi au jugé : la loupe est le dernier
 *  etage AVANT le panneau de test (4000), parce que tout ce qui montre une
 *  carte doit pouvoir la faire examiner par-dessus soi.
 */
.card-zoom {
  position: fixed; inset: 0; z-index: 3500;
  background: rgba(6, 8, 14, 0.75);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  display: grid; place-items: center; padding: 24px;
  /* Filet : sur un ecran tres court (ou une fenetre reduite en hauteur), la
     carte plafonnee ne suffit plus -- on defile plutot que de couper les
     boutons, comme c'est arrive a la barre de la loupe. */
  overflow: hidden auto;
}
/*  LA CARTE QUI SORT DE SA POCHETTE (sortirDePochette dans main.js).
 *
 *  Le voile et la fiche arrivent en fondu pendant que la carte vole ; la
 *  copie volante passe au-dessus de tout, la loupe comprise. Au retour, le
 *  voile s'efface pendant que la carte rentre. */
/*  Le voile attend que la carte soit sortie de sa pochette (`loupe-tire`) :
    il la couvrirait pendant qu'elle passe la fente. */
.card-zoom.loupe-tire { opacity: 0; }
.card-zoom.loupe-entre { animation: loupeVoile .38s ease both; }
.card-zoom.loupe-entre .zoom-wrap { animation: loupeFiche .42s .2s cubic-bezier(.2, .8, .2, 1) both; }
.card-zoom.loupe-sort { animation: loupeVoile .42s ease reverse both; pointer-events: none; }
.card-zoom.loupe-sort .zoom-wrap { animation: loupeFiche .26s ease reverse both; }
@keyframes loupeVoile { from { opacity: 0; } to { opacity: 1; } }
/*  Opacite SEULEMENT : la carte volante vise la place de la carte dans la
    fiche, mesuree pendant ce fondu -- une fiche qui glisse ou grandit
    deplacerait la cible sous elle. */
@keyframes loupeFiche { from { opacity: 0; } to { opacity: 1; } }
.carte-en-vol {
  position: fixed; z-index: 3600;
  pointer-events: none;
  transform-origin: 0 0;
  border-radius: 12px;
  will-change: transform;
  /*  La lueur de rarete, comme la carte tenue au Cartable : decalee et
      rentree, pour ne jamais dessiner de cerne au ras du bord. */
  box-shadow:
    0 30px 60px -18px rgba(0, 0, 0, .85),
    0 0 40px -6px color-mix(in srgb, var(--rc, #c9a227) 55%, transparent);
}
.carte-en-vol img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  clip-path: inset(var(--carte-marge, 1.4%) round 12px);
}
/*  La pochette reste VIDE tant que sa carte est dehors. */
.cart-vitre.est-sortie { visibility: hidden; }

.zoom-wrap {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  background: rgba(14, 19, 32, 0.94);
  border: 1px solid var(--line-gold);
  border-radius: 20px; padding: 24px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.8), 0 0 30px rgba(245, 185, 66, 0.2);
}
.zoom-print {
  /* LA LOUPE DOIT MONTRER LE TEXTE, PAS UNE MINIATURE DE PLUS.
   *
   * Elle etait plafonnee a 420 px de large : la carte sortait a 660 px de
   * haut, et la description d'une capacite -- 13 px sur un rendu de 1610 --
   * y tombait a 5 px. Illisible, alors que c'est exactement ce qu'on ouvre
   * la loupe pour lire.
   *
   * A 780 px de large la carte fait 1226 px de haut et la description
   * remonte a 10 px : on la lit. La carte pleine resolution fait 1024 px de
   * large, on reste donc EN DESSOUS de sa definition native -- elle ne sera
   * jamais etiree.
   *
   * LA CARTE N'EST PAS SEULE DANS LA COLONNE. Le plafond valait 94vh, ce qui
   * ne laissait que 6vh pour TOUT le reste : les 48 px de marge de la nappe,
   * les ecarts, la mention du geste, la barre d'actions et « Fermer ». Sur un
   * ecran de 720 px de haut, la barre tombait 91 px SOUS le bord, dans un
   * conteneur en `overflow: hidden` -- invisible et inatteignable. On plafonne
   * donc sur ce qui reste vraiment (214 px mesures, 220 pour la marge), pas
   * sur une fraction de l'ecran. */
  max-height: calc(100vh - 220px); max-width: min(94vw, 780px);
  width: auto; height: auto; border-radius: 14px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.8);
}
/*  ══ LA CARTE SE PREND EN MAIN ═════════════════════════════════════════
 *
 *  La loupe montrait une image posee a plat. Une carte, ca se tourne : c'est
 *  comme ca qu'on juge un vernis, qu'on voit le filigrane accrocher, et
 *  c'est le geste qu'on fait avec une carte qu'on vient d'ouvrir. C'est
 *  aussi le seul endroit du jeu ou l'on regarde une carte POUR ELLE-MEME --
 *  ailleurs on la joue, ici on l'examine.
 *
 *  La scene porte la perspective, la carte porte la rotation : deux roles,
 *  deux elements. Les melanger oblige a recalculer la perspective a chaque
 *  image, et la carte se met a "respirer" quand on la tourne.
 */
.zoom-scene {
  perspective: 1500px;
  perspective-origin: 50% 45%;
  /* LA CARTE QUI PENCHE NE FAIT PAS DEFILER LA FICHE (25/10/2026). En grand,
     inclinee a fond, son coin avance de quelques pour cent et depassait le
     bas de l'ecran : la barre de defilement apparaissait et disparaissait
     au gre de l'angle. Le debordement de la carte tournee n'est plus compte
     dans la mise en page (il reste dessine, rien n'est rogne). */
  contain: layout;
  display: grid; place-items: center;
  /* Le geste appartient a la carte : sur un telephone, sans cela, glisser
     dessus fait defiler la page derriere. */
  touch-action: none;
}
.zoom-carte {
  position: relative;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(calc(var(--ry, 0deg) + var(--vire, 0deg)));
  /* Au repos elle revient a plat, et doucement : une carte laissee de
     travers se lit mal, et la loupe est d'abord faite pour lire. Pendant le
     geste on coupe la transition, sinon la carte traine derriere le doigt. */
  transition: transform .45s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}
.zoom-carte.est-tenue { transition: none; }
/* Retournee d'un toucher (tickets 14 et 16) : elle vire d'un demi-tour et
   montre son dos. La transition de repos fait le mouvement. */
.zoom-carte.est-retournee { --vire: 180deg; }
.zoom-carte > img,
.zoom-carte > .vernis { display: block; }
/* La meme marge noire qu'au cartable, coupee de la meme facon : sur chaque
   enfant, pour que l'ombre de la carte survive a la decoupe -- et la meme
   retaille, pour que la carte garde la taille qu'elle avait. */
.zoom-carte > * {
  clip-path: inset(var(--carte-marge, 1.4%) round 12px);
  transform: scale(var(--carte-retaille, 1.03));
  /* La face ne se voit plus quand la carte est retournee. */
  backface-visibility: hidden;
}
/* Le dos : de l'autre cote, a la place de la carte. L'image est deja
   detouree -- pas de marge noire a couper, son contour dore resterait rogne. */
.zoom-carte > .zoom-dos {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain;
  clip-path: none;
  transform: rotateY(180deg);
  pointer-events: none;
}

/* Le geste ne se devine pas : on le dit, une fois, en petit. */
.zoom-geste {
  font-size: 12px; letter-spacing: .04em;
  color: var(--ink-faint, #8d86a0);
}

/*  Le filigrane de la loupe : meme decoupe et meme trame qu'au cartable
 *  (voir la note complete plus bas, pres de `.cart-filigrane`). Il est un
 *  peu plus franc ici -- la carte est grande, et c'est ce qu'on est venu
 *  regarder. */
.zoom-filigrane {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0;
  transition: opacity .2s ease;
  /*  PAS DE `clip-path` SUR CE CALQUE.
   *  Il en portait un (la decoupe), ce qui ECRASAIT le recadrage de la marge
   *  noire herite de son parent : le calque n'etait plus rogne comme la
   *  carte, et la decoupe tombait 1,4 % a cote. Le recadrage reste donc ici,
   *  et la decoupe descend d'un etage -- deux decoupes, deux elements. */
}
.zoom-carte.est-tenue .zoom-filigrane { opacity: 1; }
.zoom-filigrane > i {
  position: absolute; inset: 0; display: block;
  clip-path: var(--decoupe, none);
  background: repeating-linear-gradient(
    calc(var(--ang, 90) * 1deg),
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, .09) 9%,
    rgba(255, 255, 255, .42) 16%,
    rgba(255, 255, 255, .09) 23%,
    rgba(255, 255, 255, 0) 34%,
    rgba(255, 255, 255, 0) 62%);
  /*  UNE SEULE TUILE, JAMAIS REPETEE.
   *
   *  `background-repeat` vaut `repeat` par defaut. La tuile fait 220 % de la
   *  carte : au bord, le degrade est tranche la ou il en est et la tuile
   *  suivante repart a zero -- une ligne droite en travers des sigles, que
   *  l'oeil lit tout de suite comme un defaut d'impression.
   *
   *  Avec `no-repeat`, le deplacement doit rester dans 0-100 % : la tuile
   *  etant plus grande que la carte, elle la couvre alors a toute position.
   *  A 170 % elle sortait du cadre et laissait un bord sans lumiere. Meme
   *  reglage que `.vr-carte` plus bas, qui avait deja ete corrige. */
  background-size: 220% 220%;
  background-repeat: no-repeat;
  background-position: calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: screen;
  -webkit-mask-image: var(--fili);
  mask-image: var(--fili);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.zoom-force { color: var(--accent); font-weight: 800; font-size: 14px; font-family: var(--font-num); }
.zoom-bar { display: flex; gap: 10px; align-items: center; }
.zoom-bar .hint { color: var(--ink-dim); font-size: 13px; }

/*  ECRAN BAS (22/10/2026, tele 4K a 300 % : 1280 x 595 CSS). Empilees, la
 *  carte n'avait plus que 175 px de haut sous tout le reste, et « Fermer »
 *  passait sous le bord. Sur un PC bas, la carte prend la gauche sur toute
 *  la hauteur, la fiche la droite. `ajusterLoupe` lit --loupe-cote.
 *  ET TOUT ECRAN LARGE (Alexandre, 25/10/2026 : « on veut vraiment bien les
 *  voir ») : empilee, la carte partageait la hauteur avec les statistiques,
 *  les boutons et les exemplaires, et sortait a 600 px sur un ecran de
 *  1080. A cote, elle a toute la hauteur -- la version jeu, en 16:9, aussi. */
/*  SOUS LA CARTE (par defaut) : la fiche (`.zoom-fiche`, main.js) et son pied
 *  s'effacent, leurs lignes s'empilent sous la carte comme avant. L'en-tete
 *  et les titres de rubrique ne servent qu'a cote : empilee, la carte est
 *  juste au-dessus. La vue rapprochee, rangee au pied de la fiche, remonte
 *  juste sous la carte. */
.zoom-fiche, .zoom-pied, .zoom-gestes { display: contents; }
.zoom-tete, .zoom-rubrique, .zoom-dit { display: none; }
.zoom-wrap > :not(.zoom-fiche) { order: -2; }
.zoom-proche { order: -1; }

@media (min-width: 901px) and (max-height: 760px), (min-width: 1000px) and (min-aspect-ratio: 5 / 4) {
  .card-zoom { padding: 12px; }
  .zoom-wrap {
    --loupe-cote: 1;
    display: grid; grid-template-columns: auto minmax(0, 640px);
    gap: 0 34px; padding: 16px 22px 16px 16px; max-width: 100%;
  }
  .zoom-wrap > :not(.zoom-fiche) { grid-column: 1; grid-row: 1; align-self: center; margin: 0; }
  .zoom-wrap > .zoom-geste { display: none; }

  /*  LA FICHE PREND TOUTE LA HAUTEUR DE LA CARTE (28/10/2026, Alexandre :
   *  « ca doit prendre tout l'espace »). Elle se centrait en hauteur, petite,
   *  avec un grand vide dessus et dessous. Elle se lit maintenant comme une
   *  page : l'en-tete en haut, « Fermer » en bas, les exemplaires prennent ce
   *  qui reste et defilent seuls s'ils debordent.
   *  `contain: size` : la fiche ne compte pas dans la hauteur de la rangee
   *  -- c'est la carte qui la donne, la fiche s'etire dessus. */
  .zoom-fiche {
    grid-column: 2; grid-row: 1; align-self: stretch;
    display: flex; flex-direction: column; gap: 20px;
    contain: size;
    overflow: hidden auto;
    padding: 8px 6px 2px 0;
    text-align: left;
  }
  .zoom-fiche > * { flex: none; margin: 0; }
  /*  Les rubriques se separent d'un trait discret, pas d'un filet d'or : l'or
   *  est pour les titres et les chiffres. */
  .zoom-fiche .zoom-bar,
  .zoom-fiche > .ex-section { padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, .07); }

  /*  L'en-tete : le rang et le numero, le nom, le genre, la citation. */
  .zoom-tete { display: grid; gap: 8px; }
  .zoom-rang {
    display: flex; align-items: center; gap: 10px; margin: 0;
    font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-dim);
  }
  .zoom-rang b { color: var(--rc, var(--accent)); font-weight: 700; }
  .zoom-rang b + span::before { content: '·'; margin-right: 10px; color: var(--ink-faint); }
  .zoom-rang .zoom-pts {
    margin-left: auto; padding: 4px 12px; border-radius: 999px;
    font-family: var(--font-num); font-size: 16px; font-weight: 800;
    letter-spacing: .02em; text-transform: none; color: var(--accent);
    background: rgba(245, 185, 66, .08); border: 1px solid var(--line-gold);
  }
  .zoom-rang .zoom-pts::before { content: none; }
  .zoom-nom {
    margin: 0; font-family: var(--font-title); font-weight: 700;
    font-size: clamp(32px, 4.4vh, 50px); line-height: 1.08; color: var(--ink-bright, #fff);
  }
  .zoom-genre { display: flex; flex-wrap: wrap; gap: 0 10px; margin: 0; font-size: 17px; color: var(--ink-dim); }
  .zoom-genre > span + span::before { content: '·'; margin-right: 10px; color: var(--ink-faint); }
  .zoom-genre .zoom-element { color: var(--ec, var(--ink-dim)); }
  /*  La citation du bas de la carte : le temoin qui raconte la bete. Elle
   *  ouvre la fiche, en italique, derriere un guillemet d'or. */
  .zoom-citation {
    position: relative; margin: 10px 0 0; padding: 2px 0 0 40px;
    font-family: var(--font-num); font-style: italic;
    font-size: clamp(16px, 1.9vh, 20px); line-height: 1.5; color: #d9cfb8;
  }
  .zoom-citation::before,
  .zoom-citation::after {
    font-family: Georgia, serif; font-style: normal; line-height: 0;
    color: var(--accent); opacity: .75;
  }
  .zoom-citation::before { content: '\201C'; position: absolute; left: 0; top: 22px; font-size: 56px; }
  /*  Le guillemet fermant suit la derniere ligne, sans l'ecarter des autres. */
  .zoom-citation::after { content: '\201D'; margin-left: 6px; font-size: 40px; vertical-align: -.42em; }

  /*  Les trois chiffres en tuiles : le chiffre en grand, le libelle dessus. */
  .zoom-fiche .zoom-stats {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px; max-width: none; margin: 0;
  }
  .zoom-fiche .zoom-stat {
    display: flex; flex-direction: column; gap: 6px;
    padding: 14px 16px; border-radius: 12px;
    background: rgba(255, 255, 255, .035); border: 1px solid rgba(245, 185, 66, .2);
  }
  .zoom-fiche .zoom-stat dd {
    font-family: var(--font-num); font-size: 30px; font-weight: 700; line-height: 1.1;
  }
  .zoom-fiche .zoom-stat dd b { font-weight: inherit; }
  .zoom-fiche .zoom-stat dd small {
    display: block; margin-top: 3px;
    font-family: inherit; font-size: 13px; font-weight: 400; color: var(--ink-dim);
  }
  .zoom-fiche .zoom-stats.est-mots dd { font-size: 17px; font-weight: 600; line-height: 1.35; }
  .zoom-fiche .zoom-stats > span:empty { display: none; }
  .zoom-fiche .zoom-stats-plus { grid-column: 1 / -1; justify-self: end; font-size: 14px; }

  /*  Le deck et la Forge : un titre, les boutons sur toute la largeur. La
   *  force est dans l'en-tete ; une barre qui n'avait qu'elle disparait. */
  .zoom-fiche .zoom-bar .zoom-force { display: none; }
  .zoom-fiche .zoom-bar:not(:has(> :not(.zoom-force))) { display: none; }
  .zoom-fiche .zoom-bar { flex-wrap: wrap; gap: 10px 12px; }
  .zoom-fiche .zoom-bar > button { flex: 1 1 0; min-height: 48px; font-size: 16px; justify-content: center; }
  .zoom-rubrique { display: block; margin: 0; font-family: var(--font-title); font-size: 15px; color: var(--ink); }
  .zoom-fiche .zoom-deck, .zoom-fiche .zoom-forge {
    display: grid; grid-template-columns: 1fr 1fr; align-items: center;
  }
  .zoom-fiche .zoom-deck > .zoom-rubrique { grid-row: 1; grid-column: 1; }
  .zoom-fiche .zoom-deck > .hint { grid-row: 1; grid-column: 2; justify-self: end; text-align: right; font-size: 14px; }
  .zoom-fiche .zoom-deck > button { grid-row: 2; }
  .zoom-fiche .zoom-forge > .zoom-rubrique { grid-column: 1 / -1; }
  .zoom-dit { display: block; font-size: 14px; line-height: 1.4; color: var(--ink-dim); }

  .zoom-fiche > .zoom-pret { max-width: none; margin: 0; }

  /*  Les exemplaires prennent la place qui reste, SANS JAMAIS SE TASSER
   *  (30/10/2026). Ils etaient la seule rubrique qui savait retrecir : des
   *  que la fiche manquait de hauteur, ils tombaient a zero -- leur titre et
   *  un filet de defilement, rien d'autre. Ce qui ne tient pas fait defiler
   *  la fiche entiere, comme une page. */
  .zoom-fiche > .ex-section { flex: 1 0 auto; display: flex; flex-direction: column; width: auto; margin: 0; }

  /*  Le pied, en bas de la carte : « Fermer ». */
  .zoom-pied { display: flex; gap: 12px; margin-top: auto; }
  .zoom-pied > button { flex: 1 1 0; min-height: 48px; font-size: 16px; justify-content: center; }
  /*  PAS DE VUE RAPPROCHEE A COTE (Alexandre, 28/10/2026 : « c'est assez gros,
   *  on n'en a plus besoin ») : la carte a toute la hauteur de l'ecran, son
   *  illustration se voit deja en grand. Empilee, plus petite, elle la garde. */
  .zoom-pied > .zoom-proche { display: none; }
}

/*  UNE FICHE BASSE SE RESSERRE (30/10/2026). Un ami d'Alexandre, sur une
 *  tele 4K de 55 pouces : « une grande partie des infos est cachee ». La
 *  scene y fait 1280 x 720 (taille 150 %) ; en-tete, note du deck de depart,
 *  chances, deck, Forge et exemplaires depassaient de cent pixels -- de
 *  quarante sur un portable en 1536 x 864. Sous 940 px de haut, les
 *  espacements se resserrent ; sous 800, le deck et la Forge passent sur une
 *  meme rangee (`.zoom-gestes`, main.js), leurs boutons alignes. Memes
 *  conditions que la fiche a cote, plus la hauteur. */
@media (min-width: 901px) and (max-height: 760px),
       (min-width: 1000px) and (min-aspect-ratio: 5 / 4) and (max-height: 940px) {
  .zoom-fiche { gap: 10px; padding-top: 2px; }
  .zoom-fiche .zoom-bar,
  .zoom-fiche > .ex-section { padding-top: 10px; }
  .zoom-tete { gap: 4px; }
  .zoom-rang .zoom-pts { padding: 2px 11px; }
  .zoom-citation { margin-top: 4px; line-height: 1.4; }
  .zoom-fiche > .zoom-pret { gap: 2px; padding: 8px 12px; }
  .zoom-fiche .zoom-stats { gap: 8px 12px; }
  .zoom-fiche .zoom-stat { gap: 3px; padding: 9px 14px; }
  .zoom-fiche .zoom-stat dd { font-size: 24px; }
  .zoom-fiche .zoom-stat dd small { margin-top: 2px; font-size: 12px; line-height: 1.3; }
  .zoom-fiche .zoom-stats.est-mots dd { font-size: 16px; }
  .zoom-fiche .zoom-bar > button,
  .zoom-pied > button { min-height: 42px; }
  .zoom-fiche .ex-titre { margin-bottom: 6px; }
  .zoom-fiche .ex-ligne { padding-block: 6px; }
  .zoom-fiche .ex-plus { margin-top: 4px; }
}
@media (min-width: 901px) and (max-height: 760px),
       (min-width: 1000px) and (min-aspect-ratio: 5 / 4) and (max-height: 800px) {
  /*  Une rangee, deux rubriques : le deck sur deux tiers, la Forge sur le
   *  tiers restant. Les titres partagent la premiere ligne de la grille et
   *  les boutons la seconde (`subgrid`) : si l'indication du deck passe a la
   *  ligne, « Forger » descend avec les boutons du deck. La phrase sous
   *  « Forger » reste dans sa bulle (`title`). */
  .zoom-gestes {
    display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    grid-template-rows: auto auto; gap: 10px 16px;
    padding-top: 10px; border-top: 1px solid rgba(255, 255, 255, .07);
  }
  .zoom-gestes:not(:has(> .zoom-forge)) { grid-template-columns: minmax(0, 1fr); }
  .zoom-gestes > .zoom-bar { grid-row: 1 / span 2; grid-template-rows: subgrid; padding-top: 0; border-top: 0; }
  /*  L'indication du deck (« Tu n'en possedes que 2 exemplaire(s) ») a toute
   *  la ligne du titre, qu'elle laisse libre a gauche : dans une seule
   *  colonne, elle passait a la ligne et grandissait la rangee. */
  .zoom-gestes .zoom-deck > .hint { grid-column: 1 / -1; padding-left: 8em; }
  .zoom-gestes > .zoom-forge { grid-template-columns: minmax(0, 1fr); }
  .zoom-gestes .zoom-dit { display: none; }
}

/* ══ VUE COLLECTION DÉDIÉE ══════════════════════════════════════════════════ */
.collection-view-container {
  display: flex; flex-direction: column; gap: 20px;
}
.collection-banner {
  padding: 24px 28px; border-radius: 16px;
  background: linear-gradient(180deg, rgba(20, 27, 44, 0.8) 0%, rgba(10, 14, 24, 0.9) 100%);
  border: 1px solid var(--line-gold);
}
.collection-banner h2 {
  margin: 0 0 6px; font-family: var(--font-title); font-size: 22px; font-weight: 800;
  color: var(--accent-light); letter-spacing: 0.1em;
}
.collection-banner p { margin: 0; color: var(--ink-dim); font-size: 14px; }


/* ══ PARTIE ════════════════════════════════════════════════════════════════ */
.no-match {
  position: relative; z-index: 2;
  max-width: 520px; margin: 80px auto; text-align: center;
  padding: 40px 36px;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(201, 162, 70, 0.12), transparent 55%),
    linear-gradient(180deg, rgba(18, 12, 8, 0.92), rgba(8, 6, 8, 0.96));
  border: 1px solid rgba(201, 162, 70, 0.32);
  border-radius: 4px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55), 0 0 28px rgba(201, 162, 70, 0.08);
}
body.play-on .no-match {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  width: min(520px, 90vw);
}
.no-match-kicker {
  display: block;
  font-family: var(--font-title);
  font-size: 11px; font-weight: 800;
  letter-spacing: 0.32em; text-transform: uppercase;
  color: #c9a246;
  text-shadow: 0 0 14px rgba(201, 162, 70, 0.3);
}
.no-match h1 {
  margin: 10px 0 12px;
  font-family: var(--font-ornate); font-size: 28px; font-weight: 700;
  color: #f3e6c0;
}
.no-match p { color: rgba(196, 178, 148, 0.75); }
.no-match p b { color: #e8c56a; }

.match {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 12px; align-items: start;
}
.wheel-bar {
  position: absolute;
  top: 16px; left: 128px;
  z-index: 36;
  display: flex; align-items: center; gap: 10px;
  background: none; border: 0; padding: 0;
  pointer-events: none;
}
.wheel { display: flex; gap: 6px; }
.wheel span {
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--line); color: var(--ink-faint); font-size: 13px;
}
.wheel span.on {
  border-color: var(--accent); color: #1a1200; background: var(--accent);
  font-weight: 700; box-shadow: 0 0 14px rgba(255, 190, 77, .45);
}
.turn-info { color: var(--ink-dim); font-size: 13px; display: flex; align-items: center; gap: 9px; }
.turn-info b { color: var(--ink); font-size: 14px; letter-spacing: .02em; }
.turn-round {
  padding-right: 10px; border-right: 1px solid var(--line);
  color: var(--ink-dim); font-variant-numeric: tabular-nums;
}
.turn-dot {
  width: 10px; height: 10px; border-radius: 50%;
  box-shadow: 0 0 12px currentColor;
  animation: turnPulse 1.5s ease-in-out infinite;
}
.turn-dot.mine { color: var(--ok); background: var(--ok); }
.turn-dot.foe { color: var(--bad); background: var(--bad); }
@keyframes turnPulse {
  50% { transform: scale(1.35); box-shadow: 0 0 22px currentColor; }
}
.match-actions { margin-left: 0; display: flex; gap: 8px; pointer-events: auto; }
.arena-ctrl {
  padding: 7px 14px;
  font-family: var(--font-title);
  font-size: 10px; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #e8c56a;
  background: radial-gradient(circle at 40% 28%, rgba(78, 54, 24, 0.92), #140c06 72%);
  border: 1px solid rgba(201, 162, 70, 0.45);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 220, 140, 0.18);
}
.arena-ctrl:hover {
  border-color: var(--accent);
  color: #fff3c8;
  background: radial-gradient(circle at 40% 28%, rgba(120, 80, 30, 0.95), #1a1008 72%);
}
.arena-ctrl-danger { color: #e8b4a0; }
.arena-ctrl-danger:hover { color: #ffd0c0; border-color: #c07060; }

/* Le tableau de bord de la partie. Il flotte sur la marge droite de la scene :
   cadran, tour et options forment maintenant un seul objet, comme un pupitre
   pose a cote du plateau plutot que trois morceaux disperses. */
.game-module {
  position: absolute; z-index: 34;
  right: 16px; top: 16px;
  width: 232px; padding: 14px;
  border: 1px solid rgba(201, 162, 70, .42);
  border-radius: 4px;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(201, 162, 70, .14), transparent 52%),
    linear-gradient(180deg, rgba(18, 12, 8, .94), rgba(8, 6, 8, .97));
  box-shadow:
    inset 0 0 0 1px rgba(255, 220, 140, .06),
    inset 0 16px 28px rgba(201, 162, 70, .04),
    0 18px 42px rgba(0, 0, 0, .62);
  backdrop-filter: blur(9px) saturate(1.08);
  pointer-events: none;
}
.game-module::before {
  content: ""; position: absolute; inset: 7px;
  border: 1px solid rgba(201, 162, 70, .16); border-radius: 2px;
  pointer-events: none;
}
.module-label {
  position: relative; z-index: 1;
  margin-bottom: 10px; text-align: center;
  font-family: var(--font-title);
  color: #c9a246; font-size: 10px; font-weight: 800;
  letter-spacing: .22em; text-transform: uppercase;
}
.game-module .turn-info {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: auto 1fr;
  gap: 2px 9px; padding: 9px 10px;
  border: 1px solid rgba(201, 162, 70, .18); border-radius: 3px;
  background: rgba(6, 4, 8, .48);
}
.game-module .turn-info .turn-dot { grid-row: 1 / 3; align-self: center; }
.game-module .turn-info .turn-round {
  padding: 0; border: 0;
  font-size: 10px; letter-spacing: .11em; text-transform: uppercase;
}
.game-module .turn-info b { font-size: 13px; line-height: 1.25; }

/* LE CHRONO DU TOUR, EN LIGNE (main.js, `majChrono`) : 75 s par tour. Il se
   tient a droite de qui joue, discret, et ne rougit qu'aux 15 dernieres
   secondes ; « 1/3 » compte les tours d'affilee laisses au chrono. */
.game-module .turn-info:has(.turn-chrono) { grid-template-columns: auto 1fr auto; }
.turn-chrono {
  grid-column: 3; grid-row: 1 / 3; align-self: center;
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
  color: var(--ink-dim); font-variant-numeric: tabular-nums;
}
.turn-info .turn-chrono b { font-size: 15px; color: inherit; letter-spacing: .04em; }
.turn-chrono.mine { color: var(--ink); }
.turn-chrono small { font-size: 10px; color: var(--bad, #e06a5a); letter-spacing: .06em; }
.turn-chrono small:empty { display: none; }
.turn-chrono.presse { color: var(--bad, #e06a5a); animation: chronoPresse 1s ease-in-out infinite; }
@keyframes chronoPresse { 50% { opacity: .55; } }

/* ── LE PORTRAIT DU TOUR ──────────────────────────────────────────────────
   Un seul cadre, celui de la personne qui joue. Il prend la place que
   tenaient les points de deck -- deux nombres qu'on lisait une fois puis plus
   jamais, la ou l'on veut savoir QUI joue.

   Le cadre change de metal avec le camp : l'or est le mien, l'acier froid
   celui d'en face. C'est la meme opposition chaud/froid que sur les tapis et
   sur les des, donc rien de nouveau a apprendre. */
.duel-portrait {
  position: relative; z-index: 1;
  display: grid; place-items: center; gap: 6px;
  margin-bottom: 10px;
}
.dp-cadre {
  position: relative;
  width: 78px; height: 78px; border-radius: 50%;
  display: grid; place-items: center; overflow: hidden;
  border: 2px solid var(--line-gold);
  background: radial-gradient(circle at 30% 25%, rgba(245, 185, 66, .18), rgba(12, 16, 26, .92));
  transition: box-shadow .35s ease, border-color .35s ease;
}
/* L'image COUVRE le rond, posee dessus : en grille, son `height: 100%` ne
   se resolvait pas -- elle gardait sa hauteur de carte (74 x 116), debordait,
   et le blason sortait du rond, coupe et decale (08/10/2026). */
.dp-cadre img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.dp-initiales {
  font-family: var(--font-title), serif; font-size: 26px; font-weight: 800;
  letter-spacing: .04em; color: var(--accent);
}
.dp-nom {
  font-family: var(--font-title); font-size: 11px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; text-align: center;
  color: var(--ink-dim);
}
/* C'EST LE HALO QUI DIT LE TOUR, pas un liseré d'un pixel : le panneau est
   regarde du coin de l'oeil pendant qu'on joue sur la table. */
.duel-portrait.mien .dp-cadre {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 190, 77, .16), 0 0 22px rgba(255, 190, 77, .38);
}
.duel-portrait.mien .dp-nom { color: var(--accent); }
.duel-portrait.sien .dp-cadre {
  border-color: rgba(150, 168, 190, .75);
  box-shadow: 0 0 0 3px rgba(150, 168, 190, .12), 0 0 20px rgba(120, 150, 190, .3);
}

/* En portrait etroit, le pupitre partage la hauteur avec le plateau : le
   portrait maigrit plutot que de disparaitre -- c'est lui, maintenant, qui
   porte l'information « a qui le tour ». */
@media (max-width: 1100px) and (orientation: portrait) {
  .duel-portrait { margin-bottom: 6px; }
  .dp-cadre { width: 52px; height: 52px; }
  .dp-initiales { font-size: 18px; }
}
.defeat-track {
  grid-column: 1 / -1;
  display: grid; gap: 3px; margin-top: 7px; padding-top: 7px;
  border-top: 1px solid rgba(255,255,255,.07);
  font-size: 10px; letter-spacing: .03em;
}
.defeat-track span { display: flex; justify-content: space-between; gap: 8px; }
.defeat-track .mine b { color: var(--ok); }
.defeat-track .foe b { color: var(--bad); }
.module-rule {
  position: relative; z-index: 1;
  height: 1px; margin: 1px 5px 12px;
  background: linear-gradient(90deg, transparent, #74522f 20% 80%, transparent);
}
.module-end-turn {
  position: relative; z-index: 1;
  width: 100%; margin-top: 11px;
  padding: 9px 10px;
  pointer-events: auto;
  text-transform: uppercase; letter-spacing: .11em;
  font-size: 10px; font-weight: 850;
  box-shadow: 0 0 18px rgba(255,190,77,.13);
}
.module-end-turn:disabled {
  background: #181b23; color: var(--ink-faint);
  border-color: var(--line); box-shadow: none;
}

.boards {
  position: relative;
  display: flex; flex-direction: column; gap: 10px; padding: 16px;
  min-height: calc(100dvh - var(--topbar-h));
  background:
    radial-gradient(ellipse 70% 50% at 50% 0%, rgba(201, 162, 70, 0.07), transparent 55%),
    #060408;
}
.side {
  background: linear-gradient(180deg, rgba(18, 12, 8, 0.9), rgba(8, 6, 8, 0.95));
  border: 1px solid rgba(201, 162, 70, 0.28);
  border-radius: 4px; padding: 12px;
}
.side.foe { border-top: 2px solid rgba(255, 90, 90, .35); }
.side.me { border-bottom: 2px solid rgba(82, 217, 135, .35); }
.side-head { display: flex; align-items: center; gap: 14px; font-size: 12px; color: var(--ink-dim); flex-wrap: wrap; }
.side-head .who { color: var(--ink); font-weight: 600; font-size: 13px; }
.side-head .pip { color: var(--ink-faint); }

/* L'anneau : six tuiles en cercle autour du heros. La geometrie est le jeu —
   voisinage = Phalange, tuile opposee = angle mort. Une grille mentirait. */
.ring { position: relative; width: 100%; max-width: 620px; height: 300px; margin: 10px auto; }
.tile {
  position: absolute;
  width: 96px; height: 132px;
  transform: translate(-50%, -50%);
  border: 2px solid var(--line); border-radius: 10px;
  background: #090c14;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.65);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.tile-card-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border-radius: 8px; z-index: 1;
}
.tile-overlay {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, rgba(8, 12, 20, 0.75) 0%, rgba(8, 12, 20, 0.1) 40%, rgba(5, 8, 14, 0.88) 100%);
  pointer-events: none;
}
.tile.broken {
  background: repeating-linear-gradient(45deg, #0d0f14, #0d0f14 6px, #14171f 6px, #14171f 12px);
  border-style: dashed; opacity: .5;
}
.tile.tombstone {
  align-items: center; justify-content: center;
  color: #aeb4c0; background: radial-gradient(circle at 50% 36%, #3b414d, #151920 68%);
  border-color: #6b7280; box-shadow: inset 0 0 20px rgba(0,0,0,.65);
}
.tombstone-mark {
  font-family: Georgia, serif; font-size: 42px; line-height: 1;
  color: #858d9b; text-shadow: 0 3px 0 #090b0f, 0 0 12px rgba(190,205,225,.18);
}
.tile.empty { border-style: dashed; background: rgba(14, 20, 32, 0.4); }
.tile.hero {
  width: 108px; height: 144px;
  border-color: var(--accent);
  box-shadow: 0 0 18px rgba(245, 185, 66, 0.35);
}
.tile.selectable { cursor: pointer; border-color: var(--accent); box-shadow: 0 0 14px rgba(245, 185, 66, 0.5); }
.tile.selectable:hover { transform: translate(-50%, -50%) scale(1.06); }
.tile.targetable { cursor: crosshair; border-color: var(--bad); box-shadow: 0 0 16px rgba(255, 90, 90, 0.6); }
.tile.acted { opacity: .65; filter: contrast(0.85); }
.tile.final-inactive {
  opacity: .28; filter: grayscale(1) saturate(0);
  border-color: #59606d !important; pointer-events: none;
}
.tile.final-inactive::after {
  content: "HORS COMBAT"; position: absolute; inset: 0;
  display: grid; place-items: center; z-index: 10;
  color: #d3d7df; background: rgba(5,7,10,.6);
  font-size: 10px; font-weight: 900; letter-spacing: .08em;
}
.tile.asleep::after {
  content: "💤"; position: absolute; top: 4px; right: 6px; font-size: 14px; z-index: 10;
}

.tile-name {
  font-family: var(--font-title);
  font-size: 11px; font-weight: 700; padding: 5px 6px 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: #fff; text-shadow: 0 2px 4px #000;
}
.tile-el { font-size: 10px; padding: 0 5px; color: var(--ink-faint); }
.tile-stats {
  margin-top: auto; display: flex; justify-content: space-between; align-items: baseline;
  padding: 3px 6px; font-size: 11px; font-family: var(--font-num);
  text-shadow: 0 2px 4px #000;
}
.tile-atk { color: #ff8b8b; font-weight: 800; }
.tile-atk.boosted { color: var(--accent); }
.tile-hp { color: #8ff0b6; font-weight: 800; }

.hpbar { height: 4px; background: rgba(42, 20, 24, 0.8); }
.hpbar > i { display: block; height: 100%; background: #4cd987; transition: width .35s ease; }
.hpbar.low > i { background: #ff5252; }

.pips { display: flex; gap: 3px; padding: 2px 6px; flex-wrap: wrap; }
.pips i { width: 8px; height: 8px; border-radius: 50%; background: var(--energy); box-shadow: 0 0 6px rgba(87, 200, 255, .8); }
.formation { position: absolute; bottom: 6px; left: 6px; font-size: 9px; color: var(--energy); }
.formation.trio { color: #ffe17a; text-shadow: 0 0 6px currentColor; }

.float {
  position: absolute; left: 50%; top: 40%; transform: translateX(-50%);
  font-weight: 800; font-size: 18px; pointer-events: none;
  animation: rise 1s ease-out forwards; text-shadow: 0 2px 8px #000;
}
.float.dmg { color: var(--bad); }
.float.heal { color: var(--ok); }
@keyframes rise {
  0% { opacity: 0; transform: translate(-50%, 6px) scale(.8); }
  20% { opacity: 1; transform: translate(-50%, -4px) scale(1.15); }
  100% { opacity: 0; transform: translate(-50%, -34px) scale(1); }
}

/* La main : de vraies petites cartes, pas des etiquettes. */
.hand-area { grid-column: 1; padding: 0 16px 16px; }
.hand {
  display: flex; gap: 10px; flex-wrap: wrap;
  background: linear-gradient(180deg, rgba(18, 12, 8, 0.9), rgba(8, 6, 8, 0.95));
  border: 1px solid rgba(201, 162, 70, 0.28);
  border-radius: 4px; padding: 12px; min-height: 190px;
}
.hand .cf { --cf-w: 132px; cursor: pointer; transition: transform .12s, box-shadow .12s; }
.hand .slot:hover .cf { transform: translateY(-8px); box-shadow: 0 10px 24px rgba(0, 0, 0, .7); }
.hand .slot.is-on .cf { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(255, 190, 77, .4); }
.hand-empty { color: var(--ink-faint); font-size: 12px; }

.prompt {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: stretch;
  gap: 7px; padding: 0;
  background: transparent; border: 0; box-shadow: none;
  pointer-events: auto;
}
.prompt .msg { font-weight: 650; font-size: 12px; line-height: 1.4; color: var(--ink); }
/* Un geste refuse (flash) prend la place de la consigne, le temps de le lire. */
.prompt .msg.msg-refus { color: #ff9b8a; animation: msg-refus .32s ease-out; }
@keyframes msg-refus { 0%, 50% { transform: translateX(-3px); } 25%, 75% { transform: translateX(3px); } 100% { transform: none; } }
.prompt .c-meta {
  color: var(--ink-faint); font-size: 10px; line-height: 1.35;
  padding-top: 3px;
}
/* L'intertitre est un cartouche, pas une etiquette : deux filets qui courent
   de part et d'autre du mot, comme les gravures du tapis. */
.prompt-kicker {
  display: flex; align-items: center; gap: 8px;
  color: var(--accent); font-family: var(--font-title), Georgia, serif;
  font-size: 9px; font-weight: 800;
  letter-spacing: .22em; text-transform: uppercase;
}
.prompt-kicker::before, .prompt-kicker::after {
  content: ''; flex: 1 1 auto; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(201, 162, 70, .45));
}
.prompt-kicker::after { background: linear-gradient(90deg, rgba(201, 162, 70, .45), transparent); }

/* ══ LE REGISTRE DU TOUR ═══════════════════════════════════════════════════
 *
 * Trois barres pleine largeur, un texte dedans, deux teintes : ce qui restait
 * a faire etait ambre, ce qui etait fait etait gris. Cela DISAIT l'etat sans
 * jamais le montrer -- il fallait lire les trois lignes en entier pour savoir
 * ou l'on en etait, et rien ne donnait le compte.
 *
 * Trois colonnes fixes, les memes pour les trois lignes : le rang, l'action,
 * le compte. L'oeil descend une colonne au lieu de relire trois phrases.
 */
.registre { display: flex; flex-direction: column; gap: 4px; }

.opt {
  position: relative;
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto;
  align-items: center; gap: 7px;
  padding: 6px 8px 6px 7px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: rgba(255, 255, 255, .022);
  transition: border-color .2s ease, background .2s ease;
}
/* Le liseré de gauche porte l'etat : c'est la seule chose qui court sur toute
   la hauteur de la ligne, donc la premiere que l'oeil suit en descendant. */
.opt::before {
  content: ''; position: absolute; left: 0; top: 5px; bottom: 5px;
  width: 2px; border-radius: 2px;
  background: var(--line-gold, rgba(201, 162, 70, .3));
}

/* LE RANG, dans son mereau. Rond, parce qu'un chiffre dans un cercle se lit
   comme un jeton pose sur la table -- et que le carre etait deja pris par les
   logements du plateau. */
.opt-rang {
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-title), Georgia, serif;
  font-size: 9px; font-weight: 800; letter-spacing: 0;
  border: 1px solid var(--line);
  color: var(--ink-faint);
}
.opt-nom { min-width: 0; display: block; }
/* Le pupitre ne fait que 232 px de large : a 11 px, « Deployer une creature »
   sortait du cadre et finissait en points de suspension. Mesure a 10 px, la
   ligne la plus longue tient avec de la marge. */
.opt-nom b {
  display: block;
  font-family: var(--font-title), Georgia, serif;
  font-size: 10px; font-weight: 700; letter-spacing: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Deux longueurs pour un meme libelle : la place decide, pas le code.
   Ecrit `.opt-court`, ce masquage perdait contre `.opt-nom b` juste au-dessus
   -- une classe plus un element l'emportent sur une classe seule -- et les
   DEUX libelles s'empilaient. On qualifie donc au meme niveau. */
.opt-nom b.opt-court { display: none; }
.opt-valeur {
  font-family: var(--font-num), Georgia, serif;
  font-size: 10px; font-weight: 700; letter-spacing: .03em;
  color: var(--ink-faint); white-space: nowrap;
}

/* ── OUVERT : il reste ceci a faire ── */
.opt--ouvert {
  border-color: rgba(255, 190, 77, .38);
  background:
    linear-gradient(90deg, rgba(255, 190, 77, .10) 0%, rgba(255, 190, 77, .03) 45%, transparent 100%),
    rgba(255, 190, 77, .04);
}
.opt--ouvert::before { background: var(--gold-grad, #f5b942); box-shadow: 0 0 8px rgba(245, 185, 66, .55); }
.opt--ouvert .opt-rang {
  background: var(--gold-grad, linear-gradient(180deg, #f5d67a, #c9a246));
  border-color: #ffe082; color: #1a1202;
  box-shadow: 0 0 10px rgba(245, 185, 66, .35);
}
.opt--ouvert .opt-nom b { color: var(--ink-bright, #fff3d6); }
.opt--ouvert .opt-valeur { color: #ffd98a; }

/* ── FAIT : c'est joue, la ligne s'efface sans disparaitre ── */
.opt--fait { opacity: .62; }
.opt--fait::before { background: rgba(127, 216, 162, .5); }
.opt--fait .opt-rang { color: #7fd8a2; border-color: rgba(127, 216, 162, .4); }
.opt--fait .opt-nom b { color: var(--ink-dim); font-weight: 600; }

/* ── FERME : la porte est close, ce n'est PAS un devoir accompli ──
   Le combat final, ou le heros sorti apres trois pertes. L'ancienne version
   melait ce cas au precedent : on croyait avoir deploye alors qu'on ne
   POUVAIT plus deployer. */
.opt--ferme { opacity: .78; border-color: rgba(200, 90, 70, .3); }
.opt--ferme::before { background: rgba(224, 122, 95, .55); }
.opt--ferme .opt-rang { color: #e08a70; border-color: rgba(224, 122, 95, .42); }
.opt--ferme .opt-nom b { color: #d9a495; font-weight: 600; }
.opt--ferme .opt-valeur { color: #c8836e; font-style: italic; }
.prompt > button { width: 100%; margin-top: 3px; }

@media (max-width: 1100px) {
  body.atelier-on { overflow: auto; }
  .atelier { height: auto; }
  .atelier-body { grid-template-columns: 1fr; }
  .filters { border-right: none; border-bottom: 1px solid var(--line); flex-direction: row; flex-wrap: wrap; }
  .gal { min-height: 70vh; }
}
@media (max-width: 1100px) {
  .match { grid-template-columns: 1fr; }
}

/* ══ ACCUEIL ═══════════════════════════════════════════════════════════════ */
.home { max-width: 980px; margin: 42px auto; display: flex; flex-direction: column; gap: 28px; }
.home-title { text-align: center; }
.home-title h1 {
  margin: 0; font-size: 56px; letter-spacing: .28em; font-weight: 700;
  font-family: "Fraunces", Georgia, serif;
  background: linear-gradient(180deg, #1d1914 0%, var(--accent) 140%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
body.light-ui .home-card:hover:not(:disabled) { background: #fff; border-color: var(--accent); }
body.light-ui .home-card--go { background: linear-gradient(160deg, #fff3e4, #fff); }
.home-tag { color: var(--ink-dim); max-width: 560px; margin: 10px auto 0; }

.home-stats { display: flex; justify-content: center; gap: 26px; flex-wrap: wrap; }
.home-stats div { text-align: center; }
.home-stats b { display: block; font-size: 24px; color: var(--accent); line-height: 1.1; }
.home-stats span { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }

.home-menu { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.home-card {
  text-align: left; padding: 20px; border-radius: 12px;
  background: var(--bg-2); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 6px;
}
body.light-ui .home-card { background: #fff; }
.home-card:hover:not(:disabled) { border-color: var(--accent); background: #171c27; }
.hc-ico { font-size: 24px; color: var(--accent); line-height: 1; }
.hc-t { font-size: 15px; font-weight: 700; }
.hc-d { font-size: 12px; color: var(--ink-dim); }
.home-card--go { background: linear-gradient(160deg, #2a2008, var(--bg-2)); border-color: #4a3a12; }
.home-card--go .hc-t { color: var(--accent); }
.home-card:disabled { opacity: .5; }

.home-decks { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; align-items: center; }
.home-decks .lbl { font-size: 12px; color: var(--ink-faint); }

.home-help { border-top: 1px solid var(--line); padding-top: 16px; color: var(--ink-dim); }
.home-help summary { cursor: pointer; color: var(--ink); font-weight: 600; }
.home-help ol { margin: 8px 0 0; padding-left: 22px; display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
/* Deux listes maintenant : le deroulement, puis les regles. Sans intertitre on
   lisait dix lignes d'affilee sans savoir laquelle repondait a « et ensuite ? ». */
.home-help h4 { margin: 18px 0 0; font-size: 11px; letter-spacing: .12em;
                text-transform: uppercase; color: var(--accent); font-weight: 700; }
.home-help h4:first-of-type { margin-top: 14px; }
.home-help li b { color: var(--ink); }

@media (max-width: 760px) { .home-menu { grid-template-columns: 1fr; } }

/* L'illustration peinte, quand elle existe. Elle occupe exactement la place du
   sigil procedural : la galerie ne bouge pas selon que l'art est la ou non. */
.cf-img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ── La table 3D ──────────────────────────────────────────────────────────
   Le canvas occupe tout l'espace de jeu ; les etiquettes flottent au-dessus,
   positionnees par projection depuis la scene. Elles ne captent pas la souris
   (pointer-events:none) : les clics doivent atteindre les cartes du canvas. */
/* La table prend toute la hauteur disponible sous la barre de Roue. Laissee a
   sa hauteur naturelle, le canvas se reduisait a une bande et la main sortait
   du cadre par le bas. 100dvh tient compte des barres mobiles. */
.table3d {
  position: relative; width: 100%;
  height: calc(100dvh - var(--topbar-h)); min-height: 480px;
  border: 0; border-radius: 0;
  overflow: hidden; background: #060408;
  box-shadow: none;
}
.table3d > canvas { display: block; width: 100%; height: 100%; }

.arena-sanctum {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 0;
  overflow: hidden;
}
#view-play:has(#no-match[hidden]) .arena-sanctum { display: none; }
.arena-close-halo {
  position: absolute;
  left: 50%; top: 48%;
  width: 560px; height: 420px;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse 55% 50% at 50% 45%,
    rgba(255, 214, 130, 0.18) 0%,
    rgba(180, 110, 40, 0.05) 46%,
    transparent 70%);
  filter: blur(28px);
  animation: haloPulse 5s ease-in-out infinite alternate;
}

.arena-frame {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 20;
}
.arena-vault {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 46% at 50% -8%,
    rgba(0, 0, 0, 0.18) 0%,
    transparent 70%);
}
.arena-shaft {
  position: absolute;
  left: 50%; top: 0;
  width: 100%; height: 70%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse 18% 58% at 50% 0%,
    rgba(255, 228, 170, 0.34) 0%,
    rgba(232, 196, 120, 0.10) 28%,
    transparent 62%);
  filter: blur(58px);
  mix-blend-mode: screen;
  animation: shaftPulse 8s ease-in-out infinite alternate;
}
.arena-floor {
  position: absolute;
  left: 50%; bottom: 0;
  width: 90%; height: 32%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 88%,
    rgba(201, 162, 70, 0.08) 0%,
    transparent 70%);
  filter: blur(14px);
}
.arena-fog {
  position: absolute;
  left: -16%; right: -16%;
  height: 28%;
  bottom: -8%;
  filter: blur(28px);
  opacity: 0.34;
}
.arena-fog-1 {
  background: radial-gradient(ellipse at 50% 80%,
    rgba(48, 32, 22, 0.78) 0%, rgba(28, 18, 16, 0.32) 52%, transparent 72%);
  animation: fogDrift 22s ease-in-out infinite alternate;
}
.arena-fog-2 {
  height: 22%;
  bottom: -5%;
  background: radial-gradient(ellipse at 32% 70%,
    rgba(90, 58, 28, 0.32) 0%, transparent 70%);
  animation: fogDrift 16s ease-in-out infinite alternate-reverse;
}
.arena-runes {
  position: absolute;
  bottom: 2.8%; left: 118px; right: 16px;
  text-align: center;
  font-family: var(--font-title);
  letter-spacing: 0.5em;
  font-size: 11px;
  color: rgba(201, 162, 70, 0.28);
  text-shadow: 0 0 12px rgba(201, 162, 70, 0.28);
  animation: runeGlow 7s ease-in-out infinite alternate;
}
.arena-vignette {
  position: absolute; inset: 0;
  /* La vignette cadre le regard, elle n'eteint pas la table. */
  background: radial-gradient(ellipse 74% 68% at 50% 46%,
    transparent 40%,
    rgba(0, 0, 0, 0.12) 74%,
    rgba(0, 0, 0, 0.42) 100%);
}
/* Filet de surete : lanternes CSS (oeufs ambre) hors du grimoire.
   Elles survivaient au cache HTML et se lisaient autour des tapis. */
#view-play .chamber-lantern,
#table3d .arena-lantern,
.arena-frame .arena-lantern,
.arena-sanctum .chamber-lantern {
  display: none !important;
}
.arena-filigree { position: absolute; inset: 0; color: #c9a246; }
.arena-filigree .filigree-tl { top: 10px; left: 118px; }
.arena-filigree .filigree-tr { top: 10px; right: 252px; }
.arena-filigree .filigree-bl { bottom: 10px; left: 118px; }
.arena-filigree .filigree-br { bottom: 10px; right: 14px; }
@media (max-width: 760px) {
  .arena-runes { display: none; }
  .arena-filigree .filigree { width: 52px; height: 52px; }
  .arena-filigree .filigree-tl,
  .arena-filigree .filigree-bl { left: 8px; }
  .arena-filigree .filigree-tr,
  .arena-filigree .filigree-br { right: 8px; }
}


/* ── La main, en colonne a gauche ─────────────────────────────────────────
   Une carte de main doit se LIRE avant d'etre jouee. En eventail dans la 3D
   elle faisait 60 px de haut et penchait : on distinguait la couleur, pas le
   texte. En colonne, elle se survole et se deplie. */
.main-col {
  /* LA MAIN PASSE AU-DESSUS DU CADRE. Le voile d'arene (.arena-frame, z-20)
     couvrait tout, y compris cette colonne -- et c'est justement le bord
     gauche, la ou la vignette est la plus noire. Les cartes n'etaient pas
     grisees par le jeu : elles etaient sous un rideau. */
  z-index: 25;
  position: absolute; left: 14px; top: 14px; bottom: 14px;
  width: 104px; display: flex; flex-direction: column; gap: 6px;
  align-items: flex-start; justify-content: flex-start;
  pointer-events: none;
}
/*  LE RATELIER DE LA MAIN -- ET NON PLUS UNE BANDE NOIRE.
 *
 *  Ce fond etait un simple degrade vers le noir. Tant que les sept cartes y
 *  etaient posees, on ne le voyait pas ; mais la main arrive APRES le lancer
 *  d'ouverture et la pose des heros, et pendant tout ce temps le joueur avait
 *  sous les yeux une bande noire de la hauteur de l'ecran, collee au bord
 *  gauche, qui ne ressemblait a rien -- ni a un morceau d'arene, ni a un
 *  endroit ou des cartes vont venir.
 *
 *  C'est maintenant un RATELIER taille dans la meme pierre que le reste de la
 *  salle : un panneau d'ardoise, un filet d'or sur son arete, et sept
 *  logements creuses en attente. Vide, il annonce ce qu'il va recevoir ; plein,
 *  il disparait derriere les cartes, ce qu'il faisait deja. */
.main-col::before {
  content: '';
  position: absolute;
  inset: -10px -14px -10px -16px;
  border-radius: 0 10px 10px 0;
  background:
    /* Les logements : sept encoches sombres, separees d'un filet clair. C'est
       ce qui fait qu'un ratelier vide se lit comme un ratelier. */
    repeating-linear-gradient(180deg,
      rgba(255, 232, 180, .10) 0px,
      rgba(255, 232, 180, .10) 1px,
      rgba(0, 0, 0, .26) 2px,
      rgba(0, 0, 0, .26) 12.2%),
    /* La lumiere de la salle tombe du haut, comme sur les parois de l'arene. */
    linear-gradient(180deg, rgba(64, 54, 72, .95), rgba(34, 27, 42, .95) 46%, rgba(22, 17, 28, .95)),
    /* Et l'ombre du bord, qui detache le ratelier de la table. */
    linear-gradient(90deg, rgba(6, 4, 9, .55) 0%, rgba(8, 6, 11, .28) 74%, rgba(8, 6, 11, .10) 100%);
  box-shadow:
    inset -1px 0 0 rgba(201, 162, 70, .30),
    inset 0 1px 0 rgba(255, 232, 180, .10),
    6px 0 22px rgba(0, 0, 0, .55);
  pointer-events: none;
  z-index: -1;
}
/*  L'ARETE D'OR, et rien d'autre : le ratelier appartient a l'arene, il n'y a
 *  pas ete pose. Le filet s'eteint aux deux bouts, comme les filigranes des
 *  coins -- une ligne d'or franche du haut en bas ferait une barre de menu. */
.main-col::after {
  content: '';
  position: absolute;
  top: -10px; bottom: -10px; right: -14px; width: 2px;
  background: linear-gradient(180deg,
    transparent, rgba(201, 162, 70, .55) 12%, rgba(201, 162, 70, .55) 88%, transparent);
  pointer-events: none;
  z-index: -1;
}
/* La carte de main ne bouge JAMAIS. Elle ne fait que s'eclairer. L'agrandi
   vit dans un apercu a position fixe, plus bas. */
.mc-carte {
  position: relative; width: 100%; flex: 0 0 auto;
  cursor: pointer; pointer-events: auto;
  border-radius: 6px;
  transition: filter .18s ease, outline-color .18s ease;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, .6));
  outline: 2px solid transparent; outline-offset: 1px;
}
.mc-carte img { display: block; width: 100%; border-radius: 6px; }
/* C'EST LA FEUILLE DE STYLE QUI DIT LEQUEL DES DEUX AFFICHAGES EST EN COURS.
   Le script a besoin de le savoir -- il pose les cartes lui-meme (voir
   `disposerLaMain`) -- et recopier le seuil de 1180 px en JavaScript, c'est
   deux nombres a tenir d'accord pour toujours. Il lit donc CE drapeau. */
.main-col { --main-grande: 0; }
.mc-carte.survol { filter: drop-shadow(0 4px 14px rgba(0, 0, 0, .85)) brightness(1.12); }
.mc-carte.is-on { outline-color: var(--accent); }
.mc-carte.dead { filter: grayscale(.7) brightness(.55); }

/* Au repos (tour du bot) la carte reste lisible : elle perd son ombre portee,
   pas sa lumiere. Hors-jeu (une energie pendant le choix du heros) elle
   s'efface juste assez pour ne pas concurrencer les creatures. */
.mc-carte.repos { cursor: default; filter: saturate(.92); }
.mc-carte.hors-jeu { filter: saturate(.75) brightness(.86); cursor: not-allowed; }
/* Plus de destination ce tour (trois creatures en jeu, energie deja posee) :
   grisee franchement, mais encore lisible -- elle se relit, elle ne se joue pas. */
.mc-carte.epuisee { filter: grayscale(.85) brightness(.7); cursor: not-allowed; }
/* La carte JOUABLE : un halo qui respire, sans deplacer la carte. */
.mc-carte.jouable {
  outline-color: rgba(255, 214, 130, .9);
  animation: mc-jouable 2.2s ease-in-out infinite;
}
.mc-carte.jouable.survol { animation: none; }
/* Une fois choisie, la carte n'a plus a s'annoncer : le liseré de selection reprend la main. */
.mc-carte.jouable.is-on { outline-color: var(--accent); animation: none; }
@keyframes mc-jouable {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(245, 185, 66, .35)) brightness(1.02); }
  50%      { filter: drop-shadow(0 0 13px rgba(255, 205, 110, .85)) brightness(1.14); }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .mc-carte.jouable { animation: none; filter: drop-shadow(0 0 8px rgba(255, 205, 110, .7)); }
}
/* AU DOIGT, LE HALO RESPIRE PAR SON OPACITE, PAS PAR `filter`.
   Un `filter` anime ne se compose pas : chaque carte jouable etait repeinte,
   image apres image, pendant tout le tour -- au telephone, autant de temps
   pris a la table 3D. Le halo passe sur un pseudo-element dont seule
   l'opacite varie, ce que le compositeur fait seul. */
@media (hover: none), (pointer: coarse) {
  .mc-carte.jouable { animation: none; filter: drop-shadow(0 0 5px rgba(245, 185, 66, .45)); }
  .mc-carte.jouable::after {
    content: ''; position: absolute; inset: -2px; border-radius: 8px;
    box-shadow: 0 0 14px 2px rgba(255, 205, 110, .8);
    opacity: .2; pointer-events: none;
    animation: mc-jouable-doigt 2.2s ease-in-out infinite;
  }
  .mc-carte.jouable.survol::after,
  .mc-carte.jouable.is-on::after { animation: none; opacity: 0; }
  /* Le brouillard flou qui derive par-dessus la table : un flou de 28 px
     recompose a chaque image, pour une nappe a peine visible. Il reste, fige. */
  .arena-fog { animation: none; }
  /* Le puits de lumiere : un flou de 58 px fondu en `screen` SUR la table 3D.
     Le mode de fusion oblige a recomposer tout le voile a chaque image du
     canvas qu'il recouvre, et il pulsait en plus. Au doigt, un simple
     degrade translucide, fixe : le meme halo a l'oeil. */
  .arena-shaft { filter: none; mix-blend-mode: normal; animation: none; opacity: .5; }
  .arena-floor { filter: none; }
  /* Les runes respiraient par `letter-spacing` : une mise en page par image. */
  .arena-runes { animation: none; opacity: .7; }
}
@keyframes mc-jouable-doigt { 50% { opacity: 1; } }
@media (hover: none) and (prefers-reduced-motion: reduce), (pointer: coarse) and (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .mc-carte.jouable::after { animation: none; opacity: .7; }
}

/* ── GRAND ECRAN : DE LA PLACE POUR LA MAIN, ET POUR LA TABLE ─────────────
 *
 * Trois choses se tiennent, et il faut les trois ensemble :
 *
 *   1. LE PUPITRE PERD SON PORTRAIT. Il montrait le visage de celui dont
 *      c'est le tour -- mais les deux visages sont DEJA sur la planche,
 *      sertis dans leur anneau d'or, de part et d'autre de la Roue. Le
 *      panneau les repetait, et cette repetition coutait cent pixels de haut
 *      et une bonne part de sa largeur. Il ne garde que ce qui ne se lit
 *      nulle part ailleurs : ou l'on en est, et ce qu'on peut faire.
 *
 *   2. LA TABLE S'ETALE VERS LA DROITE, de tout ce que le pupitre a rendu.
 *
 *   3. LA MAIN PREND LA GAUCHE, en grand. Une carte y fait plus du double de
 *      sa largeur d'avant : on la reconnait sans la survoler, et le survol en
 *      montre le detail (voir `.mc-apercu`).
 */
@media (min-width: 1180px) {
  /* La largeur est declaree sur .match : la barre du haut en a besoin autant
     que la table, et elle n'est pas dans la table. */
  .match { --main-l: 250px; --module-l: 268px; }
  /*  ECRAN LARGE MAIS BAS (22/10/2026, une tele 4K a 300 % : 1280 x 595 CSS) :
   *  a 250 px, une carte de la main faisait 340 px de haut, et sept cartes
   *  empilees n'en montraient plus que le nom. La largeur suit la hauteur ;
   *  au-dela de 770 px de haut, rien ne change. */
  @media (max-height: 770px) {
    .match { --main-l: max(170px, calc(28vh + 34px)); }
  }
  /*  LE PLATEAU EST CENTRE ENTRE SES DEUX BORDS.
   *  La main mangeait la gauche du cadre et le pupitre la droite, mais seule
   *  la main etait deduite : le canvas debordait sous le pupitre, et le
   *  plateau -- centre dans le canvas -- se posait donc trop a droite, a
   *  moitie cache par la colonne. On rend au cadre ses DEUX marges : 252 px
   *  de pupitre plus ses 16 px de retrait contre la paroi. */
  .table3d { padding-left: var(--main-l); padding-right: var(--module-l); }
  /* La barre d'abandon etait calee a 128 px, soit juste a droite de
     l'ancienne colonne. */
  .wheel-bar { left: calc(var(--main-l) + 14px); }

  /* Le pupitre, reduit a ce qu'il dit. */
  .game-module { width: 208px; padding: 11px; }
  .duel-portrait { display: none; }

  .main-col {
    --main-grande: 1;
    left: 12px; width: calc(var(--main-l) - 34px);
    /* Les cartes sont posees une a une, en absolu (`disposerLaMain`) : la
       colonne n'est plus une pile qui coule, c'est un plan. */
    display: block; overflow: visible;
  }
  .main-col::before { inset: -10px -18px -10px -14px; }
  .main-col::after { right: -18px; }

  /*  UNE CARTE DE LA MAIN.
   *
   *  Seul `top` est pose par le script (`disposerLaMain`) : le recouvrement
   *  depend du NOMBRE de cartes, et une feuille de style ne sait pas compter.
   *  Tout le reste -- la matiere, le relief, ce que fait le survol --
   *  appartient a la feuille de style.
   */
  .mc-carte {
    position: absolute; left: 0; width: 100%;
    transition: transform .16s ease, filter .16s ease;
    border-radius: 8px;
    filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .7));
  }
  .mc-carte img { border-radius: 8px; }

  /*  LE SURVOL SORT LA CARTE DU JEU.
   *  Elle avance vers la table et passe au-dessus de ses voisines -- le geste
   *  qu'on fait avec de vraies cartes en main. Le detail, lui, s'affiche en
   *  grand a cote (`.mc-apercu`).
   */
  .mc-carte.survol,
  .mc-carte.is-on {
    transform: translateX(18px) scale(1.05);
    z-index: 60 !important;
    filter: drop-shadow(0 10px 26px rgba(0, 0, 0, .9)) brightness(1.06);
  }

  /* L'apercu se pose a droite de la main, au-dessus de la table. */
  .table3d .mc-apercu { left: calc(var(--main-l) + 16px); width: 320px; }
  .arena-filigree .filigree-tl,
  .arena-filigree .filigree-bl { left: calc(var(--main-l) + 14px); }
}

/* ── AU LARGE, LE PUPITRE EST UNE COLONNE ENTIERE ─────────────────────────
 *
 *  Il tenait dans un petit rectangle cale en haut a droite, dimensionne sur
 *  son contenu : trois options serrees a dix pixels, des libelles tronques en
 *  points de suspension, et le drapeau d'abandon parti vivre tout seul dans
 *  le coin oppose de l'ecran. Tout ce qui S'ADRESSE AU JOUEUR -- ou l'on en
 *  est, ce qu'il reste a faire, et les deux gestes qui closent son tour --
 *  etait donc disperse sur les deux bords, et aucun n'avait la place de se
 *  dire correctement.
 *
 *  Le pupitre prend maintenant toute la hauteur de la scene, comme un vrai
 *  tableau de bord pose contre la paroi droite de l'arene. La place gagnee ne
 *  sert pas a en dire plus : elle sert a le dire mieux -- les options
 *  respirent, les libelles tiennent en entier, et le bas de la colonne
 *  devient la barre des gestes : « Finir le tour », puis, sous un filet,
 *  l'abandon.
 *
 *  L'abandon n'est pas deplace dans le HTML : il sert aussi au portrait, ou
 *  il est une pastille ronde posee sur le plateau, et le pupitre y est une
 *  grille de trois lignes fixes qui ne lui ferait pas de case. Il est ICI
 *  aligne sur la derniere ligne du pupitre, que celui-ci lui reserve
 *  (`padding-bottom`).
 */
@media (min-width: 1180px) {
  .game-module {
    top: 16px; bottom: 16px; right: 16px; width: 252px;
    /* Le bas appartient a la barre des gestes : on le lui garde. */
    padding: 15px 13px 58px;
    display: flex; flex-direction: column;
    overflow: hidden;
  }
  .game-module::before { inset: 8px; border-radius: 3px; }

  .module-label { margin-bottom: 13px; font-size: 11px; letter-spacing: .26em; }
  .module-rule { margin: 13px 5px; }

  /*  LE CORPS DU PUPITRE.
   *  Il occupe tout ce qui reste entre l'etat du tour et les gestes. C'est la
   *  seule partie qui defile, et elle ne defile presque jamais : c'est la
   *  reserve, pour le jour ou une invite sera plus longue que prevu. */
  .game-module .prompt {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overscroll-behavior: contain;
    justify-content: flex-start; gap: 10px;
  }
  .game-module .prompt::-webkit-scrollbar { width: 4px; }
  .game-module .prompt::-webkit-scrollbar-thumb {
    background: rgba(201, 162, 70, .3); border-radius: 2px;
  }

  .game-module .prompt-kicker { font-size: 10px; letter-spacing: .2em; }
  .game-module .prompt .msg { font-size: 12.5px; line-height: 1.5; }

  /*  LES OPTIONS, AU LARGE.
   *  Le libelle etait mesure a 10 px « parce que le pupitre ne fait que 232 px
   *  de large » et coupe net a la premiere lettre de trop. La colonne est plus
   *  large et la ligne peut se plier : on rend au texte sa taille, et au
   *  mereau les six pixels qui le font lire comme un jeton. */
  .game-module .registre { gap: 7px; }
  .game-module .opt {
    grid-template-columns: 26px minmax(0, 1fr) auto;
    gap: 10px; padding: 10px 11px 10px 11px;
    border-radius: 8px;
  }
  .game-module .opt::before { top: 7px; bottom: 7px; width: 3px; }
  .game-module .opt-rang { width: 26px; height: 26px; font-size: 11px; }
  .game-module .opt-nom b {
    font-size: 11.5px; letter-spacing: .015em;
    white-space: normal; overflow: visible; text-overflow: clip;
  }
  .game-module .opt-valeur { font-size: 11px; }

  /*  LA LIGNE QUI RAPPELLE LE GESTE tombe au pied du corps, contre les
   *  gestes -- pas juste sous la derniere option, ou elle se lisait comme une
   *  quatrieme ligne du registre. */
  .game-module .prompt .c-meta {
    margin-top: auto; padding-top: 11px;
    border-top: 1px solid rgba(201, 162, 70, .16);
    font-size: 10.5px; line-height: 1.45;
  }

  .module-end-turn {
    flex: 0 0 auto; margin-top: 13px;
    padding: 11px 10px; font-size: 11px;
  }

  /*  LA DERNIERE LIGNE DU PUPITRE : renoncer, et regler le fond.
   *  Le bloc flotte librement sur la scene ; on l'aligne au pixel sur la
   *  colonne de contenu du pupitre -- 16 px de marge, plus ses 13 px de
   *  rembourrage. */
  .wheel-bar {
    left: auto; right: 29px; top: auto; bottom: 27px;
    width: 226px; z-index: 37; gap: 7px;
  }
  .wheel-bar::before {
    content: ''; position: absolute; left: 0; right: 0; top: -13px;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(201, 162, 70, .34) 18% 82%, transparent);
  }
  .match-actions { flex: 1 1 auto; }
  .arena-ctrl-palette { flex: 0 0 auto; width: 32px; padding-inline: 0; }
}

/* L'apercu : une seule case, toujours au meme endroit. Passer d'une carte a
   l'autre n'y change que l'image -- aucun mouvement, donc aucun aller-retour
   a rattraper. */
.mc-apercu {
  position: absolute; left: 132px; top: 50%;
  transform: translateY(-50%);
  width: 300px; max-width: 34vw;
  pointer-events: none; z-index: 45;
  opacity: 0; transition: opacity .16s ease;
  display: flex; flex-direction: column; gap: 8px;
}
.mc-apercu.vu { opacity: 1; }
.mc-apercu img, .mc-apercu .mc-apercu-img {
  display: block; width: 100%; border-radius: 12px;
  filter: drop-shadow(0 14px 34px rgba(0, 0, 0, .85));
}

/* Panneau de statistiques et statut en direct au survol */
.mc-apercu-live {
  background: rgba(10, 14, 22, 0.94);
  border: 1px solid rgba(245, 185, 66, 0.35);
  border-radius: 10px;
  padding: 10px 12px;
  backdrop-filter: blur(10px);
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.8), inset 0 0 15px rgba(245, 185, 66, 0.08);
  display: flex; flex-direction: column; gap: 6px;
  animation: apercuPop 0.18s ease-out;
}

@keyframes apercuPop {
  from { transform: translateY(6px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.mc-live-hp-row {
  display: flex; justify-content: space-between; align-items: baseline;
}
.mc-live-hp-label {
  font-family: var(--font-num);
  font-size: 15px; font-weight: 700;
  color: #fff;
}
.mc-live-hp-val {
  font-size: 20px; font-weight: 900;
  color: #52d987;
  text-shadow: 0 0 10px rgba(82, 217, 135, 0.6);
}
.mc-live-hp-val.low {
  color: #ff5a5a;
  text-shadow: 0 0 10px rgba(255, 90, 90, 0.7);
}
.mc-live-hp-unit {
  font-size: 12px; color: var(--ink-faint); font-weight: 600;
}
/*  « si le de passe » : la retenue du potentiel. Voir `.vie-texte.est-pari`. */
.mc-live-pari {
  font-size: 11px; font-weight: 700; color: #ffd98a; letter-spacing: .02em;
  white-space: nowrap;
}
.mc-live-atk {
  font-family: var(--font-title);
  font-size: 14px; font-weight: 800;
  color: #ff8b8b;
}
.mc-live-atk.boosted {
  color: #ffc857;
  text-shadow: 0 0 10px rgba(255, 200, 87, 0.6);
}

.mc-live-bar {
  height: 6px; border-radius: 3px;
  background: rgba(45, 12, 16, 0.8);
  overflow: hidden; border: 1px solid rgba(0, 0, 0, 0.6);
}
.mc-live-fill {
  height: 100%;
  background: linear-gradient(90deg, #3db872, #68f0a4);
  box-shadow: 0 0 8px rgba(104, 240, 164, 0.8);
  transition: width 0.3s ease;
}
.mc-live-bar.low .mc-live-fill {
  background: linear-gradient(90deg, #c72c3b, #ff5a6a);
  box-shadow: 0 0 8px rgba(255, 90, 106, 0.8);
}

.mc-live-meta {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; font-weight: 600; color: #a9b7cf;
}
.mc-live-nrj {
  color: #60c8ff;
  text-shadow: 0 0 8px rgba(96, 200, 255, 0.6);
}
.mc-live-tag {
  padding: 2px 6px; border-radius: 4px; font-size: 11px;
}
.mc-live-tag.sleep { background: rgba(30, 60, 120, 0.6); color: #b8deff; }
.mc-live-tag.acted { background: rgba(60, 60, 70, 0.6); color: #d0d0d8; }
/* Un etat (coma, radiation, bouclier...) : sa couleur vient de `etatsVisibles`. */
.mc-live-tag.etat { background: rgba(14, 12, 22, 0.72); color: var(--etat, #eee);
  box-shadow: inset 0 0 0 1px var(--etat, #888);
  display: inline-flex; align-items: center; gap: 4px; }
/*  Glyphe d'etat : card-render/icons/Etat_*.png, deja en couleur. */
.etat-ico {
  display: block; flex: none; width: 14px; height: 14px;
  background: var(--ico) center / contain no-repeat;
}
.step-num:has(.etat-ico):not(.etats-trio) { width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; }
.step-num .etat-ico { width: 28px; height: 28px; }
.step-num.etats-trio {
  width: auto; height: 34px; padding: 0 6px; gap: 4px;
  display: inline-flex; align-items: center; border-radius: 17px;
}
.step-num.etats-trio .etat-ico { width: 24px; height: 24px; }
.loupe-mod.etat { align-items: flex-start; }
.loupe-mod.etat .etat-ico { width: 20px; height: 20px; margin-top: 0; }

/* Badge de résistance Duo / Trio dans l'aperçu */
.mc-live-shield {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 10px; border-radius: 6px;
  font-size: 11px; font-weight: 800;
  margin-top: 2px;
}
.mc-live-shield.duo {
  background: linear-gradient(90deg, rgba(20, 50, 90, 0.85) 0%, rgba(10, 25, 50, 0.85) 100%);
  border: 1px solid #5ec9ff;
  color: #d8f2ff;
  box-shadow: 0 0 10px rgba(94, 201, 255, 0.35);
}
.mc-live-shield.trio {
  background: linear-gradient(90deg, rgba(80, 55, 10, 0.9) 0%, rgba(45, 30, 5, 0.9) 100%);
  border: 1px solid #ffd15c;
  color: #fff2c7;
  box-shadow: 0 0 14px rgba(255, 209, 92, 0.5);
}
.mc-live-shield .shield-title {
  font-family: var(--font-title);
  letter-spacing: 0.05em;
}
/*  LA LIGNE QUI DIT QUOI FAIRE -- OU POURQUOI ON NE PEUT PAS.
    Elle se detache du reste par un filet, parce qu'elle ne decrit pas la
    creature : elle s'adresse au joueur. */
.mc-live-geste {
  margin-top: 7px; padding-top: 7px;
  border-top: 1px solid rgba(201, 162, 70, .22);
  font-size: 11.5px; line-height: 1.35;
  color: var(--accent);
}
.mc-live-geste + .mc-live-geste { margin-top: 3px; padding-top: 0; border-top: 0; }
.mc-live-geste.bloque { color: #b9a9c4; }
.mc-live-shield .shield-desc {
  font-weight: 700;
  color: #fff;
}

.mc-vide { color: var(--ink-faint); font-size: 11px; pointer-events: none; }

/* Beaucoup de cartes : on les fait se chevaucher plutot que deborder. */
/* Au-dela de quatre cartes la colonne depassait par le bas. On les fait se
   chevaucher, comme une main tenue : le haut de chaque carte -- son nom et
   son element -- reste visible, et le survol deplie celle qu'on vise. */
.main-col.serre { gap: 0; }
.main-col.serre .mc-carte { margin-bottom: calc(-1 * var(--chevauche, 40px)); }
.main-col.serre .mc-carte:last-child { margin-bottom: 0; }
.main-col.serre .mc-carte.survol { z-index: 50; }

/* ── La Roue, en haut a droite de la table ────────────────────────────────
   Faite des memes icones que celles gravees sur les cartes. Le cadre reprend
   le langage des cartes : metal sombre, biseau, liseré -- le dos de carte n'a
   pas encore de motif dessine, on ne pouvait donc pas le citer directement. */
/*  LE CADRAN HTML EST PARTI, ET C'EST LA FUSION DES PLATEAUX.
 *
 *  Il vivait ici : un disque de six pastilles, mesure sur `--roue-d`, pose
 *  dans le pupitre au large et dans un coin de l'ecran en portrait. La Roue
 *  est maintenant SERTIE AU CENTRE DE LA PLANCHE, en 3D (table3d.js,
 *  `_sertirRoue`) -- l'afficher aussi dans un coin, c'etait garder la
 *  redondance que la fusion des deux plateaux venait supprimer.
 *
 *  `.hero-roue*`, plus haut, est une AUTRE chose : le blason du heros dans le
 *  portrait du duel. Il reste.
 */

/* ── Le recit vivant de la partie & Effets de Combat Épiques ──────────────
   VFX Élémentaires cinématiques, projectiles, impacts, screen shake et dégâts */
.battle-fx {
  position: absolute; inset: 0; z-index: 38;
  pointer-events: none; overflow: hidden;
}

/* ── Screen Shake & Screen Flash ─────────────────────────────────────────── */
.screen-shake-light {
  animation: shakeLight 0.35s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
.screen-shake-heavy {
  animation: shakeHeavy 0.55s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
@keyframes shakeLight {
  10%, 90% { transform: translate3d(-2px, 1px, 0); }
  20%, 80% { transform: translate3d(3px, -2px, 0); }
  30%, 50%, 70% { transform: translate3d(-3px, 2px, 0); }
  40%, 60% { transform: translate3d(2px, -1px, 0); }
}
@keyframes shakeHeavy {
  10%, 90% { transform: translate3d(-6px, 4px, 0) rotate(-0.5deg); }
  20%, 80% { transform: translate3d(8px, -5px, 0) rotate(0.6deg); }
  30%, 50%, 70% { transform: translate3d(-9px, 6px, 0) rotate(-0.8deg); }
  40%, 60% { transform: translate3d(6px, -4px, 0) rotate(0.4deg); }
}

.hit-flash-overlay {
  position: absolute; inset: 0; z-index: 50;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%, var(--flash-col, rgba(255,255,255,0.75)) 0%, transparent 70%);
  animation: hitFlashAnim 0.38s ease-out forwards;
}
@keyframes hitFlashAnim {
  0% { opacity: 0.9; }
  100% { opacity: 0; }
}

.fx {
  position: absolute; transform: translate(-50%, -50%);
  pointer-events: none; white-space: nowrap;
  font-family: var(--font-title); font-size: 13px; font-weight: 900; letter-spacing: .08em;
  text-shadow: 0 2px 12px #000, 0 0 6px #000;
}

/* ── L'ÉNERGIE DONNÉE OU ARRACHÉE (01/11/2026, main.js `effetEnergieSurTable`) ──
   Donnée : les grains convergent, le halo s'allume, le chiffre claque et les
   pastilles s'allument une a une. Arrachée : une dechirure, les grains
   eclatent vers l'exterieur, le chiffre tremble et les pastilles se brisent.
   --c : la teinte (element, or de l'Aube, violet de la Faille). */
.nrj-fx {
  position: absolute; width: 0; height: 0; pointer-events: none; z-index: 6;
  --c: #ffd27a; --c2: #fff;
}
.nrj-fx > * { position: absolute; left: 0; top: 0; }
.nf-halo {
  width: 200px; height: 200px; border-radius: 50%; transform: translate(-50%, -50%);
  background: radial-gradient(circle, color-mix(in srgb, var(--c) 60%, transparent) 0%,
    color-mix(in srgb, var(--c) 20%, transparent) 42%, transparent 70%);
  animation: nfHalo 1.5s ease-out forwards;
}
.nf-onde {
  width: 60px; height: 60px; border-radius: 50%; transform: translate(-50%, -50%);
  border: 3px solid var(--c); opacity: 0;
  box-shadow: 0 0 16px var(--c), inset 0 0 10px var(--c);
}
.nrj-fx.gain .nf-onde { animation: nfOndeEntre .62s .26s cubic-bezier(.3, .6, .3, 1) forwards; }
.nrj-fx.gain .nf-onde2 { animation-delay: .4s; }
.nrj-fx.perte .nf-onde { animation: nfOndeSort .7s cubic-bezier(.2, .7, .3, 1) forwards; }
.nrj-fx.perte .nf-onde2 { animation-delay: .14s; }
.nf-grain {
  width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0 25%, var(--c) 55%, transparent 72%);
  box-shadow: 0 0 10px var(--c);
  opacity: 0;
}
.nrj-fx.gain .nf-grain { animation: nfConverge .5s var(--d) cubic-bezier(.55, 0, .9, .45) forwards; }
.nrj-fx.perte .nf-grain { animation: nfEclate .8s var(--d) cubic-bezier(.15, .7, .3, 1) forwards; }
/* La dechirure : un eclair brise en travers de la carte. */
.nf-dechirure {
  width: 120px; height: 120px; transform: translate(-50%, -50%) rotate(-18deg);
  background:
    linear-gradient(90deg, transparent 47%, #fff 49%, var(--c) 50%, #fff 51%, transparent 53%);
  clip-path: polygon(46% 0, 56% 0, 50% 30%, 60% 34%, 46% 66%, 54% 70%, 44% 100%, 40% 100%, 47% 72%, 38% 67%, 52% 36%, 42% 31%);
  filter: drop-shadow(0 0 8px var(--c));
  opacity: 0;
  animation: nfDechire .55s ease-out forwards;
}
.nf-tete {
  display: flex; align-items: center; gap: 8px;
  transform: translate(-50%, -50%);
  animation: nfTete 1.75s cubic-bezier(.2, 1.3, .35, 1) forwards;
}
.nrj-fx.perte .nf-tete { animation: nfTetePerte 1.75s ease-out forwards; }
/*  Le chiffre : le metal des titres du duel (duel_jeu.css, .turn-banner),
    teinte de l'element -- blanc au sommet, la couleur au ventre, sombre au
    pied --, un eclat qui le traverse une fois. Ni contour (-webkit-text-stroke
    sur le Cinzel 900 empatait la lettre) ni text-shadow (il couvrirait l'or
    decoupe dans la lettre) : l'ombre et la lueur passent par filter. */
.nf-chiffre {
  display: flex; align-items: flex-start;
  font: 700 54px/1 var(--font-num); font-variation-settings: 'opsz' 144;
  font-variant-numeric: lining-nums; letter-spacing: -.01em;
  padding: 0 .04em;
  background-image:
    linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .95) 50%, transparent 60%),
    linear-gradient(180deg, #fff 0%, color-mix(in srgb, var(--c) 22%, #fff) 32%,
      var(--c) 64%, color-mix(in srgb, var(--c) 50%, #000) 100%);
  background-size: 300% 100%, 100% 100%;
  background-position: 150% 0, 0 0;
  background-repeat: no-repeat;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, .85))
    drop-shadow(0 2px 0 color-mix(in srgb, var(--c) 25%, #000))
    drop-shadow(0 0 14px color-mix(in srgb, var(--c) 80%, transparent));
  animation: nfEclat .9s .32s ease-out both;
}
/*  Le signe en petit corps optique (opsz 9) : au 144 du chiffre, le « + »
    de Fraunces n'est qu'un trait de cheveu. */
.nf-signe {
  font: inherit; font-size: .58em; line-height: 1;
  font-variation-settings: 'opsz' 9;
  margin: .14em .05em 0 0;
}
.nf-pts { display: flex; gap: 5px; }
.nf-pt {
  width: 16px; height: 16px; border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #fff 0 18%, var(--c2) 40%, var(--c) 75%);
  border: 1.5px solid rgba(255, 255, 255, .85);
  box-shadow: 0 0 12px var(--c);
}
.nrj-fx.gain .nf-pt { opacity: 0; animation: nfPtAllume .34s calc(.42s + var(--i) * .12s) cubic-bezier(.2, 1.6, .4, 1) forwards; }
.nrj-fx.perte .nf-pt { animation: nfPtBrise .5s calc(.2s + var(--i) * .1s) ease-in forwards; }
/*  Le nom : une legende gravee, pas un second titre. Cinzel 700, petit et
    tres espace, ivoire a peine teinte, entre deux filets de la couleur ; une
    ombre serree pour se lire sur n'importe quelle carte. Le retrait a gauche
    rend l'espacement de la derniere lettre : le mot reste centre. */
.nf-nom, .nf-pouvoir {
  display: flex; align-items: center; gap: 9px;
  transform: translate(-50%, 0); white-space: nowrap;
  font-family: var(--font-title); font-weight: 700; text-transform: uppercase;
  color: color-mix(in srgb, var(--c) 18%, #fbf1dc);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .9), 0 0 6px rgba(0, 0, 0, .85),
    0 0 14px color-mix(in srgb, var(--c) 55%, transparent);
}
.nf-nom { top: 33px; font-size: 12.5px; letter-spacing: .32em; text-indent: .32em; animation: nfNom 1.75s ease-out forwards; }
.nf-nom::before, .nf-nom::after {
  content: ''; width: 22px; height: 1px; flex: none;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--c) 60%, #fff3d0));
  box-shadow: 0 0 6px var(--c);
}
.nf-nom::after { transform: scaleX(-1); }
.nf-pouvoir {
  top: 54px; font-size: 10px; font-weight: 600; letter-spacing: .3em; text-indent: .3em;
  color: color-mix(in srgb, var(--c2) 45%, #fbf1dc);
  animation: nfNom 1.75s .08s ease-out both;
}
.nrj-fx.perte .nf-nom { color: #ffd9d2; }
@keyframes nfEclat {
  0%, 10% { background-position: 150% 0, 0 0; }
  100% { background-position: -50% 0, 0 0; }
}

@keyframes nfHalo {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.3); }
  20% { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.25); }
}
@keyframes nfOndeEntre {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(3); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(.6); }
}
@keyframes nfOndeSort {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(.4); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(3.2); }
}
@keyframes nfConverge {
  0% { opacity: 0; transform: rotate(var(--a)) translateX(var(--r)) scale(1.4); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: rotate(var(--a)) translateX(0) scale(.4); }
}
@keyframes nfEclate {
  0% { opacity: 1; transform: rotate(var(--a)) translateX(0) scale(1.3); }
  100% { opacity: 0; transform: rotate(var(--a)) translateX(var(--r)) translateY(26px) scale(.3); }
}
@keyframes nfDechire {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(-18deg) scaleY(.2); }
  25% { opacity: 1; transform: translate(-50%, -50%) rotate(-18deg) scaleY(1.1); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(-18deg) scale(1.3, 1); }
}
@keyframes nfTete {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.3); }
  22% { opacity: 1; transform: translate(-50%, -50%) scale(1.25); }
  34% { transform: translate(-50%, -50%) scale(1); }
  75% { opacity: 1; transform: translate(-50%, -78%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -110%) scale(.92); }
}
@keyframes nfTetePerte {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(1.5); }
  12% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  18% { transform: translate(calc(-50% - 7px), -50%); }
  24% { transform: translate(calc(-50% + 6px), -50%); }
  30% { transform: translate(calc(-50% - 4px), -50%); }
  36% { transform: translate(-50%, -50%); }
  75% { opacity: 1; transform: translate(-50%, -30%); }
  100% { opacity: 0; transform: translate(-50%, -10%) scale(.95); }
}
@keyframes nfPtAllume {
  0% { opacity: 0; transform: scale(2.2); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes nfPtBrise {
  0% { opacity: 1; transform: scale(1); }
  35% { opacity: 1; transform: scale(1.35); filter: brightness(2); }
  100% { opacity: 0; transform: translateY(18px) scale(.2) rotate(70deg); }
}
@keyframes nfNom {
  0%, 15% { opacity: 0; transform: translate(-50%, 8px); }
  30% { opacity: 1; transform: translate(-50%, 0); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -14px); }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .nrj-fx .nf-grain, :where(html:not(.mouvement-plein)) .nrj-fx .nf-onde, :where(html:not(.mouvement-plein)) .nrj-fx .nf-dechirure { display: none; }
}

/* ── L'état reçu : l'icône jaillit sur la carte puis rejoint sa pastille ── */
.etat-recu {
  position: absolute; width: 0; height: 0; pointer-events: none; z-index: 5;
  --c: #fff;
}
.etat-recu > * { position: absolute; left: 0; top: 0; transform: translate(-50%, -50%); }
.etat-recu .er-halo {
  width: 190px; height: 190px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--c) 55%, transparent) 0%,
    color-mix(in srgb, var(--c) 18%, transparent) 45%, transparent 70%);
  animation: er-halo 1.9s ease-out forwards;
}
.etat-recu .er-rayons {
  width: 230px; height: 230px; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    color-mix(in srgb, var(--c) 70%, transparent) 0deg 4deg, transparent 4deg 22deg);
  -webkit-mask-image: radial-gradient(circle, transparent 18%, #000 30%, transparent 68%);
          mask-image: radial-gradient(circle, transparent 18%, #000 30%, transparent 68%);
  animation: er-rayons 1.4s ease-out forwards;
}
.etat-recu .er-onde {
  width: 70px; height: 70px; border-radius: 50%;
  border: 4px solid var(--c);
  box-shadow: 0 0 18px var(--c), inset 0 0 12px var(--c);
  animation: er-onde .9s cubic-bezier(.2, .7, .3, 1) forwards;
}
.etat-recu .er-onde2 { animation-delay: .18s; opacity: 0; }
.etat-recu .er-ico {
  width: 96px; height: 96px; object-fit: contain;
  filter: drop-shadow(0 0 10px var(--c)) drop-shadow(0 4px 8px rgba(0, 0, 0, .8));
  animation: er-ico 1.9s cubic-bezier(.2, .8, .3, 1) forwards;
}
.etat-recu .er-nom {
  top: 66px; white-space: nowrap;
  font-family: var(--font-title); font-size: 17px; font-weight: 900; letter-spacing: .1em;
  text-transform: uppercase; color: #fff;
  text-shadow: 0 0 10px var(--c), 0 0 3px var(--c), 0 2px 6px #000;
  animation: er-nom 1.9s ease-out forwards;
}
@keyframes er-halo {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.3); }
  15% { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
  60% { opacity: .8; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.2); }
}
@keyframes er-rayons {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.4) rotate(0deg); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.3) rotate(40deg); }
}
@keyframes er-onde {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(.3); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(3); }
}
@keyframes er-ico {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.1) rotate(-25deg); }
  14% { opacity: 1; transform: translate(-50%, -50%) scale(1.35) rotate(6deg); }
  24% { opacity: 1; transform: translate(-50%, -50%) scale(.95) rotate(0deg); }
  32%, 66% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  90% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--fx, -34px)), calc(-50% + var(--fy, -30px))) scale(.28); }
}
@keyframes er-nom {
  0%, 10% { opacity: 0; transform: translate(-50%, -30%) scale(.8); }
  22% { opacity: 1; transform: translate(-50%, -50%) scale(1.08); }
  30%, 70% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -80%) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .etat-recu .er-rayons, :where(html:not(.mouvement-plein)) .etat-recu .er-onde { display: none; }
}

/* ── Projectiles & Faisceaux d'Attaque Élémentaires ───────────────────────── */
.attack-beam {
  height: 8px; transform-origin: 0 50%;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #fff 30%, #ff8a3d 75%, transparent);
  box-shadow: 0 0 14px #ff7a33, 0 0 32px rgba(255, 110, 50, 0.95);
  animation: beamShot .68s cubic-bezier(.12, .75, .22, 1) forwards;
}

/* 🔥 FEU : Météore ardent flamboyant */
.attack-beam.el-feu {
  height: 12px;
  background: linear-gradient(90deg, transparent, #fff 15%, #ffcc00 40%, #ff3b00 80%, transparent);
  box-shadow: 0 0 20px #ff3700, 0 0 45px #ff7700, 0 0 8px #fff;
  filter: drop-shadow(0 0 10px #ff2200);
}
.attack-beam.el-feu::after {
  content: ""; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #ffaa00 50%, #ff2200 100%);
  box-shadow: 0 0 25px #ff4400, 0 0 10px #fff;
}

/* 💧 EAU : Torrent liquide turquoise et javelot de glace */
.attack-beam.el-eau {
  height: 10px;
  background: linear-gradient(90deg, transparent, #e0ffff 20%, #00d4ff 60%, #0055ff 85%, transparent);
  box-shadow: 0 0 18px #00bfff, 0 0 40px rgba(0, 140, 255, 0.9);
}
.attack-beam.el-eau::after {
  content: ""; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #00f0ff 60%, #0066ff 100%);
  box-shadow: 0 0 20px #00e1ff;
}

/* 🌪️ AIR : Double vortex supersonique tranchant */
.attack-beam.el-air {
  height: 9px;
  background: linear-gradient(90deg, transparent, #ffffff 30%, #a6f4ff 65%, #4dc3ff 85%, transparent);
  box-shadow: 0 0 16px #80ecff, 0 0 35px #00a2ff;
}
.attack-beam.el-air::after {
  content: ""; position: absolute; right: 0; top: 50%; transform: translateY(-50%) rotate(45deg);
  width: 28px; height: 10px; border-radius: 4px;
  background: #fff; box-shadow: 0 0 18px #a6f4ff;
}

/* ⛰️ TERRE : Traînée tellurique et éclats de roche dorée */
.attack-beam.el-terre {
  height: 12px;
  background: linear-gradient(90deg, transparent, #ffe89e 20%, #d49a37 60%, #704415 85%, transparent);
  box-shadow: 0 0 18px #e6a83e, 0 0 38px rgba(160, 100, 30, 0.9);
}

/* ☀️ LUMIÈRE : Faisceau céleste sacré incandescent */
.attack-beam.el-lumiere {
  height: 14px;
  background: linear-gradient(90deg, transparent, #ffffff 10%, #fffbe0 40%, #ffd700 75%, transparent);
  box-shadow: 0 0 25px #ffe066, 0 0 60px #ffb700, 0 0 12px #ffffff;
}
.attack-beam.el-lumiere::after {
  content: ""; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #ffe680 50%, transparent 80%);
  box-shadow: 0 0 30px #ffd700;
}

/* 🔮 ÉTHER : Faille cosmique et distorsion nébuleuse violette */
.attack-beam.el-ether {
  height: 11px;
  background: linear-gradient(90deg, transparent, #ffccff 15%, #c040ff 55%, #6600cc 85%, transparent);
  box-shadow: 0 0 22px #c44dff, 0 0 50px rgba(150, 0, 255, 0.95);
}
.attack-beam.el-ether::after {
  content: ""; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 24px; height: 24px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #d966ff 50%, #440099 100%);
  box-shadow: 0 0 28px #bf00ff;
}

/* Surpuissance Ascendance */
.attack-beam.is-ascendant {
  height: 16px;
  filter: brightness(1.3) saturate(1.4);
}

@keyframes beamShot {
  0% { clip-path: inset(0 100% 0 0); opacity: 0; transform: rotate(var(--rot, 0deg)) scaleY(0.4); }
  22% { clip-path: inset(0 0 0 0); opacity: 1; transform: rotate(var(--rot, 0deg)) scaleY(1.25); }
  68% { opacity: 1; }
  100% { clip-path: inset(0 0 0 100%); opacity: 0; transform: rotate(var(--rot, 0deg)) scaleY(0.7); }
}

/* ── Déflagrations & Impacts Épiques par Élément ─────────────────────────── */
.impact-explosion {
  position: absolute; transform: translate(-50%, -50%);
  width: 140px; height: 140px; pointer-events: none;
  display: grid; place-items: center; z-index: 45;
}

/* 🔥 Explosion Volcanique */
.impact-explosion.imp-feu::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #ff7700 35%, #ff1100 65%, transparent 80%);
  box-shadow: 0 0 50px #ff3b00, 0 0 100px #ff8800;
  animation: blastBurst 0.65s cubic-bezier(0.1, 0.85, 0.25, 1) forwards;
}
.impact-explosion.imp-feu::after {
  content: ""; position: absolute; inset: -20px; border-radius: 50%;
  border: 4px solid #ffaa00;
  box-shadow: 0 0 35px #ff4400;
  animation: ringExpand 0.55s ease-out forwards;
}

/* 💧 Onde Aquatique & Gel */
.impact-explosion.imp-eau::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #00e5ff 40%, #0066ff 70%, transparent 85%);
  box-shadow: 0 0 45px #00bfff, 0 0 80px #0044ff;
  animation: blastBurst 0.65s cubic-bezier(0.1, 0.85, 0.25, 1) forwards;
}
.impact-explosion.imp-eau::after {
  content: ""; position: absolute; inset: -15px; border-radius: 50%;
  border: 3px solid #b3f5ff;
  box-shadow: 0 0 30px #00f0ff;
  animation: ringExpand 0.52s ease-out forwards;
}

/* 🌪️ Dual Cross Slash Air */
.impact-explosion.imp-air::before {
  content: ""; position: absolute; width: 130px; height: 8px; border-radius: 4px;
  background: #fff; box-shadow: 0 0 30px #a6f4ff, 0 0 60px #00a2ff;
  transform: rotate(45deg);
  animation: slashCross 0.5s ease-out forwards;
}
.impact-explosion.imp-air::after {
  content: ""; position: absolute; width: 130px; height: 8px; border-radius: 4px;
  background: #fff; box-shadow: 0 0 30px #a6f4ff, 0 0 60px #00a2ff;
  transform: rotate(-45deg);
  animation: slashCross 0.5s ease-out forwards;
}
@keyframes slashCross {
  0% { transform: scaleX(0.1) rotate(var(--r, 45deg)); opacity: 0; }
  30% { transform: scaleX(1.3) rotate(var(--r, 45deg)); opacity: 1; }
  100% { transform: scaleX(1.6) rotate(var(--r, 45deg)); opacity: 0; }
}

/* ⛰️ Fracas Tellurique */
.impact-explosion.imp-terre::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #e6a83e 40%, #704415 75%, transparent 90%);
  box-shadow: 0 0 45px #d49a37, 0 0 80px rgba(120, 70, 20, 0.9);
  animation: blastBurst 0.7s cubic-bezier(0.1, 0.85, 0.25, 1) forwards;
}

/* ☀️ Nova Sacrée Céleste */
.impact-explosion.imp-lumiere::before {
  content: ""; position: absolute; inset: -10px; border-radius: 50%;
  background: radial-gradient(circle, #ffffff 0%, #fff2a3 35%, #ffcc00 65%, transparent 85%);
  box-shadow: 0 0 60px #ffd700, 0 0 120px #ffaa00;
  animation: blastBurst 0.75s cubic-bezier(0.1, 0.85, 0.25, 1) forwards;
}
.impact-explosion.imp-lumiere::after {
  content: ""; position: absolute; inset: -25px; border-radius: 50%;
  border: 4px solid #fff;
  box-shadow: 0 0 40px #ffe680;
  animation: ringExpand 0.6s ease-out forwards;
}

/* 🔮 Nova Cosmique Éther */
.impact-explosion.imp-ether::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, #ffffff 0%, #df80ff 35%, #7700cc 70%, transparent 85%);
  box-shadow: 0 0 55px #bf00ff, 0 0 110px #6600cc;
  animation: blastBurst 0.72s cubic-bezier(0.1, 0.85, 0.25, 1) forwards;
}
.impact-explosion.imp-ether::after {
  content: ""; position: absolute; inset: -20px; border-radius: 50%;
  border: 3px solid #f0aaff;
  box-shadow: 0 0 35px #a000ff;
  animation: ringExpand 0.58s ease-out forwards;
}

@keyframes blastBurst {
  0% { transform: scale(0.15); opacity: 1; filter: brightness(2.5); }
  45% { transform: scale(1.15); opacity: 0.95; filter: brightness(1.5); }
  100% { transform: scale(1.7); opacity: 0; filter: brightness(0.8); }
}
@keyframes ringExpand {
  0% { transform: scale(0.2); opacity: 1; border-width: 6px; }
  100% { transform: scale(2.2); opacity: 0; border-width: 1px; }
}

/* ── Chiffres de Dégâts Géants Épiques (Floating Combat Text) ─────────────── */
.damage-number-pop {
  /*  L'origine au point d'ancrage (le centre visible, apres le -50 %) : la
   *  naissance (`scale`) et l'inclinaison (`rotate`) se font sur place,
   *  sans glisser vers le coin. */
  position: absolute; transform: translate(-50%, -50%); transform-origin: 0 0;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  pointer-events: none; z-index: 48;
  --dnp-c1: #ff2a00;
  --dnp-c2: #ff6a00;
  --dnp-coeur: #ffffff;
}
.damage-number-pop.el-feu     { --dnp-c1: #ff2600; --dnp-c2: #ff8800; --dnp-coeur: #fff7e0; }
.damage-number-pop.el-eau     { --dnp-c1: #0066ff; --dnp-c2: #00d9ff; --dnp-coeur: #f0fcff; }
.damage-number-pop.el-terre   { --dnp-c1: #b86214; --dnp-c2: #f0a838; --dnp-coeur: #fff5dc; }
.damage-number-pop.el-air     { --dnp-c1: #0095ff; --dnp-c2: #8ef2ff; --dnp-coeur: #ffffff; }
.damage-number-pop.el-lumiere { --dnp-c1: #e69500; --dnp-c2: #ffe055; --dnp-coeur: #ffffff; }
.damage-number-pop.el-ether   { --dnp-c1: #7a00e6; --dnp-c2: #d866ff; --dnp-coeur: #fdf2ff; }

/*  LE CHIFFRE DEFILE, FRAPPE, PUIS MONTE (23/10/2026).
 *
 *  . IL ROULE (`.dnp-roule`) : il nait petit a l'impact et compte jusqu'aux
 *    degats (main.js, `afficherDegatsPop`), en grossissant avec la valeur
 *    (`--dnp-k` de 0 a 1), en tremblant, avec des echos verticaux de sa
 *    couleur -- le rouleau qui tourne ;
 *  . IL FRAPPE (`.dnp-pose`) : la valeur finale claque (coup de poing
 *    d'echelle, eclair), un anneau et un trait de lumiere a la couleur de
 *    l'element jaillissent derriere lui ;
 *  . IL MONTE en s'effacant, avec une derive et une inclinaison tirees au
 *    sort (`--dnp-dx`, `--dnp-rot`).
 *  Le liseré sombre serre (deux premieres ombres) le decoupe de n'importe
 *  quel fond. `scale`, `translate`, `rotate` et `transform` ont chacun une
 *  seule animation a la fois : aucune ne marche sur l'autre. */
.dnp-val {
  position: relative;
  font-family: var(--font-num); font-size: 40px; font-weight: 900;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.02em; text-align: right;
  color: var(--dnp-coeur);
  -webkit-text-stroke: 1.5px rgba(18, 6, 4, 0.9);
  paint-order: stroke fill;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 9px rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(0, 0, 0, 0.92),
    0 0 18px color-mix(in srgb, var(--dnp-c1) 80%, transparent),
    0 0 36px color-mix(in srgb, var(--dnp-c2) 55%, transparent),
    0 5px 14px rgba(0, 0, 0, 0.95);
  --dnp-vib: 1px;
}
.damage-number-pop.ascendant .dnp-val {
  font-size: 50px;
  color: #fff8d6;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 10px rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(0, 0, 0, 0.95),
    0 0 22px #ffd700,
    0 0 48px color-mix(in srgb, var(--dnp-c2) 70%, transparent),
    0 5px 14px rgba(0, 0, 0, 0.98);
}
/*  LE CHIFFRE GROSSIT AVEC LE COUP (14/10/2026). Quatre paliers, les memes
 *  que la table (`Table3D.palier`) : un coup leger se lit petit, un coup
 *  devastateur arrive enorme et tremble plus fort. La taille passe par
 *  `font-size` pour que l'Ascendance, qui a la sienne, s'y ajoute. */
.damage-number-pop.palier-leger .dnp-val { font-size: 29px; -webkit-text-stroke-width: 1.1px; }
.damage-number-pop.palier-lourd .dnp-val {
  font-size: 52px;
  -webkit-text-stroke-width: 1.8px;
  --dnp-vib: 1.6px;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 10px rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(0, 0, 0, 0.95),
    0 0 22px color-mix(in srgb, var(--dnp-c1) 85%, transparent),
    0 0 46px color-mix(in srgb, var(--dnp-c2) 60%, transparent),
    0 5px 14px rgba(0, 0, 0, .96);
}
.damage-number-pop.palier-devastateur .dnp-val,
.damage-number-pop.is-fatal .dnp-val {
  font-size: 68px; color: #fff6e5;
  -webkit-text-stroke-width: 2.2px;
  --dnp-vib: 2.4px;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.96),
    0 0 12px rgba(0, 0, 0, 0.65),
    0 3px 0 rgba(0, 0, 0, 0.96),
    0 0 28px var(--dnp-c1),
    0 0 60px color-mix(in srgb, var(--dnp-c2) 70%, transparent),
    0 6px 16px rgba(0, 0, 0, .98);
}
.damage-number-pop.ascendant.palier-lourd .dnp-val { font-size: 58px; }
.damage-number-pop.ascendant.palier-devastateur .dnp-val,
.damage-number-pop.ascendant.is-fatal .dnp-val { font-size: 74px; }

/*  L'anneau et le trait de lumiere de la frappe, derriere le chiffre. */
.dnp-val::before, .dnp-val::after {
  content: ''; position: absolute; left: 50%; top: 50%; z-index: -1;
  translate: -50% -50%; pointer-events: none; opacity: 0;
}
.dnp-val::after {
  width: 1.5em; height: 1.5em; border-radius: 50%;
  border: 0.05em solid color-mix(in srgb, var(--dnp-c2) 85%, #fff);
  box-shadow: 0 0 0.35em var(--dnp-c1), inset 0 0 0.25em var(--dnp-c2);
}
.dnp-val::before {
  width: 3.4em; height: 0.07em; border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--dnp-coeur) 35%, #fff 50%, var(--dnp-coeur) 65%, transparent);
  box-shadow: 0 0 0.3em var(--dnp-c2), 0 0 0.7em var(--dnp-c1);
}

/*  1. IL ROULE. */
.damage-number-pop.dnp-roule { animation: dnpNait 130ms cubic-bezier(.2, .9, .3, 1.4) both; }
.dnp-roule .dnp-val {
  scale: calc(0.6 + 0.4 * var(--dnp-k, 0));
  color: color-mix(in srgb, var(--dnp-coeur) 72%, var(--dnp-c2));
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 9px rgba(0, 0, 0, 0.6),
    0 -0.16em 0 color-mix(in srgb, var(--dnp-c2) 30%, transparent),
    0 0.16em 0 color-mix(in srgb, var(--dnp-c2) 30%, transparent),
    0 0 18px color-mix(in srgb, var(--dnp-c1) 60%, transparent);
  animation: dnpVibre 68ms steps(1) infinite;
}
.dnp-roule .dnp-badge { opacity: 0; }
@keyframes dnpNait {
  0% { scale: 0.3; opacity: 0; }
  100% { scale: 1; opacity: 1; }
}
@keyframes dnpVibre {
  0% { translate: calc(var(--dnp-vib) * -1) calc(var(--dnp-vib) * .5); }
  25% { translate: var(--dnp-vib) calc(var(--dnp-vib) * -.5); }
  50% { translate: calc(var(--dnp-vib) * .5) var(--dnp-vib); }
  75% { translate: calc(var(--dnp-vib) * -.5) calc(var(--dnp-vib) * -1); }
}

/*  2. IL FRAPPE, 3. IL MONTE. */
.damage-number-pop.dnp-pose { animation: dnpMonte 1.1s cubic-bezier(.35, .6, .4, 1) .26s both; }
.dnp-pose .dnp-val { animation: dnpFrappe 280ms cubic-bezier(.2, .8, .3, 1) both; }
.dnp-pose.palier-lourd .dnp-val { animation-name: dnpFrappeLourde; animation-duration: 320ms; }
.dnp-pose.palier-devastateur .dnp-val,
.dnp-pose.is-fatal .dnp-val { animation-name: dnpFrappeDevastatrice; animation-duration: 380ms; }
.dnp-pose .dnp-val::after { animation: dnpAnneau 420ms cubic-bezier(.1, .7, .3, 1) forwards; }
.dnp-pose .dnp-val::before { animation: dnpTrait 340ms cubic-bezier(.1, .7, .3, 1) forwards; }
.dnp-pose .dnp-badge { animation: badgePop 1.1s ease-out .08s both; }
@keyframes dnpFrappe {
  0% { transform: scale(1.45); filter: brightness(2); }
  35% { transform: scale(0.92); filter: brightness(1.3); }
  65% { transform: scale(1.05); filter: brightness(1.05); }
  100% { transform: scale(1); filter: brightness(1); }
}
@keyframes dnpFrappeLourde {
  0% { transform: scale(1.65); filter: brightness(2.2); }
  30% { transform: translateX(-4px) scale(0.9); filter: brightness(1.4); }
  50% { transform: translateX(4px) scale(1.07); }
  72% { transform: translateX(-2px) scale(0.99); filter: brightness(1.05); }
  100% { transform: none; filter: brightness(1); }
}
@keyframes dnpFrappeDevastatrice {
  0% { transform: scale(1.9); filter: brightness(2.6); }
  24% { transform: translateX(-7px) scale(0.86); filter: brightness(1.6); }
  40% { transform: translateX(7px) scale(1.1); }
  56% { transform: translateX(-4px) scale(0.98); filter: brightness(1.15); }
  74% { transform: translateX(2px) scale(1.02); }
  100% { transform: none; filter: brightness(1); }
}
@keyframes dnpAnneau {
  0% { opacity: 0.95; scale: 0.35; }
  100% { opacity: 0; scale: 1.9; }
}
@keyframes dnpTrait {
  0% { opacity: 1; scale: 0.15 1; }
  45% { opacity: 0.9; }
  100% { opacity: 0; scale: 1.25 1; }
}
@keyframes dnpMonte {
  0% { translate: 0 0; rotate: var(--dnp-rot, 0deg); opacity: 1; }
  62% { opacity: 1; }
  100% { translate: var(--dnp-dx, 0px) -64px; rotate: var(--dnp-rot, 0deg); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .dnp-pose .dnp-val, :where(html:not(.mouvement-plein)) .dnp-pose .dnp-val::before, :where(html:not(.mouvement-plein)) .dnp-pose .dnp-val::after { animation: none; }
}
.dnp-badge {
  font-family: var(--font-title); font-size: 11px; font-weight: 900;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: #ffe680; background: rgba(30, 20, 5, 0.92);
  border: 1px solid #ffd700; border-radius: 999px;
  padding: 3px 10px;
  box-shadow: 0 0 16px rgba(255, 215, 0, 0.65);
}
@keyframes badgePop {
  0% { transform: scale(0.5); opacity: 0; }
  30% { transform: scale(1.1); opacity: 1; }
  75% { opacity: 1; }
  100% { transform: translateY(-20px); opacity: 0; }
}

.energy-burst, .energy-spent, .heal-burst, .status-burst, .move, .summon, .death-burst {
  padding: 6px 12px; border-radius: 999px; font-size: 12px;
  animation: fxRise 1.35s cubic-bezier(.16, .8, .25, 1) forwards;
}
.energy-burst {
  color: #dff9ff; border: 1px solid #5ae5ff;
  background: rgba(3,50,82,.88);
  box-shadow: 0 0 16px #1ccaff, 0 0 34px rgba(28,202,255,.55);
}
.energy-spent { color: #91b9c8; background: rgba(8,25,35,.85); }
.heal-burst {
  color: #eaffef; border: 1px solid var(--ok); background: rgba(8,65,36,.9);
  box-shadow: 0 0 20px rgba(82,217,135,.7);
}
.status-burst { color: #ead4ff; border: 1px solid #aa62e8; background: rgba(46,14,78,.9); }
.move { color: #fff2cb; border: 1px solid var(--accent); background: rgba(70,48,10,.9); }
.summon { color: #fff1c7; background: rgba(63,45,12,.9); }
.summon::before {
  border: 2px solid var(--accent);
  box-shadow: 0 0 30px var(--accent);
  animation: ringBurst 1s ease-out forwards;
}
/*  « TOMBÉE » EST UN TAMPON, PAS UNE PASTILLE (23/10/2026) : il claque,
 *  incline, rouge sombre bordé d'or chaud, puis s'efface en montant. */
.death-burst {
  color: #ffeae4; border-radius: 4px; padding: 5px 14px 6px;
  font-size: 13px; letter-spacing: .24em; text-transform: uppercase;
  background: linear-gradient(180deg, rgba(122, 18, 24, .96), rgba(56, 6, 12, .96));
  border: 1px solid rgba(255, 168, 120, .6);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .6), 0 0 22px rgba(255, 70, 40, .4), inset 0 1px 0 rgba(255, 255, 255, .16);
  animation: koTampon 1.3s cubic-bezier(.2, .9, .25, 1) forwards;
}
@keyframes koTampon {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(1.9) rotate(-7deg); }
  12% { opacity: 1; transform: translate(-50%, -50%) scale(.94) rotate(-3deg); }
  20% { transform: translate(-50%, -50%) scale(1.04) rotate(-3deg); }
  28% { transform: translate(-50%, -50%) scale(1) rotate(-3deg); }
  78% { opacity: 1; transform: translate(-50%, -62%) scale(1) rotate(-3deg); }
  100% { opacity: 0; transform: translate(-50%, -80%) scale(.96) rotate(-3deg); }
}
.death-burst::before {
  border: 3px solid var(--bad);
  box-shadow: 0 0 30px var(--bad);
  animation: deathRing 1s ease-in forwards;
}
@keyframes deathRing {
  0% { opacity: 1; transform: translate(-50%,-50%) scale(1.5); }
  100% { opacity: 0; transform: translate(-50%,-50%) scale(.1); }
}
@keyframes fxRise {
  0% { opacity: 0; transform: translate(-50%, 5px) scale(.55); }
  18% { opacity: 1; transform: translate(-50%, -10px) scale(1.08); }
  72% { opacity: 1; transform: translate(-50%, -24px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -48px) scale(.94); }
}

.turn-banner {
  position: absolute; z-index: 42; left: 50%; top: 19%;
  transform: translate(-50%, -50%) scale(.82);
  min-width: 260px; padding: 11px 28px 12px;
  text-align: center; pointer-events: none;
  color: #fff6df;
  background: linear-gradient(90deg, transparent, rgba(10, 8, 8, .94) 14% 86%, transparent);
  border-top: 1px solid rgba(201, 162, 70, .5);
  border-bottom: 1px solid rgba(201, 162, 70, .5);
  opacity: 0; filter: blur(5px);
}
.turn-banner strong {
  display: block; font: 750 21px/1.15 var(--font-title), Georgia, serif;
  letter-spacing: .14em;
}
.turn-banner span { display: block; margin-top: 3px; color: #c9c1b2; font-size: 11px; letter-spacing: .06em; }
.turn-banner.mine strong { color: #9bffc0; }
.turn-banner.foe strong { color: #ff9b91; }
/*  « turn-banner wheel » tombait aussi sous la regle generique `.wheel`
    (display: flex) : le sous-titre passait en colonne etroite a droite du
    titre, et « Il commande la premiere manche » s'ecrivait mot par mot sur
    la planche. */
.turn-banner.wheel { display: block; gap: 0; }
/* Et `.wheel span` en faisait un rond de 30 px : c'est lui qui ecrivait le
   sous-titre mot par mot. */
.turn-banner.wheel span {
  width: auto; height: auto; border: 0; border-radius: 0; display: block;
  place-items: normal; background: none; box-shadow: none;
  color: #c9c1b2; font-size: 11px;
}
.turn-banner.wheel strong { color: var(--accent); }
.turn-banner.show { animation: bannerReveal 1.75s ease both; }
@keyframes bannerReveal {
  0% { opacity: 0; filter: blur(5px); transform: translate(-50%,-50%) scale(.8); }
  18%, 72% { opacity: 1; filter: none; transform: translate(-50%,-50%) scale(1); }
  100% { opacity: 0; filter: blur(2px); transform: translate(-50%,-64%) scale(1.04); }
}

.match-result {
  --result: #d3b56f;
  position: absolute; z-index: 60; inset: 0;
  display: grid; place-items: center;
  padding: 24px;
  background:
    radial-gradient(circle at 50% 48%, color-mix(in srgb, var(--result) 18%, transparent), transparent 36%),
    rgba(2, 4, 8, .72);
  backdrop-filter: blur(3px) saturate(.55);
  opacity: 0; pointer-events: auto;
}
.match-result[hidden] { display: none; }
.match-result.victory { --result: #69e99b; }
.match-result.defeat { --result: #ff6f64; }
.match-result.draw { --result: #d3b56f; }
.match-result.show { animation: resultBackdrop .65s ease both; }
.match-result-panel {
  position: relative; isolation: isolate;
  width: min(620px, 82vw); padding: 30px 38px 28px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; overflow: hidden;
  color: #f5f0e7;
  background:
    linear-gradient(90deg, transparent, rgba(8,10,16,.98) 10% 90%, transparent);
  border-top: 2px solid var(--result);
  border-bottom: 2px solid var(--result);
  box-shadow: 0 0 48px color-mix(in srgb, var(--result) 24%, transparent);
}
.match-result-panel::before {
  content: ""; position: absolute; z-index: -1; inset: -80% -20%;
  background: linear-gradient(115deg, transparent 42%, color-mix(in srgb, var(--result) 16%, transparent) 49% 51%, transparent 58%);
  animation: resultSweep 2.8s ease-in-out infinite;
}
.match-result-kicker {
  color: color-mix(in srgb, var(--result) 70%, #fff);
  font-size: 10px; font-weight: 850; letter-spacing: .28em;
}
.match-result-sigil {
  margin-top: 10px; color: var(--result);
  font-size: 34px; line-height: 1;
  text-shadow: 0 0 20px currentColor;
}
.match-result-title {
  margin-top: 5px;
  color: var(--result);
  font: 850 clamp(38px, 7vw, 72px)/.95 "Fraunces", Georgia, serif;
  letter-spacing: .13em;
  text-shadow: 0 0 28px color-mix(in srgb, var(--result) 52%, transparent);
}
.match-result-reason {
  margin: 14px 0 0; color: #eee8dc;
  font-size: 15px; font-weight: 650;
}
.match-result-meta {
  margin-top: 6px; color: #aaa69e;
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
}
.match-result-replay {
  min-width: 190px; margin-top: 20px;
  border-color: var(--result) !important;
  box-shadow: 0 0 20px color-mix(in srgb, var(--result) 22%, transparent);
}
@keyframes resultBackdrop {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes resultReveal {
  from { opacity: 0; transform: scaleX(.25) scaleY(.8); filter: blur(8px); }
  55% { opacity: 1; filter: none; }
  to { transform: scale(1); }
}
@keyframes resultSweep {
  0%, 15% { transform: translateX(-45%); opacity: 0; }
  45% { opacity: 1; }
  75%, 100% { transform: translateX(45%); opacity: 0; }
}

/*  LE FIL DES EVENEMENTS NE SE VOIT PLUS (23/10/2026, Alexandre : « retire
 *  les textes qui apparaissent dans le bas de l'ecran »). Les coups se lisent
 *  sur la table ; le fil ne parle plus qu'aux lecteurs d'ecran (aria-live). */
.event-feed {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; pointer-events: none;
}

/* La fiche detaillee montre la carte PLEINE resolution : 1024 x 1610. Sans
   borne elle s'affichait a sa taille naturelle, debordait de la fenetre et
   forçait des barres de defilement. On la cadre sur la hauteur -- c'est la
   dimension qui contraint une carte en portrait.

   LA BORNE VISE L'IMAGE, OU QU'ELLE SOIT.
   Elle etait ecrite `.card-zoom > img` -- enfant DIRECT. Or `habillerDuVernis`
   remplace l'image par une enveloppe et la range dedans : des l'Epique, la
   carte n'etait plus fille de `.card-zoom` mais petite-fille, la borne ne la
   trouvait plus, et elle s'ouvrait a ses 1024 x 1610 natifs -- on n'en voyait
   qu'un coin. C'est le meme piege que la hauteur des cartes en main : toute
   regle ecrite en enfant direct saute des que le vernis s'interpose. On vise
   donc les deux chemins.

   Et c'est l'IMAGE qui porte les limites, pas l'enveloppe : celle-ci l'epouse
   ensuite, ce qui garde les fenetres mates -- posees en pourcentage de
   l'enveloppe -- exactement sur les zones qu'elles decoupent. */
.card-zoom > img,
.card-zoom > .vernis > img {
  display: block;
  max-height: 64vh;
  max-width: min(70vw, 400px);
  width: auto; height: auto;
  border-radius: 14px;
}
.card-zoom > img { filter: drop-shadow(0 20px 55px rgba(0, 0, 0, .8)); }
/* L'ombre passe sur l'enveloppe, sinon elle se glisserait ENTRE l'image et
   les couches de vernis posees par-dessus. */
.card-zoom > .vernis {
  display: inline-block; width: auto; height: auto;
  border-radius: 14px;
  filter: drop-shadow(0 20px 55px rgba(0, 0, 0, .8));
}
.card-zoom .zoom-fermer {
  position: fixed; right: 18px; top: 14px;
  color: var(--ink-dim); font-size: 12px; letter-spacing: .5px;
  pointer-events: none;
}

/* ── Le lancer d'ouverture ────────────────────────────────────────────────
   IL N'A PLUS DE BANDEAU A LUI.

   Ce panneau montrait deux carres avec un chiffre dedans, sur un voile noir
   floute couvrant tout l'ecran ; les des sont devenus de vrais solides qui
   tombent sur la table (des3d.js), et il n'est plus reste qu'un bandeau
   translucide en haut de l'ecran. Ce bandeau etait un DECOR, pas une demande :
   un titre gris en petites capitales, fondu dans un degrade noir, et un bouton
   qu'on trouvait par hasard. Le lancer passe maintenant par la fenetre
   d'action, comme toutes les autres phases -- voir `.action-window`. */

/* ── Le cartouche d'un jet de capacite ────────────────────────────────────
   Le de donne le CHIFFRE ; il ne peut pas dire quel seuil il fallait
   atteindre, ni a qui il appartient. Le cartouche s'en charge, en haut de la
   table, et n'annonce « reussi » qu'une fois le de couche. */
.jet-annonce {
  position: absolute; left: 50%; top: 8%;
  transform: translate(-50%, -10px);
  display: flex; align-items: center; gap: 10px;
  padding: 7px 14px; border-radius: 999px;
  background: rgba(8, 6, 10, .86);
  border: 1px solid rgba(201, 162, 70, .35);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .55);
  font-size: 12px; color: var(--ink);
  opacity: 0; transition: opacity .25s ease, transform .25s ease;
  pointer-events: none; z-index: 47; white-space: nowrap;
}
.jet-annonce.vu { opacity: 1; transform: translate(-50%, 0); }
.jet-qui { font-weight: 700; }
.jet-de {
  font-family: var(--font-title); letter-spacing: .12em; text-transform: uppercase;
  color: #c9a246;
}
.jet-seuil { color: var(--ink-dim); }
.jet-verdict { font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.jet-annonce.reussi { border-color: rgba(120, 220, 150, .6); }
.jet-annonce.reussi .jet-verdict { color: #7bdc96; }
.jet-annonce.manque { border-color: rgba(220, 110, 110, .5); }
.jet-annonce.manque .jet-verdict { color: #dc7070; }

/* ── Les cartes qui volent de la pioche vers la main ──────────────────────
   Elles franchissent une frontiere : la pioche est un objet 3D dans le canvas,
   la main est du DOM. On ne peut donc pas animer l'une vers l'autre en 3D ni
   en CSS seul -- on projette la position de la pile a l'ecran, et on fait
   voler des elements DOM par-dessus tout. */
.vol-carte {
  /* top/left a zero : sans eux, un element `fixed` garde sa position STATIQUE
     -- ici la fin du document -- et le translate() s'y ajoute. Les cartes
     partaient donc a 1693 px du haut, sous une fenetre qui en fait 991. */
  position: fixed; top: 0; left: 0;
  z-index: 60; pointer-events: none;
  border-radius: 6px; overflow: hidden;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .75);
  transform-origin: top left;
}
.vol-carte img { display: block; width: 100%; height: 100%; }
.mc-carte.attend { visibility: hidden; }

/* LA CARTE QUI VIENT D'ETRE PIOCHEE se signale une demi-seconde. Elle arrive
   au milieu de six autres qui lui ressemblent : sans ce battement, l'animation
   de distribution ne repond pas a la seule question qu'elle pose -- « qu'est-ce
   que je viens de tirer ? ». Le halo est porte par un pseudo-element : la carte
   elle-meme porte deja son vernis et son survol, et deux effets sur un meme
   support n'en font qu'un (voir les pieges de l'interface). */
.mc-carte.vient-d-arriver { animation: carteArrive 620ms ease-out; }
.mc-carte.vient-d-arriver::after {
  content: ''; position: absolute; inset: -3px; border-radius: 8px;
  pointer-events: none; animation: carteArriveHalo 620ms ease-out;
}
@keyframes carteArrive {
  0%   { transform: scale(1.08); }
  55%  { transform: scale(0.985); }
  100% { transform: scale(1); }
}
@keyframes carteArriveHalo {
  0%   { box-shadow: 0 0 0 2px rgba(255, 226, 150, .95), 0 0 22px 6px rgba(255, 196, 90, .75); }
  100% { box-shadow: 0 0 0 0 rgba(255, 226, 150, 0), 0 0 0 0 rgba(255, 196, 90, 0); }
}

/* ── La loupe : la creature choisie, en grand ─────────────────────────────
   La carte garde son rendu original, tandis qu'une colonne lisible reprend
   ses competences avec leur cout, leur texte et leur disponibilite. */
.loupe {
  /*  AU CENTRE DE LA TABLE, PAS A 262 PIXELS DU BORD DROIT.
   *
   *  Cet ancrage-la datait d'une loupe qui n'avait que sa carte et trois
   *  boutons : calee a droite, elle laissait le plateau visible a gauche. La
   *  colonne des gestes a grossi -- competences, puis bonus et malus -- et le
   *  panneau s'est mis a deborder vers la gauche en travers de l'anneau,
   *  toujours accroche par sa droite. On ouvrait une carte au centre et la
   *  fenetre partait de cote.
   *
   *  Elle se centre donc sur la table, et sa largeur est bornee : au-dela,
   *  ce n'est plus une loupe, c'est un deuxieme ecran. */
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  max-width: min(760px, 94%);
  z-index: 6; display: flex; gap: 14px; align-items: center;
  padding: 14px; border-radius: 4px;
  background: linear-gradient(180deg, rgba(18, 12, 8, .9), rgba(8, 6, 8, .94));
  border: 1px solid rgba(201, 162, 70, .38);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55), 0 0 22px rgba(201, 162, 70, .08);
  backdrop-filter: blur(6px);
  max-height: 92%; overflow: auto;
  /*  ELLE NE VERROUILLE PAS LA TABLE.
   *
   *  Ce panneau fait sept cent cinquante pixels de large et se pose au milieu
   *  du plateau : il couvre les six tuiles des deux camps. Tant qu'il prenait
   *  les clics sur toute sa surface, ouvrir une creature EMPECHAIT d'en ouvrir
   *  une autre -- le clic tombait sur le panneau, qui n'en faisait rien, et la
   *  loupe restait sur la premiere. On croyait la seconde creature bloquee par
   *  une regle, alors qu'elle etait simplement sous une vitre.
   *
   *  La vitre est translucide : on voit le plateau au travers, et on peut
   *  maintenant le toucher au travers. Seule la colonne des gestes retient le
   *  pointeur -- c'est la qu'il y a quelque chose a presser. Un clic ailleurs
   *  ferme la loupe (voir le guetteur de `renderLoupe`) et atteint la table
   *  dans le meme geste : une seule action pour changer de creature. */
  pointer-events: none;
}
/*  SEULS LES BOUTONS RETIENNENT LE POINTEUR.
 *  La colonne des gestes fait deux cent quatre-vingts pixels de large et tombe
 *  elle aussi sur des tuiles : lui rendre les clics en bloc, c'etait reculer
 *  le probleme de trois cents pixels. Ce qu'on presse, ce sont les lignes de
 *  competence et les boutons -- eux seuls arretent le pointeur ; les titres,
 *  les PV et les phrases d'aide le laissent passer. */
.loupe-action, .loupe-gestes button { pointer-events: auto; }
.loupe-scene { display: flex; gap: 10px; align-items: center; }
.loupe-cadre { line-height: 0; position: relative; }
/* Les jetons d'une pose (Piege, Site) : tours restants puis vie, a cheval sur
   le bord droit de la carte, comme le jeton pose sur la table. */
.loupe-pose-jetons {
  position: absolute; top: 9%; right: -18px;
  display: flex; flex-direction: column; gap: 8px; line-height: 1;
}
.pose-jeton {
  width: 52px; height: 52px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  border: 3px solid #0c0a14; box-shadow: 0 4px 12px rgba(0, 0, 0, .55);
  color: #fff; text-shadow: 0 1px 2px #000;
}
.pose-jeton b { font: 900 22px/1 "Outfit", system-ui, sans-serif; }
.pose-jeton small { font: 700 9px/1.1 "Outfit", system-ui, sans-serif; text-transform: uppercase; letter-spacing: .04em; opacity: .9; }
.pose-jeton.tours { background: radial-gradient(circle at 36% 32%, #3d4a68, #1b2434 60%, #000); }
.pose-jeton.vie { background: radial-gradient(circle at 36% 32%, #8a3446, #2a1418 60%, #000); }
.loupe-mod-duree { color: var(--gold, #e8c170) !important; }
.loupe-carte {
  display: block; height: min(68vh, 560px); width: auto;
  border-radius: 10px; box-shadow: 0 10px 26px rgba(0, 0, 0, .5);
}

/* La colonne d'energie. Elle se met du cote EXTERIEUR de l'anneau, comme sur
   la table : changer de bord entre les deux vues ferait croire a une autre
   creature. */
.loupe-nrj {
  display: flex; flex-direction: column; gap: 7px; align-items: center;
  min-width: 26px;
}
/* Une pastille porte la vraie icone de son element, issue du meme PNG que les
   cartes et le cadran. Le PNG noir sert de masque afin de garder le relief et
   la couleur propres au jeton sans retomber sur un glyphe textuel. */
.loupe-pastille {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-style: normal;
  background:
    radial-gradient(circle at 32% 28%,
      color-mix(in srgb, var(--nrj-accent, #fff) 70%, transparent) 0%,
      var(--nrj-base, #5B6B8A) 52%,
      color-mix(in srgb, var(--nrj-deep, #000) 65%, var(--nrj-base, #5B6B8A)) 100%);
  border: 1px solid color-mix(in srgb, var(--nrj-accent, #fff) 55%, transparent);
  box-shadow:
    0 0 9px color-mix(in srgb, var(--nrj-base, #5B6B8A) 75%, transparent),
    inset 0 -2px 3px rgba(0, 0, 0, .45),
    inset 0 2px 2px color-mix(in srgb, var(--nrj-accent, #fff) 30%, transparent);
}
.loupe-pastille::before {
  content: "";
  display: block; width: 14px; height: 14px;
  background: var(--nrj-accent, #fff);
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .6));
}
.loupe-nrj-n { font-size: 12px; font-weight: 700; color: var(--ink-dim); margin-top: 2px; }
.loupe-nrj-vide {
  width: 26px; height: 26px; border-radius: 50%;
  border: 1px dashed var(--line); color: var(--ink-dim);
  font-size: 12px; display: grid; place-items: center;
}
.loupe-aide { font-size: 11px; color: var(--ink-dim); line-height: 1.35; }

.loupe-gestes {
  display: flex; flex-direction: column; gap: 7px;
  min-width: 270px; max-width: 310px;
  /*  Plus haute que la carte s'il le faut : la loupe a la place (92 % de la
   *  table), et ce qui ne tient pas est resserre (`resserrerLoupeMatch`). */
  max-height: min(86vh, 800px); overflow-y: auto;
  padding-right: 3px;
}
.loupe-nom { font-size: 18px; font-weight: 750; color: var(--ink); }
.loupe-pv { font-size: 13px; color: var(--ink-dim); margin-bottom: 4px; }
.loupe-gestes button { width: 100%; }
.loupe-section {
  margin-top: 4px;
  color: var(--accent); font-size: 9px; font-weight: 850;
  letter-spacing: .16em; text-transform: uppercase;
}
.loupe-section.secondaire { margin-top: 8px; color: var(--ink-faint); }
/*  Deux cartes sur une tuile (une creature et le Piege glisse dessous) :
 *  un onglet par carte, en tete de la loupe. */
.loupe-onglets {
  display: flex; gap: 4px;
  /*  Sa propre rangee, au-dessus de la carte et des gestes. */
  flex: 0 0 auto; width: 100%;
  border-bottom: 1px solid rgba(201, 162, 70, .3);
}
.loupe:has(> .loupe-onglets) { flex-wrap: wrap; }
.loupe-onglet {
  flex: 1 1 0; min-width: 0; width: auto;
  padding: 7px 8px; border-radius: 4px 4px 0 0;
  background: transparent; border: 1px solid transparent; border-bottom: none;
  color: var(--ink-dim); font-size: 13px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer; pointer-events: auto;
}
.loupe-onglet:hover { color: var(--ink); }
.loupe-onglet.is-on {
  color: var(--accent);
  background: rgba(201, 162, 70, .1);
  border-color: rgba(201, 162, 70, .38);
}
/*  Manoeuvrer et Fermer, cote a cote. */
.loupe-boutons { display: flex; gap: 7px; }
.loupe-boutons > button { flex: 1 1 0; min-width: 0; }

/*  LES PALIERS DE `resserrerLoupeMatch` : la loupe se resserre jusqu'a tenir sans
 *  defiler. Chaque palier s'ajoute au precedent. */
.loupe.serre-1 .loupe-gestes { gap: 5px; }
.loupe.serre-1 .loupe-pv { margin-bottom: 0; }
.loupe.serre-1 .loupe-aide,
.loupe.serre-1 .loupe-section.secondaire { display: none; }
.loupe.serre-1 .loupe-mods .loupe-mod { padding-top: 4px; padding-bottom: 4px; }
.loupe.serre-1 .loupe-mods .loupe-mod-txt { display: block; line-height: 1.3; }
.loupe.serre-1 .loupe-mods .loupe-mod b { display: inline; }
.loupe.serre-1 .loupe-mods .loupe-mod small { display: inline; }
.loupe.serre-1 .loupe-mods .loupe-mod small::before { content: " · "; }
.loupe.serre-1 .loupe-mods .loupe-mod small.loupe-mod-duree { display: block; }
.loupe.serre-1 .loupe-mods .loupe-mod small.loupe-mod-duree::before { content: none; }
.loupe.serre-1 .loupe-mods-tete { margin-top: 4px; }
.loupe.serre-2 .loupe-action { padding: 7px 10px; }
.loupe.serre-2 .loupe-action .la-text { display: none; }
.loupe.serre-3 .loupe-mods .loupe-mod small:not(.loupe-mod-duree),
.loupe.serre-3 .loupe-mods-note { display: none; }
.loupe-action .la-bonus { font-size: 11px; font-weight: 700; color: var(--gold, #f5b942); margin-top: 2px; }
.loupe-actions { display: flex; flex-direction: column; gap: 7px; }
.loupe-action {
  display: block; width: 100%; padding: 9px 10px;
  text-align: left; border-radius: 9px;
  color: var(--ink-dim); background: rgba(18,22,31,.82);
  border: 1px solid #303747;
}
.loupe-action:not(.is-ready) { cursor: default; }
.loupe-action.is-ready {
  cursor: pointer;
  color: var(--ink); border-color: rgba(255,190,77,.66);
  background: linear-gradient(135deg, rgba(255,190,77,.13), rgba(25,21,16,.8));
  box-shadow: inset 3px 0 0 var(--accent);
}
.loupe-action.is-ready:hover {
  border-color: var(--accent); background: rgba(255,190,77,.18);
  transform: translateX(2px);
}
.loupe-action.is-readonly { cursor: default; }
.loupe-action.is-choisie {
  border-color: var(--accent); background: rgba(255,190,77,.24);
  box-shadow: inset 3px 0 0 var(--accent), 0 0 0 1px var(--accent);
}
.la-head { display: flex; gap: 8px; align-items: center; }
.la-head strong { color: inherit; font-size: 13px; line-height: 1.25; }
.la-cost {
  margin-left: auto; flex: none;
  color: #a9ddf2; font-size: 10px; font-weight: 750;
}
.la-text {
  margin-top: 4px; color: #c1c7d3;
  font-size: 11px; line-height: 1.4;
}
.la-state {
  margin-top: 6px; color: #d58982;
  font-size: 10px; line-height: 1.3;
}
.la-state.ok { color: var(--ok); font-weight: 700; }

@media (max-width: 1100px) {
  .loupe { right: 224px; padding: 10px; gap: 8px; }
  .loupe-carte { height: min(44vh, 340px); }
  .loupe-gestes { min-width: 230px; max-width: 260px; }
}

/* ── Le choix d'elements pour la construction auto ────────────────────────
   Six pastilles, trois au maximum. Eteintes, elles restent lisibles : on doit
   pouvoir choisir un element sans deviner sa couleur. */
.deck-els {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin: 6px 0;
}
.el-chip {
  font-size: 12px; padding: 4px 9px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent;
  color: var(--ink-dim); cursor: pointer; transition: none;
}
.el-chip:hover { color: var(--ink); border-color: var(--ink-dim); }
.el-chip.is-on { font-weight: 700; }
.el-note {
  font-size: 11px; color: var(--ink-dim); margin-left: 6px;
  letter-spacing: .02em;
}
.el-note b { color: var(--accent); font-weight: 600; }

/* ── L'ecran de defausse ──────────────────────────────────────────────────
   Choisir quoi jeter demande de comparer sept cartes : on les etale en grand,
   par-dessus la table, plutot que de faire viser dans la colonne laterale. */
.jeter[hidden] {
  display: none !important;
}
/*  AU-DESSUS DE LA MAIN ET DU PUPITRE. A z 20, la colonne de la main (z 25)
    et le pupitre (z 34) passaient par-dessus le voile : deux fenetres
    ouvertes sur les cartes a jeter, celles des bords cachees dessous
    (Alexandre, 31/10/2026 : « les deux fenetres sont la et bloquent »). */
.jeter {
  position: absolute; inset: 0; z-index: 44;
  display: grid; place-items: center;
  background:
    radial-gradient(ellipse 50% 50% at 50% 46%, rgba(201, 162, 70, 0.08), transparent 60%),
    rgba(6, 4, 8, .82);
  backdrop-filter: blur(4px);
}
.jeter-panneau {
  max-width: min(1100px, 94%); max-height: 92%; overflow: auto;
  padding: 22px 26px; border-radius: 4px;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(201, 162, 70, 0.12), transparent 50%),
    linear-gradient(180deg, rgba(18, 12, 8, .96), rgba(8, 6, 8, .97));
  border: 1px solid rgba(201, 162, 70, .36);
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6), 0 0 28px rgba(201, 162, 70, .08);
  text-align: center;
}
.jeter-titre {
  margin: 0 0 6px;
  font-family: var(--font-ornate);
  font-size: 22px; color: #f3e6c0;
}
.jeter-sous {
  margin: 0 auto 18px; max-width: 62ch;
  font-size: 13px; line-height: 1.5; color: var(--ink-dim);
}
.jeter-cartes {
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: center;
  /* Par le haut, et non par la ligne de base : une Energie n'a pas de ligne
     de type sous son nom, et les cartes qui en ont une descendaient d'un cran
     toute seule. */
  align-items: flex-start;
}
.jeter-carte {
  width: 152px; padding: 0; border: 0; background: transparent;
  cursor: pointer; display: flex; flex-direction: column; gap: 4px;
  border-radius: 10px;
}
.jeter-carte .cf { width: 152px; border-radius: 8px; transition: none; }
.jeter-carte:hover .cf,
.jeter-carte:focus-visible .cf {
  outline: 2px solid #ff8a5a; outline-offset: 3px;
}
.jeter-carte:hover { transform: translateY(-4px); }
.jeter-nom { font-size: 12px; font-weight: 600; color: var(--ink); }
.jeter-type { font-size: 11px; line-height: 15px; min-height: 15px; color: var(--ink-dim); }

/* Le bouton qui ramene au tour : on a pu toucher FINIR LE TOUR sans le vouloir,
   et rien ne doit obliger a lacher une carte pour ca. */
.jeter-annuler {
  margin: 18px auto 0; display: block;
  padding: 9px 22px; border-radius: 3px; cursor: pointer;
  font-family: var(--font-ornate); font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: #e8d9ae;
  background: linear-gradient(180deg, rgba(40, 30, 20, .9), rgba(20, 14, 10, .95));
  border: 1px solid rgba(201, 162, 70, .42);
}
.jeter-annuler:hover { color: #fff3d0; border-color: rgba(201, 162, 70, .8); }

@media (max-width: 900px) {
  .jeter-carte, .jeter-carte .cf { width: 110px; }
  .game-module { right: 9px; width: 200px; padding: 11px; }
}

@media (max-width: 760px) {
  .game-module { right: 8px; top: 8px; width: 184px; padding: 9px; }
  .turn-banner { top: 15%; min-width: 220px; padding-inline: 16px; }
  .turn-banner strong { font-size: 17px; }
  .wheel-bar { left: 8px; top: 8px; }
  .match-actions { gap: 4px; }
  .arena-ctrl { padding-inline: 8px; font-size: 10px; }
  .loupe {
    inset: 8px; transform: none; z-index: 40;
    flex-direction: column; align-items: stretch;
  }
  .loupe-scene { justify-content: center; }
  .loupe-carte { height: min(42vh, 300px); }
  .loupe-gestes {
    min-width: 0; max-width: none; max-height: none;
    overflow: visible;
  }
  .match-result { padding: 10px; }
  .match-result-panel { width: 94vw; padding: 24px 18px 22px; }
  .match-result-title { letter-spacing: .08em; }
}


/* ══ SYSTÈME DE COLLECTION (793 CARTES) & OUVERTURE DE BOOSTERS ═══════════════ */

/* ── Topbar Actions & Codex Pill ─────────────────────────────────────────── */
.header-actions {
  display: flex; align-items: center; gap: 12px; margin-left: auto;
}

/* Le lien vers le livre blanc. Discret a dessein : il doit etre trouvable
   quand on se demande "un paquet sur combien ?", pas reclamer l'attention. */
.lien-livre-blanc {
  font-family: var(--font-title); font-size: .72rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint); text-decoration: none;
  padding: 5px 10px; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap;
  transition: all .2s ease;
}
.lien-livre-blanc:hover {
  color: var(--accent-light); border-color: var(--line-gold);
  background: rgba(245, 185, 66, 0.08);
}
@media (max-width: 900px) { .lien-livre-blanc { display: none; } }

.codex-progress-pill {
  display: flex; align-items: center; gap: 6px;
  background: rgba(14, 18, 28, 0.85);
  border: 1px solid var(--line-gold);
  border-radius: 999px; padding: 5px 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  cursor: pointer; transition: all .2s ease;
}
.codex-progress-pill:hover {
  border-color: var(--accent); background: rgba(245, 185, 66, 0.12);
  transform: translateY(-1px);
}
.codex-pill-icon { font-size: 13px; }
.codex-pill-label { font-size: 11px; font-weight: 700; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.06em; }
.codex-pill-val { font-family: var(--font-num); font-size: 13px; font-weight: 800; color: var(--accent); }
.codex-pill-pct { font-size: 11px; font-weight: 700; color: var(--ink-bright); }

.btn-booster-open {
  display: flex; align-items: center; gap: 8px;
  background: linear-gradient(135deg, #3d2b0c 0%, #1f1404 100%);
  border: 1.5px solid var(--accent);
  border-radius: 999px; padding: 5px 14px 5px 10px;
  color: #fff; cursor: pointer;
  box-shadow: 0 0 16px rgba(245, 185, 66, 0.3), inset 0 1px 0 rgba(255, 235, 160, 0.4);
  transition: all .25s cubic-bezier(0.16, 1, 0.3, 1);
  animation: boosterGlowPulse 3s infinite alternate;
}
@keyframes boosterGlowPulse {
  0% { box-shadow: 0 0 12px rgba(245, 185, 66, 0.25); }
  100% { box-shadow: 0 0 24px rgba(245, 185, 66, 0.55), 0 0 8px #ffe082; }
}
.btn-booster-open:hover {
  transform: translateY(-2px) scale(1.04);
  background: linear-gradient(135deg, #593f12 0%, #2b1c05 100%);
  border-color: #ffe082;
}
.booster-icon { font-size: 15px; filter: drop-shadow(0 0 6px var(--accent)); }
.booster-text { font-family: var(--font-title); font-size: 12px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #ffe699; }
.booster-count-badge {
  font-family: var(--font-num); font-size: 11px; font-weight: 900;
  background: var(--gold-grad); color: #140d02;
  border-radius: 999px; min-width: 20px; height: 20px;
  display: grid; place-items: center; padding: 0 5px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
}

/* ── Autel des Boosters & Maîtrise du Codex (Accueil) ────────────────────── */
.home-booster-altar {
  display: grid; grid-template-columns: 320px 1fr; gap: 32px;
  padding: 30px 34px; border-radius: 20px;
  background:
    radial-gradient(ellipse 500px 300px at 15% 50%, rgba(245, 185, 66, 0.1), transparent 70%),
    linear-gradient(175deg, rgba(20, 27, 44, 0.85) 0%, rgba(10, 14, 24, 0.95) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 240, 180, 0.2);
  align-items: center;
}

.altar-pack-side {
  display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center;
}

.altar-grimoire {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 18px 26px rgba(0, 0, 0, .8))
          drop-shadow(0 0 30px rgba(245, 185, 66, .25));
  transition: transform .35s cubic-bezier(.16, 1, .3, 1), filter .35s ease;
}
.altar-pack-preview:hover .altar-grimoire {
  transform: translateY(-6px) scale(1.05);
  filter: drop-shadow(0 26px 34px rgba(0, 0, 0, .88))
          drop-shadow(0 0 46px rgba(245, 185, 66, .5));
}

.altar-pack-preview {
  /* Un cadre CARRE et NU : le grimoire est rendu sur fond transparent, et
     l'encadrer d'un rectangle borde reviendrait a poser un objet dans une
     boite qu'il n'a pas. Les rendus font 1280x1280. */
  position: relative; width: 214px; height: 214px;
  cursor: pointer;
  display: flex; align-items: flex-end; justify-content: center;
  background: none; border: 0; box-shadow: none; padding: 0;
  transition: transform .35s cubic-bezier(.16, 1, .3, 1);
}
.altar-pack-preview:hover { transform: none; }
/* ── L'invitation ────────────────────────────────────────────────────────
   Elle remplace les six jauges du Codex. La progression reste lisible en
   tete de page ; la repeter ici transformait l'accueil en bilan comptable,
   au moment precis ou l'on veut donner envie d'ouvrir. */
.altar-appel {
  display: flex; flex-direction: column; align-items: flex-start; gap: 14px;
  max-width: 520px;
}
.appel-kicker {
  font-family: var(--font-title); font-size: 11px; font-weight: 900;
  letter-spacing: 0.24em; color: var(--accent);
  text-transform: uppercase;
}
.appel-titre {
  margin: 0; font-family: var(--font-title); font-size: 34px; font-weight: 900;
  letter-spacing: 0.02em;
  background: var(--gold-grad); -webkit-background-clip: text;
  background-clip: text; color: transparent;
}
.appel-ligne {
  margin: 0; color: var(--ink-dim); font-size: 15px; line-height: 1.6;
}
.appel-ligne b { color: #ffe699; font-weight: 800; }
.altar-appel .altar-pack-actions { margin-top: 6px; }

.altar-pack-count-tag {
  position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%);
  z-index: 2;
  font-size: 10px; font-weight: 800; color: #ffe699;
  background: rgba(245, 185, 66, 0.2); border-radius: 999px;
  padding: 3px 10px; border: 1px solid rgba(245, 185, 66, 0.4);
}

.altar-pack-actions {
  display: flex; flex-direction: column; gap: 8px; width: 100%; align-items: center;
}
.btn-open-pack-main {
  width: 100%; padding: 10px 16px; font-size: 13px; font-weight: 800; letter-spacing: 0.04em;
}

/* ── La vitrine des raretés ──────────────────────────────────────────────
   Une seule créature en six exemplaires : l'œil compare, et la dernière
   case -- « 1 paquet sur 1000 » -- fait le reste. Les chances sont PAR
   PAQUET, calculées depuis les taux du set, jamais recopiées. */
.altar-appel { max-width: 700px; }
.vitrine-raretes {
  list-style: none; margin: 2px 0 0; padding: 0; width: 100%;
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px;
}
.vr-item {
  --rc: #c9ccd4;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  text-align: center; min-width: 0;
}
.vr-carte {
  /* La carte entière, jamais rognée : c'est l'image qui dicte la hauteur. */
  position: relative; width: 100%; aspect-ratio: 320 / 503; border-radius: 6px;
  overflow: hidden; background: rgba(0, 0, 0, .35);
  box-shadow: 0 6px 14px rgba(0, 0, 0, .55), 0 0 0 1px color-mix(in srgb, var(--rc) 45%, transparent);
  transition: transform .3s cubic-bezier(.16, 1, .3, 1), box-shadow .3s ease;
}
.vr-carte img { width: 100%; height: 100%; object-fit: contain; display: block; }
.vr-item:hover .vr-carte {
  transform: translateY(-6px) scale(1.06);
  box-shadow: 0 14px 24px rgba(0, 0, 0, .7), 0 0 18px color-mix(in srgb, var(--rc) 70%, transparent);
}
/*  La vitrine se clique : chaque rareté ouvre la carte en grand. Le zoom du
    survol existait déjà, mais rien ne disait qu'il y avait un geste à faire —
    d'où le curseur, et un anneau de focus pour qui navigue au clavier. */
.vr-item.est-cliquable { cursor: pointer; }
.vr-item.est-cliquable:focus-visible {
  outline: 2px solid var(--rc); outline-offset: 3px; border-radius: 8px;
}
.vr-item.est-cliquable:focus-visible .vr-carte {
  transform: translateY(-6px) scale(1.06);
  box-shadow: 0 14px 24px rgba(0, 0, 0, .7), 0 0 18px color-mix(in srgb, var(--rc) 70%, transparent);
}
/* Le reflet qui passe : réservé aux raretés vernies, comme sur la carte. */
.vr-item.is-vernie .vr-carte::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .38) 50%, transparent 65%);
  background-size: 250% 100%; animation: vr-reflet 3.2s ease-in-out infinite;
  mix-blend-mode: overlay;
}
.vr-item.is-mythique .vr-carte {
  box-shadow: 0 6px 14px rgba(0, 0, 0, .55), 0 0 0 1px var(--rc), 0 0 16px color-mix(in srgb, var(--rc) 55%, transparent);
  animation: vr-pouls 2.4s ease-in-out infinite;
}
@keyframes vr-reflet { 0% { background-position: 150% 0; } 60%, 100% { background-position: -50% 0; } }
@keyframes vr-pouls {
  50% { box-shadow: 0 6px 14px rgba(0, 0, 0, .55), 0 0 0 1px var(--rc), 0 0 28px color-mix(in srgb, var(--rc) 85%, transparent); }
}
.vr-nom {
  font-family: var(--font-title); font-size: 10.5px; font-weight: 900;
  letter-spacing: .06em; text-transform: uppercase; color: var(--rc);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.vr-chance { font-size: 11px; line-height: 1.15; color: var(--ink-dim); }
.vr-chance b { display: block; font-size: 14px; font-weight: 900; color: #fff; }
.vr-item.is-mythique .vr-chance b { color: var(--rc); text-shadow: 0 0 10px color-mix(in srgb, var(--rc) 60%, transparent); }
/* ── Accueil AAA : confiance, édition, pied de page ───────────────────── */
.hero-trust {
  display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 4px;
  font-size: 12.5px; color: var(--ink-dim); letter-spacing: .02em;
}
.hero-trust span { display: inline-flex; align-items: center; gap: 7px; }
.hero-trust span::before { content: "◆"; font-size: 8px; color: var(--accent); }
.hero-trust b { color: #fff; font-weight: 800; }
.hero-trust-lien { display: inline-flex; align-items: center; gap: 7px; color: inherit; text-decoration: none; }
.hero-trust-lien::before { content: "◆"; font-size: 8px; color: var(--accent); }
.hero-trust-lien:hover b { text-decoration: underline; }
.roue-lien-regles { align-self: flex-start; color: var(--accent-light); font-weight: 700; text-decoration: none; }
.roue-lien-regles:hover { text-decoration: underline; }
.home-edition { display: flex; flex-direction: column; gap: 20px; }
.he-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.he-carte {
  padding: 22px 20px; border-radius: 16px; display: flex; flex-direction: column; gap: 8px;
  background: linear-gradient(175deg, rgba(20, 27, 44, .85), rgba(10, 14, 24, .95));
  border: 1px solid var(--line-gold);
}
.he-chiffre {
  font-family: var(--font-title); font-size: 30px; font-weight: 900; line-height: 1;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.he-carte b { color: #fff; font-size: 15px; }
.he-carte p { margin: 0; color: var(--ink-dim); font-size: 13.5px; line-height: 1.55; }
/* Le renvoi au livre blanc se voit sans casser la ligne : un simple souligne
   dore, qui s'allume au survol. */
.he-carte p a {
  color: var(--accent-light); text-decoration: underline;
  text-underline-offset: 2px; text-decoration-color: rgba(212, 175, 105, .45);
  transition: color .2s ease, text-decoration-color .2s ease;
}
.he-carte p a:hover { color: #fff; text-decoration-color: currentColor; }
.he-lien { align-self: center; }
.he-liens { align-self: center; display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.home-footer {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px;
  padding: 22px 4px 8px; border-top: 1px solid rgba(255, 255, 255, .08);
  font-size: 12.5px; color: var(--ink-dim);
}
.home-footer nav { display: flex; gap: 18px; flex-wrap: wrap; }
.home-footer a { color: var(--ink-dim); text-decoration: none; }
.home-footer a:hover { color: #fff; }
@media (max-width: 760px) { .he-grid { grid-template-columns: 1fr; } }

.vr-tirage {
  margin-top: 2px; padding: 2px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; line-height: 1.2; color: #0b1410;
  background: var(--rc); box-shadow: 0 0 10px color-mix(in srgb, var(--rc) 60%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .vr-item .vr-carte, :where(html:not(.mouvement-plein)) .vr-item .vr-carte::after { animation: none !important; }
}

/* Dashboard de Maîtrise */
.altar-stats-side {
  display: flex; flex-direction: column; gap: 18px;
}
.altar-mastery-head {
  display: flex; justify-content: space-between; align-items: center;
}
.mastery-kicker {
  font-family: var(--font-title); font-size: 10px; font-weight: 800;
  letter-spacing: 0.22em; color: var(--accent); text-transform: uppercase;
}
.mastery-title {
  margin: 2px 0 0; font-family: var(--font-title); font-size: 22px; font-weight: 800;
  color: var(--ink-bright);
}
.mastery-rank-badge {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 14px; border-radius: 999px;
  background: linear-gradient(135deg, rgba(245, 185, 66, 0.15) 0%, rgba(20, 27, 44, 0.9) 100%);
  border: 1px solid var(--accent);
  box-shadow: 0 0 14px rgba(245, 185, 66, 0.25);
}
.rank-icon { font-size: 14px; }
.rank-title {
  font-family: var(--font-title); font-size: 12px; font-weight: 800;
  color: #ffe699; letter-spacing: 0.06em;
}

/* Grande Jauge Globale */
.mastery-global-bar-wrap {
  display: flex; flex-direction: column; gap: 6px;
}
.mastery-bar-labels {
  display: flex; justify-content: space-between; font-size: 13px;
}
.mastery-bar-labels .m-lbl { color: var(--ink-dim); font-weight: 600; }
.mastery-bar-labels .m-val { color: var(--accent); font-family: var(--font-num); font-weight: 800; }

.mastery-progress-track {
  height: 14px; width: 100%; border-radius: 999px;
  background: rgba(8, 11, 18, 0.9);
  border: 1px solid rgba(245, 185, 66, 0.35);
  overflow: hidden; padding: 2px;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.8);
}
.mastery-progress-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #d97706 0%, #f59e0b 50%, #fef08a 100%);
  box-shadow: 0 0 12px rgba(245, 185, 66, 0.6);
  transition: width .8s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Jauges par Rareté */
.mastery-rarities-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 16px;
}
.rarity-meter {
  display: flex; flex-direction: column; gap: 4px;
}
.rm-head {
  display: flex; justify-content: space-between; font-size: 11px;
}
.rm-head span { font-weight: 700; color: var(--ink-dim); }
.rm-head b { font-family: var(--font-num); font-weight: 800; }

.rm-track {
  height: 6px; width: 100%; border-radius: 999px;
  background: rgba(8, 11, 18, 0.8);
  border: 1px solid var(--line); overflow: hidden;
}
.rm-fill {
  height: 100%; border-radius: 999px;
  transition: width .6s ease;
}

.r-commune .rm-head span { color: #a1a1aa; }
.r-commune .rm-head b { color: #e4e4e7; }
.r-commune .rm-fill { background: #a1a1aa; }

.r-peu-commune .rm-head span { color: #34d399; }
.r-peu-commune .rm-head b { color: #6ee7b7; }
.r-peu-commune .rm-fill { background: #10b981; }

.r-rare .rm-head span { color: #38bdf8; }
.r-rare .rm-head b { color: #7dd3fc; }
.r-rare .rm-fill { background: #0284c7; }

.r-epique .rm-head span { color: #c084fc; }
.r-epique .rm-head b { color: #e9d5ff; }
.r-epique .rm-fill { background: #9333ea; }

.r-legendaire .rm-head span { color: #fbbf24; }
.r-legendaire .rm-head b { color: #fde68a; }
.r-legendaire .rm-fill { background: #d97706; }

.r-mythique .rm-head span { color: #f43f5e; }
.r-mythique .rm-head b { color: #fecdd3; }
.r-mythique .rm-fill { background: linear-gradient(90deg, #ec4899, #f43f5e, #f59e0b); }

@media (max-width: 960px) {
  .home-booster-altar { grid-template-columns: 1fr; }
  .mastery-rarities-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── MODAL D'OUVERTURE DE BOOSTER AAA ─────────────────────────────────────── */
/* ── La boutique ─────────────────────────────────────────────────────────
   Trois forfaits ; Legend est plus grand, doré, et porte le ×2. Adept n'est
   là que pour que Legend paraisse évident. */
.btn-voir-forfaits {
  width: 100%; padding: 8px 12px; border-radius: 10px; cursor: pointer;
  font-size: 12.5px; font-weight: 800; color: #ffe699;
  background: rgba(245, 185, 66, .1); border: 1px dashed rgba(245, 185, 66, .55);
  transition: background .2s ease;
}
.btn-voir-forfaits:hover { background: rgba(245, 185, 66, .2); }
.bvf-x2 {
  display: inline-block; margin-right: 6px; padding: 1px 7px; border-radius: 6px;
  background: linear-gradient(135deg, #ff5f6d, #ffc371); color: #1a0d05; font-weight: 900;
}
.shop-modal { position: fixed; inset: 0; z-index: 130; display: grid; place-items: center; padding: 16px; }
.shop-voile { position: absolute; inset: 0; background: rgba(4, 6, 12, .82); backdrop-filter: blur(6px); }
.shop-panneau {
  position: relative; width: min(960px, 100%); max-height: calc(100vh - 32px); overflow-y: auto;
  padding: 26px 28px 20px; border-radius: 20px; text-align: center;
  background:
    radial-gradient(ellipse 600px 260px at 50% 0%, rgba(245, 185, 66, .14), transparent 70%),
    linear-gradient(175deg, #151b2c 0%, #0a0e18 100%);
  border: 1px solid var(--line-gold); box-shadow: 0 30px 80px rgba(0, 0, 0, .7);
}
.shop-fermer {
  position: absolute; top: 12px; right: 12px; width: 32px; height: 32px; border-radius: 50%;
  background: rgba(255, 255, 255, .06); border: 0; color: var(--ink-dim); cursor: pointer; font-size: 14px;
}
.shop-reserve { margin: 0 auto 16px; max-width: 520px; }
.shop-reserve-ligne {
  display: flex; justify-content: center; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 14px; color: var(--ink);
}
.shop-reserve-ligne b { color: #ffe699; font-size: 17px; font-variant-numeric: tabular-nums; }
.shop-reserve-tag {
  padding: 2px 8px; border-radius: 6px; font-size: 10px; font-weight: 900; letter-spacing: .14em;
  background: #ff5f6d; color: #fff; animation: vr-pouls-tag 1.8s ease-in-out infinite;
}
@keyframes vr-pouls-tag { 50% { box-shadow: 0 0 14px rgba(255, 95, 109, .8); } }
.shop-reserve-jauge { margin-top: 7px; height: 8px; border-radius: 99px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.shop-reserve-jauge i { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, #ff5f6d, #ffc371); }
.shop-titre {
  margin: 0; font-family: var(--font-title); font-size: 32px; font-weight: 900;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.shop-sous { margin: 4px 0 20px; color: var(--ink-dim); font-size: 14px; }
.shop-sous b { color: #81fe97; }
.shop-forfaits { display: grid; grid-template-columns: 1fr 1fr 1.18fr; gap: 16px; align-items: end; }
.sf {
  position: relative; display: flex; flex-direction: column; gap: 10px; padding: 20px 16px 16px;
  border-radius: 16px; background: rgba(255, 255, 255, .035); border: 1px solid rgba(255, 255, 255, .1);
}
/* Le grimoire de chaque offre, et l'aura qui dit son rang. */
.sf-grimoire {
  position: relative; align-self: center; width: 130px; height: 130px; margin: 2px 0 4px;
  display: grid; place-items: center;
}
.sf-grimoire::before {
  content: ""; position: absolute; inset: 8%; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--aura) 75%, transparent) 0%, transparent 68%);
  filter: blur(14px); animation: sf-aura 2.8s ease-in-out infinite;
}
.sf-grimoire img {
  position: relative; width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 12px 18px rgba(0, 0, 0, .75)) drop-shadow(0 0 18px color-mix(in srgb, var(--aura) 70%, transparent));
  transition: transform .35s cubic-bezier(.16, 1, .3, 1);
}
.sf:hover .sf-grimoire img { transform: translateY(-6px) scale(1.05); }
.sf.is-legend .sf-grimoire { width: 160px; height: 160px; }
@keyframes sf-aura { 50% { transform: scale(1.12); opacity: .75; } }
.sf { border-color: color-mix(in srgb, var(--aura) 35%, rgba(255, 255, 255, .1)); }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .sf-grimoire::before { animation: none; } }

/* ── LE BOUTON QUI FAIT ACHETER ──
   Plus gros, en surbrillance, d'une couleur qui tranche avec l'or de la
   tuile : le rouge-orangé du ×2, et un halo qui respire. */
.home-booster-altar .btn-open-pack-main {
  padding: 18px 28px; font-size: 18px; font-weight: 900; letter-spacing: .06em;
  text-transform: uppercase; color: #fff; border: 0; border-radius: 14px;
  background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 55%, #ffc24a 100%);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
  box-shadow: 0 10px 30px rgba(255, 80, 90, .45), inset 0 1px 0 rgba(255, 255, 255, .4);
  animation: cta-halo 2.2s ease-in-out infinite;
  transition: transform .2s ease;
}
.home-booster-altar .btn-open-pack-main:hover:not(:disabled) {
  transform: translateY(-2px) scale(1.02);
  background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 55%, #ffc24a 100%);
}
@keyframes cta-halo {
  50% { box-shadow: 0 10px 44px rgba(255, 80, 90, .8), 0 0 0 6px rgba(255, 122, 61, .18), inset 0 1px 0 rgba(255, 255, 255, .4); }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .home-booster-altar .btn-open-pack-main { animation: none; } }

.sf-nom { font-family: var(--font-title); font-size: 18px; font-weight: 900; letter-spacing: .04em; color: var(--ink); }
.sf-paquets { font-size: 13px; color: var(--ink-dim); }
.sf-paquets s { opacity: .6; margin-right: 4px; }
.sf-paquets b { color: #fff; font-size: 22px; font-weight: 900; }
.sf-prix { font-size: 30px; font-weight: 900; color: #fff; line-height: 1; }
.sf-barre { font-size: 14px; color: var(--ink-dim); text-decoration: line-through; margin-left: 6px; font-weight: 600; }
.sf-unite { font-size: 12px; color: var(--ink-dim); }
.sf-unite em { font-style: normal; color: #81fe97; font-weight: 800; }
.sf-chances { list-style: none; margin: 4px 0; padding: 10px 0 0; border-top: 1px solid rgba(255, 255, 255, .08); display: grid; gap: 5px; }
.sf-chances li { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--ink-dim); }
.sf-chances li span:first-child { color: var(--rc); font-weight: 800; }
.sf-chances li b { color: #fff; }
.sf-acheter { margin-top: 4px; width: 100%; padding: 11px; font-weight: 900; }
.sf.is-legend {
  padding-top: 30px; border: 2px solid transparent;
  background:
    linear-gradient(175deg, #221a0c, #0f0c08) padding-box,
    linear-gradient(135deg, #ffe699, #c8871e, #ffe699) border-box;
  box-shadow: 0 0 40px rgba(245, 185, 66, .28);
}
.sf.is-legend .sf-nom { background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent; font-size: 22px; }
.sf.is-legend .sf-chances li.is-mythique b { color: #81fe97; font-size: 14px; }
.sf-ruban {
  position: absolute; top: -13px; left: 50%; transform: translateX(-50%); white-space: nowrap;
  padding: 4px 12px; border-radius: 99px; font-size: 11px; font-weight: 900; letter-spacing: .08em;
  background: linear-gradient(135deg, #ffe699, #c8871e); color: #1a1205;
}
.sf-x2 {
  align-self: center; padding: 4px 10px; border-radius: 8px; font-size: 12px; font-weight: 900;
  background: linear-gradient(135deg, #ff5f6d, #ffc371); color: #1a0d05;
}
.shop-note { margin: 14px 0 0; font-size: 11px; color: var(--ink-dim); opacity: .75; }
@media (max-width: 760px) {
  .shop-forfaits { grid-template-columns: 1fr; }
  .sf.is-legend { order: -1; }
  .shop-titre { font-size: 24px; }
  .shop-panneau { padding: 20px 14px 14px; }
}

.booster-modal[hidden],
.pack-wrapper[hidden],
.cards-reveal-area[hidden] {
  display: none !important;
}
.booster-modal[hidden] .chamber-lantern {
  display: none !important;
}

.booster-modal {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center;
  overflow: hidden;
}
.booster-backdrop {
  position: absolute; inset: 0;
  background: #060408;
  overflow: visible;
}

/*  LE SANCTUAIRE ETEINT LA PAGE QU'IL RECOUVRE.
 *
 *  Recouverte, la page continuait de tourner : trois orbes floutees de
 *  1300 px, le mur, la poussiere, chacune sur sa couche GPU. Mesure sur un
 *  Pixel (CDP LayerTree) : 318 Mo de couches grimoire ouvert, dont 123 pour
 *  les seules orbes, invisibles. Chrome encaisse ; le WebView de Phantom
 *  Android, au budget plus serre, abandonnait des tuiles -- et c'etaient
 *  celles du grimoire : il ne restait que le fond, la croix, et le bouton
 *  « Ouvrir 10 », sauve parce que son halo a sa propre petite couche.
 *  `visibility` et non `display` : la page garde sa mise en page, son
 *  defilement et sa table 3D, elle ne se peint simplement plus. */
body.sanctuaire-ouvert > .fantasy-bg-fx,
body.sanctuaire-ouvert > .topbar,
body.sanctuaire-ouvert > main,
body.sanctuaire-ouvert > .poussiere-accueil,
body.sanctuaire-ouvert > .braises-forge {
  visibility: hidden;
}
body.sanctuaire-ouvert .fx-orb { animation: none; }

/*  AU DOIGT, LE DECOR DU SANCTUAIRE SE PEINT UNE FOIS.
 *  Ses voiles sont deja des degrades radiaux, doux par construction : le
 *  flou par-dessus n'ajoutait presque rien a l'oeil, mais, anime, il
 *  faisait de chaque voile une couche plus grande que l'ecran, refloutee a
 *  chaque image. Fixes et nets, ils se fondent dans le fond. Le grimoire
 *  garde sa levitation ; c'est le decor qui se tait. */
@media (hover: none), (pointer: coarse) {
  .booster-modal :is(.chamber-shaft, .chamber-fog, .chamber-floor,
                     .pack-ambient-dome, .pack-halo, .pack-mist) {
    animation: none; filter: none; will-change: auto; mix-blend-mode: normal;
  }
  .booster-modal .chamber-shaft { opacity: .7; }
  .booster-modal .ambient-rarity-beam { inset: 0; mix-blend-mode: normal; }
}

/* ── Sanctuaire : chambre arcanique (ouverture + dévoilement) ─────────── */
.chamber {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: visible;
}
.chamber-stone {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 70% 55% at 50% 40%, #1a1210 0%, transparent 70%),
    radial-gradient(ellipse 50% 30% at 50% 100%, #0a0706 0%, transparent 70%),
    #060408;
}
.chamber-vault {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 50% at 50% -10%,
    rgba(0, 0, 0, 0.45) 0%,
    transparent 70%);
}
.chamber-shaft {
  position: absolute;
  left: 50%; top: 0;
  width: 100%; height: 80%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse 22% 60% at 50% 0%,
    rgba(255, 228, 170, 0.4) 0%,
    rgba(232, 196, 120, 0.12) 28%,
    transparent 62%);
  filter: blur(48px);
  mix-blend-mode: screen;
  animation: shaftPulse 8s ease-in-out infinite alternate;
}
@keyframes shaftPulse {
  from { opacity: 0.45; }
  to { opacity: 0.9; }
}
.chamber-floor {
  position: absolute;
  left: 50%; bottom: 0;
  width: 90%; height: 40%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 80%,
    rgba(201, 162, 70, 0.1) 0%,
    transparent 70%);
  filter: blur(12px);
}
.booster-backdrop .chamber-lantern {
  position: absolute;
  top: 13%;
  width: 11px; height: 16px;
  background: radial-gradient(circle at 40% 30%, #ffe9a8, #c47a2c 70%);
  border-radius: 40% 40% 45% 45% / 30% 30% 65% 65%;
  box-shadow:
    0 0 28px 14px rgba(232, 170, 70, 0.5),
    0 0 90px 28px rgba(180, 90, 20, 0.32);
  animation: flameFlicker 2.6s ease-in-out infinite;
}
.booster-backdrop .chamber-lantern::before {
  content: none;
}
.booster-backdrop .chamber-lantern-l { left: 10.5%; }
.booster-backdrop .chamber-lantern-r { right: 10.5%; animation-delay: -1.1s; }
@keyframes flameFlicker {
  0%, 100% { opacity: 0.82; transform: scale(1); }
  40% { opacity: 1; transform: scale(1.08); }
  70% { opacity: 0.7; transform: scale(0.96); }
}
.chamber-fog {
  position: absolute;
  left: -18%; right: -18%;
  height: 48%;
  bottom: -10%;
  filter: blur(28px);
}
.chamber-fog-1 {
  background: radial-gradient(ellipse at 50% 80%,
    rgba(48, 32, 22, 0.82) 0%, rgba(28, 18, 16, 0.42) 52%, transparent 72%);
  animation: fogDrift 22s ease-in-out infinite alternate;
}
.chamber-fog-2 {
  height: 36%;
  bottom: -6%;
  background: radial-gradient(ellipse at 30% 70%,
    rgba(90, 58, 28, 0.38) 0%, transparent 70%);
  animation: fogDrift 16s ease-in-out infinite alternate-reverse;
}
.chamber-fog-3 {
  height: 30%;
  bottom: -4%;
  background: radial-gradient(ellipse at 70% 80%,
    rgba(62, 28, 70, 0.36) 0%, transparent 70%);
  animation: fogDrift 19s ease-in-out infinite alternate;
  animation-delay: -7s;
}
@keyframes fogDrift {
  from { transform: translateX(-4%) scale(1); }
  to { transform: translateX(5%) scale(1.08); }
}
.chamber-runes {
  position: absolute;
  bottom: 7.5%; left: 0; right: 0;
  text-align: center;
  font-family: var(--font-title);
  letter-spacing: 0.55em;
  font-size: 13px;
  color: rgba(201, 162, 70, 0.38);
  text-shadow: 0 0 14px rgba(201, 162, 70, 0.35);
  animation: runeGlow 7s ease-in-out infinite alternate;
}
@keyframes runeGlow {
  from { opacity: 0.45; letter-spacing: 0.55em; }
  to { opacity: 0.9; letter-spacing: 0.7em; }
}
.chamber-vignette {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 72% 68% at 50% 44%,
    transparent 40%,
    rgba(0, 0, 0, 0.42) 78%,
    rgba(0, 0, 0, 0.82) 100%);
}
.chamber-filigree { position: absolute; inset: 0; color: #c9a246; }
.filigree {
  position: absolute;
  width: 78px; height: 78px;
  filter: drop-shadow(0 0 6px rgba(201, 162, 70, 0.35));
}
.filigree-tl { top: 16px; left: 16px; }
.filigree-tr { top: 16px; right: 16px; transform: scaleX(-1); }
.filigree-bl { bottom: 16px; left: 16px; transform: scaleY(-1); }
.filigree-br { bottom: 16px; right: 16px; transform: scale(-1); }

@media (max-width: 760px) {
  .booster-backdrop .chamber-lantern, .chamber-runes { display: none; }
  .filigree { width: 52px; height: 52px; }
}

/* Faisceau d'ambiance selon la rareté maximale du pack */
.ambient-rarity-beam {
  position: absolute; inset: -50%;
  background: radial-gradient(circle at 50% 50%, var(--ambient-beam-color, rgba(245, 185, 66, 0.1)) 0%, transparent 62%);
  pointer-events: none; opacity: 0.7; transition: all 1.2s ease; z-index: 2;
  mix-blend-mode: screen;
}

.booster-particles {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 3;
}
.chamber-ember {
  position: absolute; bottom: -4%;
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--spark-color, #e8b45a);
  box-shadow: 0 0 8px var(--spark-color, #e8b45a);
  animation: emberRise var(--spark-dur, 7s) ease-in infinite;
}
@keyframes emberRise {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0; }
  12% { opacity: 0.85; }
  100% { transform: translate(var(--drift, 12px), -110vh) scale(0.2); opacity: 0; }
}
.chamber-mote {
  position: absolute; bottom: -2%;
  width: 2px; height: 2px; border-radius: 50%;
  background: rgba(255, 236, 200, 0.5);
  box-shadow: 0 0 4px rgba(255, 236, 200, 0.35);
  animation: moteDrift var(--spark-dur, 12s) linear infinite;
}
@keyframes moteDrift {
  0% { transform: translate(0, 0); opacity: 0; }
  18% { opacity: 0.5; }
  100% { transform: translate(28px, -100vh); opacity: 0; }
}

.booster-stage {
  position: relative; z-index: 10;
  width: 100%; min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 40px 24px;
}

/* Barre de Contrôles Supérieure
 *  Ancrée à la fenêtre, et non à la scène : quand le bilan d'ouverture
 *  rend la scène plus haute que l'écran, la scène centrée déborde par le
 *  haut et le ✕ se faisait couper en deux. Fixe, il reste entier, quel que
 *  soit le nombre de cartes tirées. */
.booster-top-controls {
  position: fixed; top: 16px; right: 40px; z-index: 30;
  display: flex; align-items: center; gap: 10px;
}
.booster-ctrl-btn {
  width: 42px; height: 42px; border-radius: 50%;
  background:
    radial-gradient(circle at 40% 28%, rgba(80, 58, 28, 0.95), #140e08 72%);
  border: 1px solid rgba(201, 162, 70, 0.5);
  color: #e8c56a; font-size: 17px; cursor: pointer;
  display: grid; place-items: center;
  box-shadow:
    0 4px 14px rgba(0, 0, 0, 0.7),
    inset 0 1px 0 rgba(255, 220, 140, 0.22);
  transition: all .25s cubic-bezier(0.16, 1, 0.3, 1);
}
.booster-ctrl-btn:hover {
  background: radial-gradient(circle at 40% 28%, rgba(120, 80, 30, 0.95), #1a1008 72%);
  border-color: var(--accent);
  transform: scale(1.1);
}
.booster-ctrl-btn.is-muted { opacity: 0.5; filter: grayscale(1); }

/* ── Phase 1 : Le Pack Scellé & Cercle d'Incantation ─────────────────────── */
.pack-wrapper {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 32px;
  animation: packFadeIn .5s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes packFadeIn {
  from { opacity: 0; transform: scale(0.8); }
  to { opacity: 1; transform: scale(1); }
}

/*  LES VOILES FLOUS SONT PROMUS SUR LEUR PROPRE COUCHE.
 *
 *  Un flou de trente-six pixels sur un disque de 520 x 620 qu'on met a
 *  l'echelle en boucle : a chaque image, le navigateur refloute toute la
 *  surface, sur le processeur. Le grimoire sautille, et le texte pose par
 *  dessus sautille avec lui -- c'est le scintillement du bas de l'ecran.
 *
 *  `will-change` demande la couche a l'avance : le flou est calcule une fois,
 *  et l'animation ne fait plus que deplacer et fondre une image deja prete. */
.pack-ambient-dome {
  will-change: transform, opacity;
  position: absolute; top: 38%; left: 50%; transform: translate(-50%, -50%);
  width: 520px; height: 620px; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 42%,
    rgba(232, 180, 90, 0.2) 0%,
    rgba(80, 40, 16, 0.06) 48%,
    transparent 72%);
  filter: blur(36px); pointer-events: none;
  animation: domePulse 4s ease-in-out infinite alternate;
}
@keyframes domePulse {
  0% { transform: translate(-50%, -50%) scale(0.9); opacity: 0.6; }
  100% { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
}

/* Aura d'autel derrière le grimoire */
.pack-aura {
  position: absolute; top: 42%; left: 50%;
  transform: translate(-50%, -50%);
  width: 640px; height: 640px;
  pointer-events: none; z-index: 1;
}
.pack-halo {
  will-change: transform, opacity;
  position: absolute; inset: 0;
  border-radius: 50%;
  background: radial-gradient(ellipse 55% 60% at 50% 42%,
    rgba(255, 214, 130, 0.22) 0%,
    rgba(180, 110, 40, 0.06) 42%,
    transparent 68%);
  filter: blur(28px);
  animation: haloPulse 5s ease-in-out infinite alternate;
}
@keyframes haloPulse {
  0% { transform: scale(0.92); opacity: 0.6; }
  100% { transform: scale(1.12); opacity: 1; }
}
/*  Meme traitement pour les brumes : floutees, mises a l'echelle et EN PLUS
    en `mix-blend-mode`, elles forcaient le navigateur a refondre tout ce qui
    est dessous a chaque image. */
.pack-mist {
  will-change: transform, opacity;
  position: absolute;
  border-radius: 50%;
  filter: blur(28px);
  mix-blend-mode: screen;
}
.pack-mist-a {
  left: 8%; top: 28%;
  width: 46%; height: 38%;
  background: radial-gradient(ellipse, rgba(210, 170, 110, 0.22), transparent 70%);
  animation: mistDrift 11s ease-in-out infinite alternate;
}
.pack-mist-b {
  right: 6%; top: 34%;
  width: 42%; height: 34%;
  background: radial-gradient(ellipse, rgba(140, 90, 160, 0.14), transparent 70%);
  animation: mistDrift 14s ease-in-out infinite alternate-reverse;
}
@keyframes mistDrift {
  from { transform: translate(-8px, 6px) scale(1); opacity: 0.55; }
  to { transform: translate(12px, -10px) scale(1.12); opacity: 0.95; }
}
.pack-caustic {
  position: absolute;
  left: 50%; bottom: 4%;
  width: 78%; height: 28%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 50%,
    rgba(255, 214, 140, 0.22) 0%,
    rgba(201, 162, 70, 0.08) 46%,
    transparent 74%);
  filter: blur(10px);
}
.pack-glyph {
  position: absolute;
  font-family: var(--font-title);
  font-size: 18px;
  color: rgba(201, 162, 70, 0.28);
  text-shadow: 0 0 12px rgba(201, 162, 70, 0.35);
  animation: glyphFloat 9s ease-in-out infinite;
}
.pack-glyph.g1 { left: 8%; top: 22%; animation-delay: 0s; }
.pack-glyph.g2 { right: 10%; top: 38%; animation-delay: -3s; }
.pack-glyph.g3 { left: 18%; bottom: 18%; animation-delay: -6s; }
@keyframes glyphFloat {
  0%, 100% { transform: translateY(0); opacity: 0.2; }
  50% { transform: translateY(-14px); opacity: 0.55; }
}
.pack-wrapper.is-opening .pack-halo {
  background:
    radial-gradient(ellipse 70% 80% at 48% 40%,
      rgba(255, 220, 140, 0.4) 0%,
      rgba(201, 162, 70, 0.14) 46%,
      transparent 74%);
}

/* Onde de choc lors de la rupture */
.shockwave-burst {
  position: absolute; top: 45%; left: 50%; transform: translate(-50%, -50%) scale(0);
  width: 200px; height: 200px; border-radius: 50%;
  border: 3px solid rgba(232, 196, 120, 0.8);
  box-shadow: 0 0 60px rgba(201, 162, 70, 0.7), inset 0 0 40px rgba(232, 196, 120, 0.35);
  pointer-events: none; opacity: 0; z-index: 25;
}
.shockwave-burst.is-firing {
  animation: shockwaveBoom .75s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes shockwaveBoom {
  0% { transform: translate(-50%, -50%) scale(0.2); opacity: 1; border-width: 6px; }
  60% { opacity: 0.85; filter: brightness(2); }
  100% { transform: translate(-50%, -50%) scale(5.5); opacity: 0; border-width: 1px; }
}

.booster-pack-anchor {
  position: relative; z-index: 10;

  /* Les reperes projetes par Blender (out/grimoire/reperes.json), poses ici
     par main.js. Ils vivent sur l'ANCRE et non sur le coffret : la couche
     d'ejection est la SOEUR du coffret, pas sa fille -- posees sur lui, les
     variables ne descendaient pas jusqu'aux cartes, qui reprenaient alors la
     taille pleine du cadre. Valeurs de repli : celles du rendu actuel. */
  --poche-x: 53.8%;
  --poche-y: 35.1%;
  --poche-l: 20.4%;
  --poche-h: 31.9%;
  animation: packLevitate 4.5s ease-in-out infinite;
}
@keyframes packLevitate {
  0%, 100% { transform: translateY(0px) rotate(0deg); }
  50% { transform: translateY(-12px) rotate(0.8deg); }
}

.booster-pack {
  z-index: 2;
  /* Le coffret est CARRE : les rendus font 1280x1280. En gardant le cadre
     2:3 du sachet, `object-fit: contain` aurait laisse deux bandes vides et
     reduit l'objet d'un tiers. */
  position: relative; width: 360px; height: 360px;
  /*  ET IL TIENT DANS L'ECRAN, AVEC SES BOUTONS. A 360 px fixes, il
      depassait d'un iPhone SE (320 de large) et, sur un telephone bas --
      Android avec les barres de Phantom, telephone couche --, il repoussait
      « Ouvrir 1 grimoire » sous le pli. Il prend ce qui reste une fois les
      boutons et le titre poses (~280 px), jamais moins de 180. La pile et
      les calques sont en pourcentage de lui : ils suivent. */
  width: clamp(180px, min(calc(100vw - 40px), calc(100vh - 280px)), 360px);
  width: clamp(180px, min(calc(100vw - 40px), calc(100dvh - 280px)), 360px);
  height: auto; aspect-ratio: 1;
  cursor: pointer;
  user-select: none;

  /* La progression du geste, partagee par tous les calques. */
  --ouv: 0;

  filter: drop-shadow(0 26px 34px rgba(0, 0, 0, .85))
          drop-shadow(0 0 42px rgba(245, 185, 66, .22));
  transform: rotate(calc(var(--ouv) * -1deg));
  transition: transform .3s cubic-bezier(0.16, 1, 0.3, 1), filter .3s ease;
}
.booster-pack:hover {
  transform: translateY(-8px) scale(1.04) rotate(calc(var(--ouv) * -1deg));
  filter: drop-shadow(0 34px 44px rgba(0, 0, 0, .9))
          drop-shadow(0 0 62px rgba(245, 185, 66, .45));
}

.pack-calque {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  pointer-events: none;
  -webkit-user-drag: none;
}
/* Le corps dessous -- en deux etats superposes -- puis la porte. */
.pack-corps-vide { z-index: 1; }
.pack-corps { z-index: 2; }

/* LA PORTE, EN DEUX TEMPS.
   Elle s'enfonce d'abord -- un fondu entre les deux rendus, parce qu'une
   piece qui recule change de parallaxe et d'ombre, pas d'echelle -- puis
   elle coulisse vers la gauche, par-dessus le plat, comme un couvercle de
   boite d'allumettes. */
.pack-porte, .pack-porte-enfoncee {
  z-index: 4;
  transition: opacity .12s linear, transform .12s linear;
}
.pack-porte { opacity: calc(1 - var(--ouv) * 6); }
.pack-porte-enfoncee {
  opacity: calc(var(--ouv) * 6);
  /* Le glissement ne commence qu'une fois la porte ENFONCEE : la course
     n'ouvre qu'a partir du sixieme du geste, le temps de l'enfoncement. */
  transform: translateX(calc(max(0, var(--ouv) - 0.16) * -46%));
}

/* ── Piste de Déchirure Tactile (Swipe-to-Rip) ────────────────────────── */
.rip-swipe-track {
  /* UNE ZONE DE PRISE INVISIBLE.
     
     Le pointille, la pastille doree et le libelle sont retires : ils se
     posaient par-dessus les dorures de la porte et les salissaient. La zone
     reste, et le glissement vers la gauche fonctionne toujours pour qui
     l'essaie -- c'est le bouton qui porte desormais l'invitation. */
  position: absolute; top: 46%; left: 50.5%; width: 25.5%; height: 9%;
  z-index: 20;
  cursor: grab;
  touch-action: none;
  background: none; border: 0;
}
.rip-swipe-track:active { cursor: grabbing; }




.pack-prompt {
  position: relative; z-index: 10;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  transition: opacity .25s ease;
}
/*  LE RITUEL LANCE, LES BOUTONS S'EFFACENT. Ils restaient allumes sous la
 *  pile pendant toute l'ouverture -- « Ouvrir 1 grimoire », « Ouvrir 3 »
 *  coupes en deux par le paquet, encore touchables --, et le choix du lot
 *  reparaissait en plein ecran pendant la dissipation, quand le coffret
 *  avait deja disparu. Ils reviennent avec `resetBoosterStage`. */
.pack-wrapper.is-opening .pack-prompt {
  opacity: 0;
  pointer-events: none;
}
.btn-rip-pack {
  padding: 15px 36px; font-size: 16px; font-weight: 900; letter-spacing: 0.12em;
  box-shadow:
    0 8px 32px rgba(201, 162, 70, 0.4),
    0 0 16px rgba(232, 180, 90, 0.22),
    inset 0 1px 0 rgba(255, 236, 180, 0.35);
}
.btn-rip-pack:hover {
  transform: translateY(-2px) scale(1.05);
  box-shadow: 0 14px 44px rgba(201, 162, 70, 0.55), 0 0 18px rgba(232, 196, 120, 0.35);
}
.pack-hint {
  text-align: center; max-width: 100%;
  color: rgba(201, 162, 70, 0.55);
  font-family: var(--font-title);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* ── Animation de Déchirure Physique et Éjection des Cartes ────────────────── */
/* Le logement SE VIDE au moment ou la pile se leve.
   
   Le fondu emporte aussi l'ombre et le rebond de lumiere des cartes sur le
   velours -- ils sont dans le rendu, pas ajoutes apres coup. */
.booster-pack.is-ripping .pack-corps {
  animation: pocheSeVide .3s ease-out .56s forwards;
}
@keyframes pocheSeVide {
  to { opacity: 0; }
}

/* ── L'ouverture, une fois lancee ────────────────────────────────────── */
.booster-pack.is-ripping .pack-porte { opacity: 0; }
.booster-pack.is-ripping .pack-porte-enfoncee {
  animation: porteCoulisse 1s cubic-bezier(.22, 1, .3, 1) forwards;
}
@keyframes porteCoulisse {
  0%   { transform: translateX(-6%); opacity: 1; }
  62%  { transform: translateX(-40%); opacity: 1; }
  100% { transform: translateX(-58%); opacity: 0; }
}

/* Le coffret ne disparait plus : il se recule doucement une fois vide, et
   laisse la place a la rangee de cartes. */
.booster-pack.is-ripping {
  animation: coffretRecule 2.32s cubic-bezier(.16, 1, .3, 1) forwards;
}
@keyframes coffretRecule {
  /* Il tressaille a l'ouverture, PUIS ATTEND. La pile finit de sortir a
     1600 ms et se dissout jusqu'a 2280 : le grimoire ne commence a se retirer
     qu'a 70 % de sa course, soit 1620 ms, en meme temps que la lame part.
     Un livre qui s'efface pendant que son contenu en sort raconte l'inverse
     de ce qui se passe -- mais un livre qui s'attarde apres, aussi. */
  0%   { transform: rotate(-1deg) translateY(0); }
  5%   { transform: rotate(-1.7deg) translateY(-4px); }
  12%  { transform: rotate(-.5deg) translateY(1px); }
  22%  { transform: rotate(0deg) translateY(0); }
  70%  { transform: rotate(0deg) translateY(0); opacity: 1; }
  100% { transform: rotate(0deg) translateY(54px) scale(.90); opacity: 0; }
}

/* Les cartes sortent réellement du sachet avant de rejoindre leur rangée. */
/* ── La pile qui sort du coffret ──────────────────────────────────────── */
.pack-pile {
  /* Elle nait EXACTEMENT sur la poche -- position et taille reprises des
     reperes projetes par Blender. Aucun nombre releve a l'oeil sur le PNG. */
  position: absolute; z-index: 5;
  left: var(--poche-x); top: var(--poche-y);
  width: var(--poche-l); height: var(--poche-h);
  pointer-events: none;
  opacity: 0;
  /*  L'OMBRE EST CELLE DU PAQUET, PAS DE CHAQUE CARTE. Posee sur la pile,
      elle suit l'alpha du dos detoure -- ses coins arrondis --, la ou une
      `box-shadow` par image dessinait sept rectangles a angles vifs. */
  filter: drop-shadow(0 10px 16px rgba(0, 0, 0, .8))
          drop-shadow(0 0 10px rgba(245, 185, 66, .25));
}
/*  NEUF DOS, ET LA TRANCHE SE LIT.
 *
 *  Le decalage de chaque carte est pose en ligne (voir `epaissirPile`) ; ce
 *  qui se regle ici est la LUMIERE. Une pile de cartes n'est pas neuf images
 *  empilees : c'est une tranche, donc une arete claire en haut de chaque
 *  carte, une ombre courte sous elle, et une seule ombre longue sous
 *  l'ensemble. Sans l'arete, la pile est un bloc noir ; sans l'ombre courte,
 *  elle est un mille-feuille sans poids. */
.pack-pile img {
  position: absolute; inset: 0;
  /*  CONTAIN, JAMAIS COVER. En `cover`, un dos dont le format differe d'un
      rien de celui de la pile perd le haut et le bas de son cadre -- c'est
      ce qu'on voyait a la sortie du grimoire. */
  width: 100%; height: 100%; object-fit: contain; display: block;
  /*  LE MASQUE DE DISSIPATION, AU REPOS.
   *
   *  Il est declare ici et NE BOUGE PAS tant que l'animation ne le pousse
   *  pas : cadre de 260 % dont la partie opaque couvre toute la carte. Une
   *  fois lance, il remonte, et la carte se mange par le bas. Le degrade est
   *  long (18 points) : c'est lui qui donne le bord effrange, pas une
   *  texture. */
  -webkit-mask-image: linear-gradient(to top, transparent 0 48%, #000 60% 100%);
  mask-image: linear-gradient(to top, transparent 0 48%, #000 60% 100%);
  -webkit-mask-size: 100% 300%; mask-size: 100% 300%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 0 8%; mask-position: 0 8%;
}

/*  LA LAME. Une barre de lumiere large comme la pile, qui la remonte de bas
 *  en haut. Elle n'est PAS masquee -- c'est elle qui mange, elle ne peut pas
 *  etre mangee -- et elle tient au-dessus de toutes les couches. */
.pile-lame {
  position: absolute; left: -8%; right: -8%;
  height: 26px; bottom: -6px;
  z-index: 40; opacity: 0;
  border-radius: 50%;
  background: linear-gradient(to top,
    transparent, rgba(255, 214, 140, .85) 45%, #fff6e2 60%, rgba(255, 214, 140, .8) 72%, transparent);
  filter: blur(3px);
  box-shadow: 0 0 34px rgba(255, 196, 96, .9);
}

/*  DEUX TEMPS, DEUX ANIMATIONS, DES PROPRIETES DISJOINTES.
 *
 *  `pileSort` tient la POSE (transform, opacite) ; `pileSeDissout` tient la
 *  MATIERE (le masque, la couleur). Elles se suivent sur le meme element sans
 *  se marcher dessus parce qu'elles ne touchent pas aux memes proprietes --
 *  si les deux ecrivaient `transform`, la seconde effacerait la premiere. */
.pack-wrapper.is-opening .pack-pile {
  animation: pileSort 1.08s cubic-bezier(.16, 1, .3, 1) .52s both,
             pileCharge .5s ease-in 1.12s both;
}
/*  LA PILE SE CHARGE AVANT DE PARTIR. Arrivee au centre, elle ne restait
 *  qu'immobile, puis la lame la mangeait : rien n'annoncait ce qui allait
 *  arriver. Pendant la demi-seconde qui precede, sa lueur monte -- la
 *  lumiere qui va la dissoudre est deja DEDANS. Seul `filter` bouge ici :
 *  `pileSort` tient la pose, les deux ne se marchent pas dessus. */
@keyframes pileCharge {
  0%   { filter: drop-shadow(0 10px 16px rgba(0, 0, 0, .8))
                 drop-shadow(0 0 10px rgba(245, 185, 66, .25)); }
  100% { filter: drop-shadow(0 10px 16px rgba(0, 0, 0, .6))
                 drop-shadow(0 0 26px rgba(255, 214, 140, .95)); }
}
/*  La pile passe DEVANT les boutons. Elle vit dans l'ancre du coffret
 *  (z-index 10) et le pupitre « Ouvrir 1 grimoire » en vaut autant : a egalite
 *  c'est le dernier du document qui gagne, et le paquet arrivait au centre de
 *  l'ecran derriere un bouton. */
.pack-wrapper.is-opening .booster-pack-anchor { z-index: 20; }
/*  ELLE VA AU CENTRE DE L'ECRAN, ET LE CENTRE SE MESURE.
 *
 *  Elle montait de `-130%` de sa propre hauteur, DROIT. C'etait juste tant
 *  que le coffret tenait le milieu d'un grand ecran : la poche est a 64 % de
 *  la largeur du coffret, donc la pile sortait deja a droite, et au telephone
 *  elle finissait en haut a droite, coupee par le bord de la fenetre -- le
 *  paquet qu'on vient d'ouvrir, on ne le voyait pas.
 *
 *  Le trajet ne peut pas s'ecrire en pourcentages : il depend d'ou la poche
 *  tombe dans l'ecran, ce que seul le navigateur sait. `viserLeCentre` le
 *  mesure au moment ou la porte s'ouvre et pose `--pile-dx`, `--pile-dy` et
 *  `--pile-ech` ; les valeurs de repli ci-dessous redonnent l'ancienne
 *  montee, au cas ou la mesure echouerait. */
@keyframes pileSort {
  /*  Elle sort du logement, gagne le milieu de l'ecran, s'agrandit et tient
   *  en l'air. Elle ne se dissipe pas ici : une pile qui disparait pendant
   *  qu'elle sort raconte deux choses a la fois, et on n'en lit aucune. */
  0%   { opacity: 0; transform: translate(0, 0) scale(1); }
  13%  { opacity: 1; }
  64%  {
    transform: translate(calc(var(--pile-dx, 0px) * .95), calc(var(--pile-dy, -130%) * .93))
               scale(calc(var(--pile-ech, 1.66) * .97)) rotate(-2.2deg);
  }
  88%  {
    transform: translate(var(--pile-dx, 0px), calc(var(--pile-dy, -130%) * 1.015))
               scale(calc(var(--pile-ech, 1.66) * 1.006)) rotate(.4deg);
  }
  100% {
    opacity: 1;
    transform: translate(var(--pile-dx, 0px), var(--pile-dy, -130%))
               scale(var(--pile-ech, 1.66)) rotate(0deg);
  }
}

/*  LA DISSIPATION : LA PILE SE MANGE PAR LE BAS.
 *
 *  Chaque dos porte SON masque, et chaque dos est decale de quelques pixels :
 *  la ligne de dissolution ne passe donc pas au meme instant sur toutes les
 *  couches. Le paquet ne s'efface pas d'un bloc, il se defeuille. Aucun
 *  reglage a faire pour ca -- c'est l'epaisseur de la pile qui l'obtient. */
.pack-wrapper.is-opening .pack-pile img {
  /*  TOUTES LES COUCHES ENSEMBLE. Un retard par couche avait ete essaye (la
      carte du dessus d'abord) : les cartes du dessous restaient ENTIERES
      sous la lame, et le paquet ne se defaisait plus, il changeait de
      carte. */
  animation: pileSeDissout .66s cubic-bezier(.4, 0, .75, .35) 1.62s both;
}
@keyframes pileSeDissout {
  /*  LES DEUX BORNES SONT CALCULEES, PAS CHOISIES.
   *
   *  Le cadre du masque fait trois fois la hauteur de la carte : sa moitie
   *  haute est opaque, sa moitie basse transparente. Le glisser de 8 % a 62 %
   *  amene exactement la frontiere du bas de la carte jusqu'a son sommet --
   *  ni plus (la fin serait un temps mort), ni moins (il resterait un bandeau
   *  de carte a l'ecran). A 0 % la carte est pleine, a 100 % il n'en reste
   *  rien. */
  0%   { -webkit-mask-position: 0 8%; mask-position: 0 8%; filter: none; }
  55%  { filter: brightness(1.8) saturate(.85); }
  100% { -webkit-mask-position: 0 62%; mask-position: 0 62%;
         filter: brightness(2.8) saturate(.55); }
}
.pack-wrapper.is-opening .pile-lame {
  animation: lameMonte .66s cubic-bezier(.4, 0, .75, .35) 1.62s both;
}
@keyframes lameMonte {
  0%   { opacity: 0; bottom: -6px; transform: scaleX(.72); }
  12%  { opacity: 1; transform: scaleX(1); }
  82%  { opacity: 1; }
  100% { opacity: 0; bottom: 104%; transform: scaleX(.55); }
}

/*  LA GERBE DE BRAISES.
 *
 *  Elle vit par-dessus tout, en `position: fixed`, et ne prend aucun clic :
 *  c'est de la lumiere, pas de la matiere. Chaque braise a son ecart, sa
 *  montee, sa taille et son retard, tires au sort a la naissance -- une
 *  gerbe reguliere ressemble a une rampe de LED. */
.gerbe-paquet { position: fixed; inset: 0; z-index: 4200; pointer-events: none; }
.gerbe-paquet i {
  position: fixed;
  width: var(--taille, 3px); height: var(--taille, 3px);
  margin: calc(var(--taille, 3px) / -2);
  border-radius: 50%;
  background: var(--teinte, #f0d9a0);
  box-shadow: 0 0 10px var(--teinte, #f0d9a0);
  animation: braiseMonte 1s cubic-bezier(.2, .7, .3, 1) both;
}
@keyframes braiseMonte {
  0%   { opacity: 0; transform: translate(0, 0) scale(.4); }
  14%  { opacity: 1; transform: translate(calc(var(--dx) * .12), calc(var(--dy) * .10)) scale(1.25); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.25); }
}

/*  L'ECLAT : la lumiere du paquet ramassee en un point (voir
 *  `dissiperLePaquet`). Un coeur blanc qui gonfle et s'eteint, un anneau de
 *  la couleur du lot qui s'en echappe. */
.eclat-paquet {
  position: fixed; z-index: 4200; pointer-events: none;
  width: 0; height: 0;
}
.eclat-paquet i, .eclat-paquet b {
  position: absolute; left: 0; top: 0;
  width: var(--taille, 160px); height: var(--taille, 160px);
  margin: calc(var(--taille, 160px) / -2);
  border-radius: 50%;
}
.eclat-paquet i {
  background: radial-gradient(circle, #fffaf0 0%, var(--teinte, #f0d9a0) 30%, transparent 68%);
  animation: eclatCoeur .55s cubic-bezier(.2, .8, .3, 1) both;
}
.eclat-paquet b {
  border: 2px solid var(--teinte, #f0d9a0);
  box-shadow: 0 0 18px var(--teinte, #f0d9a0);
  animation: eclatAnneau .7s cubic-bezier(.15, .85, .3, 1) both;
}
@keyframes eclatCoeur {
  0%   { opacity: 0; transform: scale(.2); }
  25%  { opacity: 1; transform: scale(.9); }
  100% { opacity: 0; transform: scale(1.3); }
}
@keyframes eclatAnneau {
  0%   { opacity: 0; transform: scale(.3); }
  20%  { opacity: .9; }
  100% { opacity: 0; transform: scale(2.6); }
}

/*  LES TRAITS : un par carte, de l'eclat jusqu'a l'emplacement. Une tete
 *  claire, une queue qui s'efface derriere elle -- la queue est le trait
 *  lui-meme, tourne vers sa cible. */
.traits-paquet { position: fixed; inset: 0; z-index: 4200; pointer-events: none; }
.traits-paquet i {
  position: fixed; width: 0; height: 0;
  animation: traitVole 380ms cubic-bezier(.55, 0, .35, 1) both;
}
.traits-paquet i::before {
  content: ""; position: absolute; right: 0; top: -2px;
  width: 90px; height: 4px; border-radius: 4px;
  transform-origin: 100% 50%;
  transform: rotate(var(--angle, 0rad));
  background: linear-gradient(90deg, transparent, var(--teinte, #f0d9a0) 70%, #fffaf0);
  box-shadow: 0 0 12px var(--teinte, #f0d9a0);
}
@keyframes traitVole {
  0%   { opacity: 0; transform: translate(0, 0) scale(.3); }
  15%  { opacity: 1; }
  85%  { opacity: 1; transform: translate(calc(var(--dx) * .96), calc(var(--dy) * .96)) scale(1); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.2); }
}

/* ── Phase 2 : Révélation des 5 Cartes Mystérieuses ──────────────────────── */
/*  LA REVELATION DEFILE, QUEL QUE SOIT LE NOMBRE DE CARTES.
 *
 *  Le defilement n'etait accorde qu'au mode « lot » (`.is-lot`). A un ou
 *  trois grimoires, la rangee fait pourtant 1430 px de haut sur un ecran de
 *  768 : elle depassait dans `.booster-stage`, qui est lui-meme dans un
 *  `#booster-modal` en `overflow: hidden`. Personne ne pouvait donc defiler
 *  -- ni la molette, ni le doigt -- et le bas de la rangee, avec les boutons
 *  « Ouvrir un autre » et « Terminer », etait INATTEIGNABLE.
 *
 *  `overflow-x` est ferme exprès : le sceau d'apparition deborde de chaque
 *  carte, et sur les colonnes de bord ce debord ferait naitre une barre
 *  horizontale. */
.cards-reveal-area {
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  width: 100%;
  max-height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  /*  DE LA MARGE POUR LES HALOS. La zone defile, donc elle COUPE : la lueur
      de rarete des cartes -- et l'ombre de celle qu'on agrandit -- etait
      tranchee net au ras de la rangee, sur toute la largeur. Le bas et les
      cotes laissent maintenant la place a la plus grande lueur. La Mythique
      pulse jusqu'a 80 px de flou et le survol y ajoute son ombre : 88 px
      tranchaient encore le halo (23/09/2026), d'ou 128. */
  padding: 8px 56px 128px;
  box-sizing: border-box;
  animation: revealAreaFadeIn .5s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes revealAreaFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.reveal-header { text-align: center; }
.reveal-header::after {
  content: '';
  display: block;
  width: 148px; height: 1px;
  margin: 14px auto 0;
  background: linear-gradient(90deg, transparent, rgba(201, 162, 70, 0.7), transparent);
  box-shadow: 0 0 8px rgba(201, 162, 70, 0.35);
}
.reveal-kicker {
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: 0.32em; color: #c9a246;
  text-transform: uppercase;
  text-shadow: 0 0 16px rgba(201, 162, 70, 0.35);
}
.reveal-title {
  margin: 6px 0 0; font-family: var(--font-ornate); font-size: 28px; font-weight: 700;
  color: #f3e6c0; letter-spacing: 0.04em;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.8), 0 0 24px rgba(201, 162, 70, 0.18);
}
.reveal-hint {
  margin: 8px 0 0; color: rgba(196, 178, 148, 0.72); font-size: 14px;
}

/* ── Bandeau de Score de Chance du Tirage ─────────────────────────────────── */
.pull-score-banner {
  width: min(840px, 92vw);
  background: linear-gradient(135deg, rgba(28, 16, 10, 0.92) 0%, rgba(10, 8, 8, 0.95) 100%);
  border: 1.5px solid rgba(201, 162, 70, 0.4);
  border-radius: 4px;
  padding: 16px 28px;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.8), 0 0 20px rgba(201, 162, 70, 0.22);
  animation: pullBannerSlide .6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes pullBannerSlide {
  from { opacity: 0; transform: translateY(-16px) scale(0.92); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.pull-score-left { display: flex; flex-direction: column; gap: 2px; }
.pull-score-kicker {
  font-family: var(--font-title); font-size: 10px; font-weight: 900;
  letter-spacing: 0.24em; color: var(--accent);
}
.pull-rating-title {
  margin: 0; font-family: var(--font-title); font-size: 20px; font-weight: 900;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pull-rating-desc { margin: 0; font-size: 13px; color: var(--ink-dim); }

.pull-score-right { display: flex; align-items: center; gap: 16px; }
.pull-score-badge {
  background: radial-gradient(circle, rgba(245, 185, 66, 0.25) 0%, rgba(14, 18, 30, 0.9) 100%);
  border: 1.5px solid var(--accent); border-radius: 12px;
  padding: 6px 14px; text-align: center;
  box-shadow: 0 0 16px rgba(245, 185, 66, 0.4);
}
.score-val {
  display: block; font-family: var(--font-title); font-size: 26px; font-weight: 900;
  color: #fff; line-height: 1;
}
.score-lbl {
  display: block; font-size: 8px; font-weight: 900; letter-spacing: 0.14em;
  color: var(--accent-light); margin-top: 2px;
}
.pull-score-stars {
  font-size: 22px; color: var(--accent);
  letter-spacing: 2px;
  filter: drop-shadow(0 0 8px rgba(245, 185, 66, 0.8));
}

/* CINQ PAR RANGEE, ET CHAQUE RANGEE CENTREE.
   
   Deux essais ont echoue pour des raisons opposees. Le flux libre laissait la
   largeur decider du nombre par rangee -- 3+2, 4+3 selon l'ecran -- et les
   cartes du bas tombaient entre celles du haut. La grille, elle, remplissait
   bien de gauche a droite, mais une grille ne sait pas centrer sa derniere
   rangee incomplete : les deux dernieres restaient calees a gauche.
   
   La solution tient dans une LARGEUR : un flux centre, borne a exactement
   cinq colonnes. La rangee du haut se remplit donc de gauche a droite, elle
   est pleine, et les deux dernieres se centrent d'elles-memes en dessous. */
.reveal-cards-row {
  display: flex; flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
  width: 100%;
  max-width: calc(5 * 184px + 4 * 24px);   /* 1016px : cinq cartes, quatre ecarts */
  margin: 0 auto;
  perspective: 1400px;
}
@media (max-width: 1120px) {
  .reveal-cards-row { max-width: calc(4 * 184px + 3 * 24px); }
}
@media (max-width: 900px) {
  .reveal-cards-row { max-width: calc(3 * 184px + 2 * 24px); }
}
@media (max-width: 680px) {
  .reveal-cards-row { max-width: calc(2 * 184px + 24px); }
}

/* Emplacement de carte 3D. La carte parait ici meme -- rien ne s'y deplace. */
.reveal-card-slot {
  position: relative; width: 184px; height: 280px;
  /*  Le meme ancrage au repos qu'au survol : sinon il bascule au debut de la
      transition et la carte saute avant de grandir. */
  transform-origin: 50% 100%;
  perspective: 1400px; cursor: pointer;
  border-radius: 14px;
  transition: transform .35s cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow .35s ease, filter .35s ease;
}

/*  L'APPARITION : LA CARTE SE FORME A SA PLACE.
 *
 *  Rien ne se deplace. La carte nait couchee et floue au fond d'un sceau de
 *  lumiere, se redresse, prend sa nettete, et le sceau s'eteint derriere
 *  elle. Un seul geste par carte, joue par un seul element : il n'y a plus de
 *  raccord a tenir entre un paquet et une grille, donc plus rien a
 *  desaccorder.
 *
 *  La classe est RETIREE a la fin (voir `faireParaitreLesCartes`) : une
 *  animation en `fill: both` garde sa derniere image, et tant qu'elle est la
 *  aucun `:hover { transform }` ne peut passer. */
/*  LA CARTE SE POSE, DE DOS, PRETE A ETRE RETOURNEE.
 *
 *  Elle naissait couchee et floue, et se redressait face a nous : une
 *  apparition, pas une donne. Alexandre voulait des cartes POSEES. Elle
 *  nait donc de la lumiere de son trait, un peu au-dessus de la table et
 *  un peu plus grande -- plus pres de l'oeil --, descend, touche (60 %),
 *  s'ecrase d'un rien et se tient. C'est a l'instant du contact que le son
 *  tombe et que l'anneau du sceau part (voir `.carte-sceau b`). */
.reveal-card-slot.parait {
  animation: carteSePose .72s cubic-bezier(.3, .7, .35, 1) var(--app-delai, 0ms) both;
}
@keyframes carteSePose {
  0% {
    opacity: 0;
    transform: translateY(-26px) scale(1.08) rotate(-2deg);
    filter: brightness(3) blur(3px);
  }
  24% { opacity: 1; filter: brightness(1.9) blur(1px); }
  60% {
    transform: translateY(2px) scale(.985) rotate(0deg);
    filter: brightness(1.15) blur(0);
  }
  78% { transform: translateY(-1px) scale(1.006); }
  100% { opacity: 1; transform: none; filter: none; }
}

/*  LE SCEAU. Deux pieces : un disque qui s'ouvre sous la carte (`i`) et
 *  l'anneau qui s'en echappe (`b`). Il ne prend aucun clic et disparait de la
 *  page des qu'il a fini -- ce qui ne sert qu'une fois ne doit pas rester. */
/*  LA CARTE SORT DU SCEAU, ELLE N'EST PAS POSEE DESSUS.
 *
 *  Le disque passe DERRIERE la carte (z-index 0, la carte a 1) : c'est de la
 *  lumiere qui vient du fond, et la carte s'y decoupe. Seul l'anneau passe
 *  devant (3) -- il s'echappe vers nous, il doit croiser la carte en chemin.
 *  Le sceau lui-meme ne porte AUCUN z-index : il ne doit pas creer de couche,
 *  sinon ses deux pieces se retrouvent enfermees du meme cote. */
.carte-sceau {
  position: absolute; inset: -18%;
  pointer-events: none;
}
.carte-sceau i, .carte-sceau b {
  position: absolute; inset: 0; margin: auto;
  border-radius: 50%;
  content: "";
}
.carte-sceau i {
  z-index: 0;
  width: 74%; height: 52%;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(255, 240, 200, .95) 0%, rgba(245, 185, 66, .55) 38%, transparent 72%);
  filter: blur(6px);
  animation: sceauSouffle .8s ease-out var(--app-delai, 0ms) both;
}
.carte-sceau b {
  z-index: 3;
  width: 58%; height: 40%;
  border: 1.5px solid rgba(245, 205, 130, .85);
  box-shadow: 0 0 18px rgba(245, 185, 66, .6), inset 0 0 14px rgba(245, 185, 66, .45);
  /*  L'anneau part au CONTACT, pas a la naissance : 60 % de .72 s. */
  animation: sceauAnneau .92s cubic-bezier(.15, .85, .3, 1) calc(var(--app-delai, 0ms) + 430ms) both;
}
@keyframes sceauSouffle {
  0%   { opacity: 0; transform: scale(.25); }
  22%  { opacity: 1; transform: scale(1.05); }
  100% { opacity: 0; transform: scale(1.5); }
}
@keyframes sceauAnneau {
  0%   { opacity: 0; transform: scale(.2) rotate(-18deg); }
  18%  { opacity: 1; }
  100% { opacity: 0; transform: scale(2.35) rotate(14deg); }
}

.reveal-card-3d {
  position: relative; z-index: 1; width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform .7s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.reveal-card-slot.is-flipped .reveal-card-3d {
  transform: rotateY(180deg);
}

/* PLUS D'ECORNAGE AU SURVOL.
   
   Il inclinait chaque carte survolee du meme rotateY(38deg) rotateX(-8deg) :
   cinq cartes cote a cote prenaient donc exactement la meme pose, ce qui ne
   ressemble a rien -- ni a une carte qu'on souleve, ni a un eventail. Le
   devoilement est desormais la seule rotation, et c'est une rotation SUR
   ELLE-MEME. */

.card-face {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.8);
}
/*  LA FACE NE DOIT PAS DEPENDRE DE `backface-visibility` SEULE.
 *
 *  Dans un WebKit qui aplatit la 3D -- un filtre ou un `will-change` sur un
 *  parent suffit sur iPhone, et le WebKit de bureau n'en fait jamais --, la
 *  face « cachee » ne l'est plus : les cartes posees montraient leur face EN
 *  MIROIR (« W3N » pour « NEW ») au lieu du dos, avant meme d'etre
 *  retournees. On bascule donc aussi la VISIBILITE, a mi-course de la
 *  rotation (0,08 s avec cette courbe) : une regle que tout moteur respecte,
 *  3D ou pas. */
.card-face-front { visibility: hidden; transition: visibility 0s linear .08s; }
.is-flipped .card-face-front { visibility: visible; }
.is-flipped .card-face-back { visibility: hidden; transition: visibility 0s linear .08s; }

/* Dos de carte KAIROS doré */
.card-face-back {
  /* LE dos du jeu, pas un dos dessine en CSS.
     
     Il y en avait deux : celui de la pile qui sort du coffret (l'art reel,
     dos_kairos.png) et celui-ci, redessine en degrade + blason + texte. Au
     moment ou la pile se distribue, le dos changeait donc sous les yeux du
     joueur -- ce qui se lit comme une coupure meme quand le mouvement est
     continu. */
  /*  Plus de bordure ni de fond : le dos porte son propre cadre de bronze,
      et un filet dore par-dessus en faisait deux. L'arrondi est celui du
      cadre (4,5 % de la largeur) -- a 14 px, la face rognait l'or des
      coins. */
  background: transparent;
  border: 0;
  border-radius: 4.5% / 2.9%;
  overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  box-shadow:
    0 14px 34px rgba(0, 0, 0, 0.85),
    inset 0 0 20px rgba(0, 0, 0, 0.9);
  transition: all .28s ease;
}
.back-art {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}

/* ── L'AURA D'ATTENTE : SUR UN CALQUE A ELLE ────────────────────────────
   
   Elle est la MEME pour toutes les cartes -- un dos ne doit rien dire de sa
   face, et une aura qui vend la meche supprime l'attente qu'elle cree.
   
   Mais elle vit sur un PSEUDO-ELEMENT, et c'est le point important. Posee
   directement sur la carte, elle se disputait la propriete `animation` avec
   celle de la pose : a specificite egale, la derniere ecrite l'emporte, et
   l'autre ne tourne jamais. Deux animations sur un meme element, c'est une
   seule animation et un bug. Chacune a son support. */
/*  L'AURA D'ATTENTE PULSE EN OPACITE, PAS EN OMBRE PORTEE.
 *
 *  Elle animait son `box-shadow` : a chaque image, le navigateur recalcule un
 *  flou de vingt a trente-huit pixels autour de la carte, et il le fait sur le
 *  processeur. Sur quatorze cartes ca passe ; sur cent quarante, c'est cent
 *  quarante flous redessines soixante fois par seconde -- l'aura saccade, et
 *  tout le reste avec.
 *
 *  L'ombre est desormais FIXE et c'est l'opacite qui respire : le navigateur
 *  la compose sur le GPU sans rien repeindre. A l'oeil, c'est le meme
 *  battement. */
.reveal-card-slot:not(.is-flipped)::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 0 34px rgba(245, 185, 66, .55);
  will-change: opacity;
  animation: attenteDoree 2.2s infinite alternate;
}
@keyframes attenteDoree {
  0%   { opacity: .55; }
  100% { opacity: 1; }
}

.reveal-card-slot:not(.is-flipped):hover {
  /* Un leger zoom sur place, rien d'autre (Alexandre, 10/10/2026). */
  transform: scale(1.06);
  z-index: 15;
}

/* Face avant de la carte */
.card-face-front {
  transform: rotateY(180deg);
  background: #090c14;
  border: 1.5px solid var(--card-border, #f5b942);
  display: flex; flex-direction: column;
  position: relative;
}
.card-face-front img {
  display: block; width: 100%; height: 100%; object-fit: cover;
}

/* Reflet Holographique Foil */

/* ── Éclats Élémentaires lors de la Révélation ───────────────────────────── */
.elem-burst-spark {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  pointer-events: none; z-index: 35;
  animation: elemBurstSpark .8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes elemBurstSpark {
  0% { transform: translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(0); opacity: 0; }
}

/* Halo de Rareté sur carte révélée */
/* LE MEME SOULEVEMENT QUE LE DOS. La carte devoilee grandissait a 1,55 au
   survol : dans une rangee de cinq, elle recouvrait ses deux voisines et le
   titre, et Alexandre l'a trouvee beaucoup trop forte (23/09/2026). Elle
   prend donc la force du dos (-12 px, 1,06) ; pour LIRE une carte, le clic
   l'ouvre en grand. */
.reveal-card-slot.is-flipped:hover {
  /*  `--tx` / `--ty` sont ecrits par le pointeur (`faireCourirLaLumiere`,
      main.js), comme le classeur le fait pour ses pochettes. Sans eux la
      carte grandissait sans jamais bouger, et la lumiere qui la balayait se
      lisait comme un calque qui glisse par-dessus. La perspective vient en
      TETE : posee apres les rotations, elle ne s'applique plus a elles. */
  /*  UN LEGER ZOOM, SUR PLACE (Alexandre, 10/10/2026). La carte montait et
      s'inclinait sous le pointeur ; elle ne fait plus que grandir un peu.
      La lumiere du filigrane court toujours (`--mx`, `--my`). */
  transform: scale(1.06);
  /*  Depuis son centre : a 1,06 elle ne deborde que de quelques pixels. */
  transform-origin: 50% 50%;
  z-index: 60;
  /*  L'OMBRE SUIT LE ZOOM. Reglee pour 1,55 (30 px de decalage, 50 de
      flou), elle descendait a 130 px sous la carte, et la zone des cartes --
      qui defile, donc qui coupe -- la tranchait net a 100 px. Pour un
      soulevement de 12 px, une ombre a sa mesure. */
  filter: drop-shadow(0 14px 20px rgba(0, 0, 0, .85))
          drop-shadow(0 0 22px var(--card-glow, #f5b942));
}
.reveal-card-slot.glow-commune.is-flipped {
  box-shadow: 0 0 24px rgba(200, 200, 200, 0.5);
}
.reveal-card-slot.glow-peu-commune.is-flipped {
  box-shadow: 0 0 32px rgba(16, 185, 129, 0.7);
}
.reveal-card-slot.glow-rare.is-flipped {
  box-shadow: 0 0 38px rgba(2, 132, 199, 0.85), 0 0 14px #38bdf8;
}
.reveal-card-slot.glow-epique.is-flipped {
  box-shadow: 0 0 45px rgba(147, 51, 234, 0.95), 0 0 18px #e9d5ff;
}
.reveal-card-slot.glow-legendaire.is-flipped {
  box-shadow: 0 0 55px rgba(245, 185, 66, 1), 0 0 26px #fff;
  animation: pulseLegendaire 2.2s infinite alternate;
}
/* Ces deux pulsations etaient NOMMEES mais jamais definies : `legendCardPulse`
   et `mythicRainbowPulse` n'existaient nulle part dans la feuille. Les cartes
   les plus rares etaient donc les seules a ne rien faire une fois revelees.
   Elles pulsent sur la LUEUR, jamais sur la position -- une carte posee ne
   bouge plus. */
@keyframes pulseLegendaire {
  0%   { box-shadow: 0 0 40px rgba(245, 185, 66, .85), 0 0 16px #fff; }
  100% { box-shadow: 0 0 70px rgba(245, 185, 66, 1), 0 0 32px #fff; }
}
@keyframes pulseMythique {
  0%   { box-shadow: 0 0 45px #ec4899, 0 0 24px #f59e0b; }
  50%  { box-shadow: 0 0 68px #8b5cf6, 0 0 30px #06b6d4; }
  100% { box-shadow: 0 0 80px #f43f5e, 0 0 34px #eab308; }
}
.reveal-card-slot.glow-mythique.is-flipped {
  box-shadow: 0 0 65px rgba(236, 72, 153, 1), 0 0 32px #f59e0b;
  animation: pulseMythique 2.6s infinite alternate;
}

/* Focus Cinématique Majeur */

/* Badge Nouvelle Carte */
.badge-new-card {
  position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
  z-index: 30;
  font-family: var(--font-title); font-size: 10px; font-weight: 900;
  letter-spacing: 0.14em;
  padding: 4px 11px; border-radius: 999px;
  background: var(--gold-grad); color: #171002;
  border: 1.5px solid #fff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.85), 0 0 16px var(--accent);
  animation: newBadgeBounce .65s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes newBadgeBounce {
  from { transform: translateX(-50%) scale(0); }
  to { transform: translateX(-50%) scale(1); }
}

/* Actions de Révélation */
.reveal-actions {
  display: flex; gap: 16px; align-items: center; margin-top: 10px;
}
.btn-reveal-all {
  font-size: 14px; font-weight: 800; color: var(--accent-light);
  letter-spacing: 0.06em;
}
.btn-open-another {
  padding: 13px 26px; font-size: 14px; font-weight: 800;
}
.btn-finish-pack {
  padding: 13px 22px; font-size: 14px;
}

/* ── LE VERNIS INVERSÉ ─────────────────────────────────────────────────────
 *
 * À partir d'Épique. Le vernis épargne l'illustration ET le pavé d'actions :
 * il ne reste que le cadre. Un reflet sur une illustration sombre lui mange
 * ses noirs ; sur un texte, il le rend pénible à lire.
 *
 * Les bords des deux fenêtres viennent de FENETRES_MATES (js/rules.js) et
 * sont posés en variables par le script : une seule source, un seul endroit
 * à corriger le jour où le gabarit bouge.
 */
.vernis {
  position: relative;
  /* `inline-block` par defaut : l'enveloppe epouse l'image au lieu de
   * s'etirer, et les fenetres mates -- posees en pourcentage -- tombent donc
   * exactement la ou elles sont sur la carte. Les conteneurs qui dimensionnent
   * eux-memes leur image la repassent en 100% plus bas. */
  display: inline-block;
  line-height: 0;
  border-radius: inherit;
}
/* Les valeurs de repos vivent sur la RACINE, pas sur la carte : c'est de la
 * racine que vient la lumiere, et une carte qui les redeclare cesserait de la
 * suivre. Voir js/vernis.js -- une seule lampe pour toute la page. */
:root { --mx: 0.5; --my: 0.5; --ang: 90; }
.vernis > img { position: relative; z-index: 0; }

.vernis-couche {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 1;
  border-radius: inherit;
  /* La decoupe est CALCULEE dans js/vernis.js a partir des fenetres mates
   * declarees dans js/rules.js. L'ecrire ici aussi ferait deux listes de
   * coordonnees a tenir d'accord -- et la pastille d'element, ronde, ne
   * s'ecrit de toute facon pas a la main. */
  clip-path: var(--vernis-decoupe);
}

/* DES BANDES, PAS UN POINT.
 *
 * La première version superposait un dégradé RADIAL — un point chaud qui
 * suivait le pointeur — et un dégradé CONIQUE. Les deux ont un centre par
 * construction, et ça se voyait : la carte avait l'air éclairée par une lampe
 * posée dessus, au lieu d'être une surface qu'on incline.
 *
 * Une vraie feuille holographique n'a pas d'origine. Elle porte des bandes
 * parallèles, et quand on penche la carte, les bandes BALAIENT toute la
 * surface d'un bord à l'autre. C'est l'angle qui fait tout.
 *
 * D'où deux dégradés LINÉAIRES : les teintes de la Roue en bandes larges, et
 * un éclat blanc étroit qui glisse par-dessus. `--ang` les oriente, la
 * position du pointeur fait glisser leur phase — le fond est plus grand que
 * la carte, donc on ne voit jamais où la bande commence ni où elle finit. */
.vernis-iris {
  background:
    /* L'éclat : une bande claire qui traverse. */
    repeating-linear-gradient(
      calc(var(--ang) * 1deg),
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, 0.55) 7%,
      rgba(255, 255, 255, 0) 15%,
      rgba(255, 255, 255, 0) 50%),
    /* Les teintes de la Roue, en bandes larges. */
    repeating-linear-gradient(
      calc(var(--ang) * 1deg),
      hsl(0 92% 62%) 0%,
      hsl(38 95% 60%) 9%,
      hsl(190 92% 60%) 18%,
      hsl(30 60% 44%) 27%,
      hsl(50 96% 66%) 36%,
      hsl(278 88% 64%) 45%,
      hsl(0 92% 62%) 54%);
  background-size: 240% 240%, 200% 200%;
  /* Les deux couches glissent à des vitesses différentes : l'éclat court plus
   * vite que les teintes, comme sur une vraie feuille où le reflet spéculaire
   * devance la diffraction. Sans cet écart, tout bouge d'un bloc et on
   * retrouve la sensation d'un calque collé. */
  background-position:
    calc(var(--mx) * 190%) calc(var(--my) * 190%),
    calc(var(--mx) * 100%) calc(var(--my) * 100%);
  mix-blend-mode: color-dodge;
  opacity: var(--vernis-force, 0.30);
}
/* Sans grain, un dégradé se lit comme du plastique : c'est lui qui fait la
 * différence entre un vernis et un calque coloré. */
.vernis-grain {
  background-image: var(--vernis-grain);
  background-size: 168px 168px;
  mix-blend-mode: overlay;
  opacity: calc(var(--vernis-force, 0.30) * 0.4);
}

/* Un fin liseré cerne chaque fenêtre mate. Sans lui, le vernis s'arrête net et
 * la coupure a l'air d'un défaut d'affichage ; avec, elle a l'air d'une
 * découpe voulue -- la même logique que le vernis sélectif en imprimerie. */
.vernis-cerne {
  position: absolute; z-index: 2;
  pointer-events: none;
  border: 1px solid rgba(255, 255, 255, 0.2);
  /*  Le rayon de l'impression (14 px sur 1024), et PAS D'OMBRE : un halo
   *  sombre de 10 px autour d'une boite a coins presque vifs se lisait comme
   *  un rectangle glisse sous le cadre arrondi. */
  border-radius: 11px;
}
.vernis-cerne.art {
  left: var(--art-g); right: calc(100% - var(--art-d));
  top: var(--art-h); bottom: calc(100% - var(--art-b));
}
.vernis-cerne.tuiles {
  left: var(--tui-g); right: calc(100% - var(--tui-d));
  top: var(--tui-h); bottom: calc(100% - var(--tui-b));
}

@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .vernis-iris { transition: none; }
}

/* L'enveloppe du vernis remplace l'image dans la mise en page : elle doit donc
 * occuper exactement la place que l'image occupait, sinon la carte se ratatine
 * au moment ou on la vernit. */
.cf--print > .vernis { width: 100%; height: 100%; }
.cf--print > .vernis > img { width: 100%; height: 100%; object-fit: cover; }

/* DANS LA LOUPE, C'EST L'IMAGE QUI COMMANDE, PAS L'ENVELOPPE.
 *
 * En contraignant les deux, l'enveloppe sortait a 893 px de haut et l'image a
 * 1226 : les fenetres mates, exprimees en POURCENTAGE de l'enveloppe,
 * tombaient a cote, et le liseré barrait l'illustration en plein milieu.
 *
 * L'image garde donc ses limites (.zoom-print), et l'enveloppe l'epouse. */
.zoom-wrap > .vernis { display: inline-block; width: auto; height: auto; }
.zoom-wrap > .vernis > img { display: block; }

/* Le vernis se glisse entre l'image et son conteneur : partout ou le conteneur
 * dimensionnait l'image, il doit maintenant dimensionner l'enveloppe. Sans
 * ces lignes, la carte se ratatine a la taille naturelle du PNG au moment ou
 * on la vernit. */
.card-face-front > .vernis,
.fan-card > .vernis,
.hand-card > .vernis,
.slot > .vernis { width: 100%; height: 100%; }

/* UNE CARTE VERNIE A LA MEME HAUTEUR QU'UNE CARTE NUE.
 *
 * Dans la main, les Epiques et au-dela sortaient six pixels plus hautes que
 * leurs voisines -- un rang de cartes aux sommets en dents de scie. Ce n'est
 * pas le vernis qui grandit : c'est son enveloppe, `inline-block`, qui
 * s'aligne sur la LIGNE DE BASE de la carte et se reserve donc la place des
 * jambages en dessous. `line-height: 0` sur l'enveloppe ne peut rien : c'est
 * la ligne du PARENT qui creuse cet espace, pas la sienne.
 *
 * Rendue `block`, l'enveloppe quitte le flux en ligne et epouse exactement
 * l'image -- comme le fait deja l'image nue chez les cartes sans vernis. */
.mc-carte > .vernis { display: block; }
.card-face-front > .vernis > img,
.fan-card > .vernis > img,
.hand-card > .vernis > img,
.slot > .vernis > img { width: 100%; height: 100%; object-fit: cover; }

/* AU REPOS, LE VERNIS EST POSÉ ; SOUS LA SOURIS, IL VIT.
 *
 * Une carte qu'on ne survole pas garde les valeurs de la racine : son reflet
 * est fixe. Celle qu'on survole reçoit les siennes et suit le pointeur. La
 * différence d'éclat est légère — c'est le MOUVEMENT qui distingue les deux,
 * pas la luminosité ; un écart marqué ferait clignoter la grille au passage
 * de la souris. */
.vernis-iris { transition: opacity .18s ease; }
.vernis--vif .vernis-iris { opacity: calc(var(--vernis-force, 0.30) * 1.3); }

@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .vernis-iris { transition: none; }
}

/* ══ LE JEU SUR TÉLÉPHONE ═══════════════════════════════════════════════════
 *
 * Un téléphone tenu debout n'est pas un écran de bureau étroit : c'est une
 * autre table. Sur bureau, le pupitre est à droite et la main en colonne à
 * gauche, parce que la place est large et le regard horizontal. En portrait
 * il n'y a plus de marge latérale du tout -- 390 pixels, moins que la seule
 * colonne de main -- et c'est la HAUTEUR qui abonde.
 *
 * On empile donc : la table en haut, le pupitre juste en dessous, la main tout
 * en bas, sous le pouce. Le geste de jeu (choisir une carte, puis sa place)
 * remonte alors de la main vers la table, ce qui est le sens naturel.
 *
 * Le canvas, lui, RETRÉCIT : il ne rend plus que la bande haute. La 3D ne se
 * dessine donc jamais derriere le pupitre ni derriere la main, et `cadrer()`
 * n'a rien a savoir de l'interface -- il lit la taille du canvas, qui dit
 * deja la verite. C'est ce qui evite une seconde arithmetique de marges,
 * fatalement desynchronisee de la premiere.
 */
@media (max-width: 1100px) and (orientation: portrait) {
  /* EN PARTIE, LA BARRE DU HAUT DISPARAIT.
     Quarante-six pixels de navigation au-dessus d'une table qui en reclame
     chacun : pendant un duel on ne va nulle part ailleurs. La hauteur qu'elle
     occupait retombe donc sur le plateau (`--topbar-h: 0`), et « Abandonner »
     reste la seule sortie -- comme dans la plupart des jeux. */
  body.play-on .topbar { display: none; }
  body.play-on { --topbar-h: 0px; }

  /*  RIEN NE BOUGE PLUS EN BAS DE L'ECRAN.
   *
   *  Le pupitre se dimensionnait sur son contenu, et son contenu change a
   *  chaque tour : « À toi de jouer » fait une ligne, « Choisis ta
   *  creature-heros... » en fait trois. La main faisait de meme -- sept cartes
   *  se partagent la largeur, donc elles sont plus courtes que trois. A chaque
   *  rendu, `ajusterReserveMobile` mesurait les deux, redonnait sa hauteur au
   *  canvas, et `cadrer()` recalculait la camera : la table SAUTAIT, en pleine
   *  partie, sans que rien ne se soit passe sur le plateau.
   *
   *  Tout est donc calcule ici, une fois pour toutes, et plus rien n'est
   *  mesure a l'execution :
   *
   *    . la LARGEUR d'une carte est celle qui fait tenir SEPT cartes dans
   *      l'ecran -- la main pleine. En dessous elles n'y gagnent rien, au-dela
   *      elles se serrent, et dans les deux cas la hauteur du rail ne bouge
   *      pas d'un pixel ;
   *    . la hauteur du rail suit le rapport de la carte ;
   *    . le pupitre est la somme de ses trois lignes, chacune de hauteur
   *      fixe -- le message defile dans la sienne au lieu de la faire enfler ;
   *    . la reserve du bas est la somme des deux, et le canvas prend le reste.
   *
   *  Le canvas garde ainsi la meme taille du debut a la fin de la partie, et
   *  `cadrer()` n'est plus rappele que sur une vraie rotation d'ecran.
   */
  :root {
    --topbar-h: 46px;
    /* 16 de marges laterales, six intervalles de 5 : ce qui reste, divise par
       sept. */
    --carte-w: calc((100vw - 46px) / 7);
    --carte-h: calc(var(--carte-w) * 1610 / 1024);
    /*  QUATRE PIXELS NE SUFFISAIENT PAS.
     *
     *  La boite de la main valait la carte plus quatre pixels, dont quatre
     *  partaient dans son propre `padding-bottom` : il ne restait RIEN. La
     *  hauteur de la carte se deduit d'un calcul en `calc()` sur `100vw`, qui
     *  ne tombe jamais rond -- et le moindre dixieme arrondi vers le haut
     *  passait sous `overflow: hidden`, emportant le bas du cadre de la
     *  carte. C'est visible : la carte n'a plus de bordure basse.
     *
     *  Dix pixels au lieu de quatre. C'est de l'air qu'on prend au plateau,
     *  mais un cadre de carte tronque se lit comme un defaut d'affichage.
     */
    --main-h: calc(var(--carte-h) + 10px);
    /* Les trois lignes du pupitre, et ce qui les separe. */
    --info-h: 18px;
    --prompt-h: 44px;
    --fin-h: 42px;
    --module-h: calc(14px + var(--info-h) + 5px + var(--prompt-h) + 5px + var(--fin-h));
    /*  LE PUPITRE EST PASSE EN HAUT, ET LA RESERVE S'EST COUPEE EN DEUX.
     *
     *  Elle etait unique et tout en bas : le pupitre, la main, et leurs
     *  marges, empiles sous le plateau. Le pupitre est ce qu'on LIT -- l'etat
     *  du tour, la consigne -- et il se lisait a l'endroit ou le pouce vient
     *  de deposer une carte, c'est-a-dire sous sa propre main. Le regard
     *  faisait l'aller-retour d'un bout a l'autre de l'ecran.
     *
     *  En haut, il est dans le sens de la lecture : on prend la consigne,
     *  puis on descend vers la table et la main. Le bas de l'ecran ne garde
     *  que ce qu'on TOUCHE.
     *
     *  Deux reserves, donc, et le plateau entre les deux. La somme n'a pas
     *  bouge : le canvas garde exactement la meme hauteur qu'avant.
     */
    --reserve-haut: calc(var(--module-h) + 12px + env(safe-area-inset-top));
    --reserve-bas: calc(var(--main-h) + 12px + env(safe-area-inset-bottom));
  }

  /* ── La barre du haut se réduit à ses signes ── */
  .topbar { padding: 5px 10px; gap: 8px; }
  .brand-text, .brand-sub { display: none; }
  .brand-crest-wrap { width: 26px; height: 26px; }
  .header-actions { margin-left: auto; gap: 6px; }
  .cta-booster-txt { display: none; }

  /* ── La table : la bande haute, et rien d'autre ── */
  .table3d { height: calc(100dvh - var(--topbar-h)); min-height: 0; }
  /* Il commence sous le pupitre et s'arrete au-dessus de la main. La marge
     du haut est une VRAIE marge et non un decalage de position : le canvas
     est en flux dans `.table3d`, le pousser suffit. */
  .table3d > canvas {
    margin-top: var(--reserve-haut);
    height: calc(100% - var(--reserve-haut) - var(--reserve-bas));
  }
  /* Le décor de chambre est dessiné pour un cadre large : en portrait ses
     halos tombent a cote du plateau et ne font plus qu'assombrir. */
  .arena-runes, .arena-filigree, .arena-shaft { display: none; }
  .arena-vignette { background: radial-gradient(ellipse 90% 60% at 50% 34%,
    transparent 46%, rgba(0, 0, 0, 0.10) 78%, rgba(0, 0, 0, 0.34) 100%); }

  /* LA SORTIE SE MET A L'ABRI DU POUCE.
     Elle partageait le haut de l'ecran avec la roue : la roue a droite, la ou
     le pouce d'une main droite se pose, « Abandonner » a gauche, la ou l'on
     n'appuie pas par megarde. La roue est descendue dans la planche ; le coin
     droit est libre, mais l'abandon reste a gauche -- c'est du pouce qu'il
     fallait l'eloigner, pas de la roue. */
  /*  LE PORTRAIT DU PUPITRE N'A PLUS DE RAISON D'ETRE ICI.
   *
   *  Le pupitre est une grille de trois lignes de hauteur FIXE -- l'etat, le
   *  message, le bouton -- et le portrait n'a pas de case : il se rangeait
   *  dans une quatrieme ligne implicite, qui debordait sous la hauteur fixe.
   *  En bas de l'ecran, ce debordement passait derriere la main et personne
   *  ne le voyait ; en haut, il tombe en plein sur le plateau.
   *
   *  On ne lui fabrique pas une case pour autant. Il montrait UN visage,
   *  celui de la personne dont c'est le tour, parce qu'un encart de coin n'en
   *  tient pas deux. La planche montre maintenant LES DEUX, de part et
   *  d'autre de la Roue, avec la surbrillance sur celui qui joue -- c'est la
   *  meme information, mieux dite, et deja a l'ecran. Au large il reste : le
   *  pupitre y a la place, et un grand visage y vaut le detour.
   */
  .game-module .duel-portrait { display: none; }

  /*  LE LANCER D'OUVERTURE COMMENCE SOUS LE PUPITRE.
   *  Sa nappe part du haut de l'ecran (`top: 0`), qui appartient desormais au
   *  pupitre : son titre et son bouton se posaient dessus. On la fait
   *  commencer ou le plateau commence. */
  .des { top: var(--reserve-haut); }

  /*  ILS DESCENDENT AVEC LE PUPITRE QUI MONTE.
     *  Le haut de l'ecran est desormais au pupitre, sur toute la largeur : les
     *  deux jetons y seraient poses dessus. Ils passent au-dessus de la main,
     *  a gauche -- toujours du cote ou le pouce d'une main droite ne va pas
     *  se poser par megarde, ce qui etait la raison de leur place. */
  .wheel-bar {
    right: auto; left: 8px; top: auto;
    bottom: calc(var(--reserve-bas) + 8px);
  }
  .match-actions { gap: 4px; }
  /* « ABANDONNER » SE REPLIE SUR SON SIGNE.
     Vu de haut le plateau prend toute la largeur qu'on lui donne : sur un
     iPhone SE il ne reste plus de lave sur les cotes, et cent pixels de texte
     doré s'echouaient en travers de la planche adverse. Le mot devient un
     drapeau blanc dans une pastille ronde, posee dans son coin : le plateau
     prend tout le reste.
     `font-size: 0` efface le mot a l'oeil sans l'effacer du bouton : les
     lecteurs d'ecran l'annoncent toujours « Abandonner ». */
  .arena-ctrl {
    width: 34px; height: 34px; padding: 0;
    border-radius: 50%;
    display: grid; place-items: center;
    font-size: 0;
  }
  .arena-ctrl::before {
    content: '⚑';
    font-size: 16px; line-height: 1;
    font-family: var(--font-body), sans-serif; letter-spacing: 0;
  }

  /* ── LE PUPITRE, à plat au-dessus de la main ──
     Sur bureau c'est une colonne : étiquette, tour, message, bouton. Ici la
     place manque en hauteur et abonde en largeur, et le message -- celui qui
     dit ce qu'on attend du joueur -- prend toute la ligne du bas. C'est lui
     qu'on lit le plus, il ne doit jamais etre tronque.

     IL N'Y A PLUS DE CADRAN A CASER. Trois paragraphes tenaient ici pour
     justifier ou le poser : il volait 74 px de large a la ligne du message,
     on le sortait donc du pupitre pour l'aller poser dans un coin de l'ecran.
     La Roue est maintenant sertie au centre de la planche : elle ne dispute
     plus sa place a rien. */
    /* LE PUPITRE, EN TROIS LIGNES PLEINE LARGEUR.
     Le bouton et le tour se partageaient une ligne : le bouton, dimensionne
     sur son texte, prenait ce qu'il voulait et « À toi de jouer » se cassait
     en trois. Chacun sa ligne -- l'etat, le message, puis le geste -- et le
     bouton, seul en bas, devient une cible large sous le pouce. */
  /* LA MAIN PASSE AU-DESSUS DU PUPITRE.
     La main tenait le bas de l'ecran, sous le pouce, et le pupitre etait
     pose par-dessus. Mais on ne TAPOTE pas une carte : on la TIRE vers la
     table, et ce geste devait alors franchir tout le pupitre avant
     d'atteindre le plateau. Les cartes remontent donc contre la table -- le
     glisser part d'ou il arrive -- et le pupitre, qu'on lit et dont on ne
     touche qu'un bouton, prend le bas. */
  .game-module {
    left: 6px; right: 6px; bottom: auto;
    top: calc(6px + env(safe-area-inset-top));
    width: auto; padding: 7px 9px;
    height: var(--module-h);
    display: grid; gap: 5px;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--info-h) var(--prompt-h) var(--fin-h);
    grid-template-areas: "info" "msg" "fin";
  }
  /* UN SEUL CADRE. Le pupitre en portait deux -- le sien, plus un liseré
     interieur -- et l'etat du tour en portait un troisieme, imbrique dans les
     deux autres. Trois bordures pour trois lignes de texte. */
  .game-module::before { display: none; }
  .module-label, .module-rule { display: none; }
  /* L'ETAT TIENT VRAIMENT SUR UNE LIGNE.
     Deux colonnes seulement : le point prenait la premiere, et « Manche 1 »
     puis « A toi de jouer » se rangeaient l'une SOUS l'autre dans la seconde.
     Trente-sept pixels de haut pour cinq mots, alors que trois cent quatorze
     de large restaient vides a leur droite. Une colonne par element, et la
     ligne fait dix-huit pixels : dix-neuf rendus au plateau. */
  .game-module .turn-info {
    grid-area: info; padding: 0 2px; gap: 0 8px;
    grid-template-columns: auto auto minmax(0, 1fr);
    align-items: center;
    border: 0; background: transparent;
  }
  .game-module .turn-info b { font-size: 12px; }
  /* Le geste le plus repete de la partie merite la plus grande cible : on ne
     descend pas sous les quarante-quatre pixels d'un bout de doigt. */
  .module-end-turn {
    grid-area: fin; width: 100%; margin: 0;
    padding: 9px 12px; min-height: 42px;
  }
  /* LE MESSAGE DEFILE, IL NE POUSSE PLUS.
     C'est lui qui faisait enfler le pupitre : sa hauteur est desormais celle
     de sa ligne, et un texte plus long y defile au lieu de repousser le
     plateau. */
  .prompt {
    grid-area: msg; height: var(--prompt-h);
    flex-direction: row; flex-wrap: wrap; align-items: center;
    overflow-y: auto; overscroll-behavior: contain;
  }
  /* Le message ne doit pas pouvoir manger la table : au-dela de quatre lignes
     il defile dans son cadre plutot que de repousser le canvas. */
  .prompt .msg { font-size: 11px; line-height: 1.28; }
  /* L'APERCU NE SUIT PLUS LA SOURIS, IL SUIT LE CHOIX.
     Au doigt, le survol n'existe pas : l'apercu ne s'ouvrait jamais, et on
     jouait un rail de cartes de quarante-sept pixels a l'aveugle. Il est
     desormais appele par la SELECTION (renderMainColonne, main.js) et se pose
     au-dessus du pupitre, dans le coin droit -- la ou il ne cache ni le
     message ni la moitie du plateau ou l'on vise. */
  .mc-apercu {
    position: fixed; left: auto; top: auto; transform: none;
    right: 8px; bottom: calc(var(--reserve-bas) + 8px);
    width: 128px; max-width: 38vw;
    z-index: 46;
  }
  /* Le panneau de statistiques double le texte de la carte qu'il surmonte. */
  .mc-apercu-live { display: none; }
  .prompt > button { width: auto; margin-top: 0; padding: 8px 12px; }

  /* LES OPTIONS SE COUCHENT EN PASTILLES.
     Trois barres pleine largeur, plus leur intertitre et la ligne d'aide :
     deux cent trente pixels pour dire trois choses de cinq mots. Chacune
     tenait la largeur d'une ligne alors qu'elle n'a la longueur que d'une
     etiquette. Mises cote a cote, elles disent la meme chose en une rangee --
     et le plateau recupere tout le reste. */
  /* LE REGISTRE SE COUCHE.
     En colonne il prenait trois lignes pleine largeur pour dire trois choses
     de trois mots -- une centaine de pixels voles au plateau. Couche, il dit
     la meme chose en une rangee : les trois colonnes de chaque ligne se
     replient sur elles-memes, et c'est le libelle COURT qui s'affiche. */
  .registre { flex: 1 1 100%; flex-direction: row; gap: 4px; }
  /* LE REGISTRE EN DEUX ETAGES, PAS EN TROIS.
     Le nom au-dessus du compte, le mereau qui tient les deux sur sa gauche :
     la pastille fait la hauteur de deux petites lignes, et pas une de plus.
     C'est ce qui permet au pupitre de tenir sous la main sans manger la
     table. */
  .opt {
    flex: 1 1 0; min-width: 0;
    grid-template-columns: 16px minmax(0, 1fr);
    grid-template-areas: "rang nom" "rang val";
    gap: 0 5px; padding: 4px 6px 4px 5px;
    border-radius: 6px;
  }
  .opt::before { top: 3px; bottom: 3px; }
  .opt-rang { grid-area: rang; width: 16px; height: 16px; font-size: 8px; }
  .opt-nom { grid-area: nom; }
  .opt-nom b { font-size: 9px; letter-spacing: 0; line-height: 1.25; }
  .opt-nom b.opt-long { display: none; }
  .opt-nom b.opt-court { display: block; }
  .opt-valeur {
    grid-area: val; font-size: 9px; line-height: 1.2;
    overflow: hidden; text-overflow: ellipsis;
  }
  /* L'intertitre nomme ce que les pastilles montrent deja, et la ligne d'aide
     repete a chaque tour un conseil qui ne sert qu'au premier. */
  .prompt-kicker, .prompt .c-meta { display: none; }

  /*  LE CADRAN SUIT L'ECRAN.
   *  Il valait 74 px sur tout telephone, et 62 sur les courts : deux chiffres
   *  poses a la main, qui ne convenaient exactement a aucun des deux. Il se
   *  mesure maintenant a l'ecran lui-meme -- en largeur, puisque c'est elle
   *  qui manque en portrait, mais borne aussi par la hauteur pour qu'il ne
   *  devore pas le plateau sur un ecran court. Les bornes tiennent les
   *  extremes : jamais illisible, jamais envahissant.
   *
   *  Un iPhone SE lui donne 82 px, un 14 en donne 86, un Pro Max 95 -- la ou
   *  l'ancien reglage en donnait 62 au plus petit, le plus a l'etroit et donc
   *  celui qui en avait le plus besoin. */
  /* ── LA MAIN, un rail sous le pouce ──
     En colonne elle mangeait un quart de la largeur de l'écran. Couchée, elle
     défile du doigt et laisse toute la table visible. */
  /* LA MAIN TIENT ENTIEREMENT A L'ECRAN.
     Elle defilait : sept cartes de 71 font 533 px, l'ecran en fait 375, et
     les trois dernieres vivaient hors du champ -- on jouait une main dont on
     ne voyait pas la moitie. Les cartes se PARTAGENT donc la largeur : chacune
     prend une fraction egale de ce qui reste, quel qu'en soit le nombre. A
     sept sur 375 cela fait 45 px de large ; c'est petit, mais une carte de
     main n'a besoin que d'etre reconnue et touchee -- l'appui long l'ouvre en
     grand. La hauteur suit le rapport de la carte, et la barre d'accueil de
     l'iPhone est tenue a distance par la marge de securite. */
  .main-col {
    left: 0; right: 0; top: auto;
    /*  ELLE S'APPUIE SUR LE BAS DE L'ECRAN.
     *
     *  Elle s'appuyait sur le pupitre, qui etait sous elle ; le pupitre est
     *  monte, et il n'y a plus rien entre la main et le bord. Les six pixels
     *  d'air au-dessus de la barre d'accueil suffisent -- c'est la marge de
     *  securite qui tient le reste a distance.
     *
     *  ET ELLE A DE QUOI RESPIRER. `--main-h` valait la hauteur de la carte
     *  plus quatre pixels, et la boite rognait de justesse le bas des cartes
     *  a certaines largeurs. Voir `--main-h`.
     */
    bottom: calc(6px + env(safe-area-inset-bottom));
    width: auto; height: var(--main-h);
    flex-direction: row; align-items: flex-end; justify-content: center;
    gap: 5px;
    padding: 0 8px 4px;
    overflow: hidden;
    pointer-events: auto;
  }
  /*  COUCHE, LE RATELIER CHANGE DE SENS. Les logements sont maintenant des
      colonnes, et l'arete d'or passe du cote droit au bord SUPERIEUR : c'est
      par la que les cartes arrivent. */
  .main-col::before {
    inset: -6px 0 -8px;
    border-radius: 10px 10px 0 0;
    background:
      repeating-linear-gradient(90deg,
        rgba(255, 232, 180, .055) 0px,
        rgba(255, 232, 180, .055) 1px,
        rgba(0, 0, 0, .22) 2px,
        rgba(0, 0, 0, .22) 12.2%),
      linear-gradient(0deg, rgba(8, 6, 12, .95), rgba(24, 19, 30, .90) 62%, rgba(30, 24, 38, .60));
    box-shadow:
      inset 0 1px 0 rgba(201, 162, 70, .28),
      0 -6px 20px rgba(0, 0, 0, .55);
  }
  .main-col::after {
    top: -6px; bottom: auto; right: 0; left: 0; width: auto; height: 2px;
    background: linear-gradient(90deg,
      transparent, rgba(201, 162, 70, .5) 10%, rgba(201, 162, 70, .5) 90%, transparent);
  }
  /* Couchée, la carte se dimensionne par sa LARGEUR, pas par sa hauteur.
     `height: 100%` ne pouvait pas marcher : entre la carte et son image il y
     a l'enveloppe du vernis, qui n'a pas de hauteur propre -- le pourcentage
     ne se résolvait sur rien et l'image reprenait sa taille naturelle, cinq
     cents pixels de haut par-dessus la table. On donne donc la largeur, et la
     hauteur suit le rapport de la carte. */
  .mc-carte {
    flex: 1 1 0; min-width: 0; max-width: var(--carte-w);
    height: auto; aspect-ratio: 1024 / 1610;
    /* Le geste appartient au jeu, pas au navigateur : sans ca, un glisser vers
       la table est interprete comme un defilement et le depot n'a jamais lieu.
       La main ne defile plus (les sept cartes tiennent), rien n'est perdu. */
    touch-action: none;
  }
  .mc-carte > .vernis { width: 100%; height: auto; }
  .mc-carte img, .mc-carte > .vernis > img { width: 100%; height: auto; object-fit: contain; }
  /* Le chevauchement etait une reponse au manque de HAUTEUR, en colonne. Ici
     la contrainte est la largeur, et le partage s'en charge. */
  .main-col.serre { gap: 5px; }
  .main-col.serre .mc-carte { margin-bottom: 0; }
}

/* UN ÉCRAN COURT (iPhone SE : 667 de haut, contre 844 aux modèles récents).
 * Le budget vertical y est de deux cents pixels plus maigre : la main et le
 * pupitre se resserrent, sinon il ne reste plus assez de bande pour lire la
 * table. */
@media (max-width: 1100px) and (orientation: portrait) and (max-height: 720px) {
  /* Deux cents pixels de moins en hauteur : la carte et les trois lignes du
     pupitre se resserrent, mais toujours par des CONSTANTES -- rien ici n'est
     mesure a l'execution non plus. */
  :root {
    --carte-w: calc((100vw - 46px) / 7);
    --info-h: 16px;
    --prompt-h: 36px;
    --fin-h: 42px;
    --module-h: calc(12px + var(--info-h) + 5px + var(--prompt-h) + 5px + var(--fin-h));
  }
  /* Une seule colonne, comme au-dessus. Cette ligne declarait encore les trois
     colonnes de l'ancienne disposition -- dont celle du cadran, qui n'est plus
     la -- et ecrasait la grille en pleine largeur des que l'ecran etait court. */
  .game-module { padding: 6px 8px; gap: 5px; grid-template-columns: minmax(0, 1fr); }
  .game-module .turn-info { padding: 4px 7px; }
  .game-module .turn-info b { font-size: 11px; }
  .module-end-turn { padding: 9px; font-size: 9px; min-height: 42px; }
  .prompt .msg { font-size: 10px; max-height: 3.9em; }
  .turn-banner { top: 12%; min-width: 0; width: calc(100% - 32px); padding-inline: 12px; }
}

/* AUCUN SURVOL SUR UN DOIGT. L'aperçu de carte vivait entierement au survol :
 * sur un ecran tactile il ne s'ouvre jamais, ou pire il reste coince ouvert
 * apres un appui. La fiche complete, elle, s'ouvre par appui long (voir
 * `armerAppuiLong` dans main.js) -- c'est le geste tactile equivalent du clic
 * droit, et il montre plus que l'apercu. */
/* LE FANTOME DU GLISSER TACTILE.
 *
 * Le glisser-deposer HTML5 dessine tout seul l'image qu'on trimballe ; le
 * glisser au doigt, non -- il faut la fabriquer. Sans elle, on tirait une
 * carte invisible et rien ne disait ce qu'on tenait. */
.glisse-fantome {
  position: fixed; left: 0; top: 0; z-index: 90;
  width: 86px; pointer-events: none;
  filter: drop-shadow(0 14px 26px rgba(0, 0, 0, .8));
  opacity: .92;
}
.glisse-fantome img { display: block; width: 100%; border-radius: 6px; }

@media (hover: none), (pointer: coarse) {
  /* L'apercu etait coupe ici parce qu'il ne vivait qu'au survol : au doigt il
     ne s'ouvrait jamais, ou restait coince ouvert apres un appui. Il obeit
     desormais a la SELECTION (voir renderMainColonne, main.js), c'est-a-dire
     a un geste que le doigt sait faire -- et la classe `vu` reste le seul
     interrupteur. Le `display: none !important` d'avant l'eteignait meme
     quand le jeu venait de l'allumer. */
  /* Les commandes « + / - » d'une carte n'apparaissaient qu'AU SURVOL. Sans
     souris, retirer une carte du deck devenait impossible : on ne pouvait
     plus qu'en ajouter. Elles restent donc visibles en permanence. */
  .slot-actions { opacity: 1; pointer-events: auto; }
  /* LE GESTE DE JEU APPARTIENT AU JEU.
     `manipulation` ne supprime que le double-tap : le navigateur garde le
     defilement, et le PREMIER glisser vers la table lui revenait donc de
     droit. Il repondait par un `pointercancel`, le geste s'annulait avant
     d'arriver sur une tuile, et poser une carte au doigt etait tout
     simplement impossible. Pire, cette ligne ecrasait le `touch-action: none`
     que le bloc portrait pose sur `.mc-carte` : a specificite egale c'est la
     derniere qui gagne, et c'est celle-ci.
     Sur tout ce qui porte un geste -- la carte qu'on tire, la table ou on la
     depose, le rail qui les separe -- le navigateur ne prend plus rien.
     `none` supprime le double-tap AUSSI : on ne perd pas ce que
     `manipulation` apportait. */
  .table3d, .table3d > canvas, .main-col, .mc-carte { touch-action: none; }
  /* Ailleurs, on garde `manipulation` : ces commandes vivent dans des pages
     qui defilent, et leur retirer le defilement bloquerait la page. */
  .game-module, .tab, button { touch-action: manipulation; }
  /* L'appui long ouvre la fiche : il ne doit pas selectionner du texte ni
     declencher le menu de copie du systeme. */
  /* AUCUNE COMMANDE NE SE SURLIGNE.
     Un appui un peu long sur « Entrer dans l'Arene » et le mot sous le doigt
     partait en surbrillance bleue, avec la poignee de selection du systeme
     par-dessus le bouton. Un bouton est une cible, pas un texte a copier :
     tout ce sur quoi on APPUIE cesse d'etre selectionnable. Les zones de
     lecture -- le message du pupitre, le codex, les fiches -- gardent leur
     texte selectionnable, elles. */
  .mc-carte, .table3d > canvas,
  button, .tab, .opt, .home-card, .el-chip, .f-el, .f-rar {
    -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
  }
  /* Le retour au doigt remplace le survol : sans lui, un appui ne produit
     aucun signe et on appuie une seconde fois. Les `button` ont deja le leur
     (`button:active`, plus haut) : on ne sert ici que ce qui n'en est pas un. */
  .tab:active, .home-card:active, .mc-carte:active { transform: scale(.97); }
}


/* ══ LES ÉCRANS HORS PARTIE, SUR TÉLÉPHONE ═════════════════════════════════
 *
 * Sanctuaire, atelier, codex et ouverture de paquet étaient dessinés pour une
 * fenêtre large : titres de 43 px, cartes de 184, tuiles de statistiques de
 * 140 de large minimum, marges de 30. Rien ne débordait vraiment -- mais la
 * page d'accueil faisait quatre mille pixels de haut sur un écran de 667, et
 * chaque carte du panthéon s'affichait si grande que son propre texte
 * devenait illisible. Un écran de téléphone ne demande pas les mêmes objets
 * en plus étroit : il demande les mêmes objets PLUS PETITS et plus serrés.
 *
 * Une seule bascule, à 700 px, qui couvre tous les téléphones en portrait
 * (du SE à 375 aux grands modèles à 430) ; au-delà, la mise en page large
 * reprend telle quelle.
 */
@media (max-width: 700px) {
  /* Rien ne doit pouvoir faire glisser la page de côté : un seul élément qui
     déborde emmène toute la mise en page avec lui. */
  html, body { overflow-x: hidden; }
  main { padding: 10px 8px 24px; }

  /* La barre du bas : pictos + libelles, plus le cran de l'home indicator. */
  :root { --topbar-h: calc(64px + env(safe-area-inset-bottom, 0px)); }

  /* ── LA NAVIGATION DESCEND SOUS LE POUCE ──
     En haut, elle occupait la bande la plus difficile a atteindre d'un
     telephone tenu a une main, pour la chose qu'on touche le plus souvent.
     Elle passe donc en bas, comme dans a peu pres toutes les applications, et
     le corps de page se decale d'autant. Elle reste `.topbar` dans le code :
     c'est sa POSITION qui change, pas son role. */
  .topbar {
    position: fixed; top: auto; bottom: 0; left: 0; right: 0;
    padding: 5px 8px calc(5px + env(safe-area-inset-bottom));
    gap: 6px;
    border-bottom: 0; border-top: 1px solid var(--line-gold);
    box-shadow: 0 -4px 24px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(245, 185, 66, .15);
  }
  /* Elle est sortie du flux : sans cette reserve, la fin de chaque page
     passerait dessous. En partie `--topbar-h` vaut zero, la reserve aussi. */
  body { padding-bottom: var(--topbar-h); }
  .tabs { flex: 1 1 auto; justify-content: space-around; }
  .brand-text { display: none; }
  .brand-crest-wrap { width: 26px; height: 26px; }
  .tabs { gap: 0; min-width: 0; }
  .tab {
    flex: 1 1 0; min-width: 0;
    flex-direction: column; gap: 1px;
    padding: 3px 2px 2px;
  }
  .tab-text {
    display: block; font-size: 9px; font-weight: 700;
    letter-spacing: 0; line-height: 1.1;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tab[data-view="stats"] .tab-text { font-size: 0; }
  .tab[data-view="stats"] .tab-text::after { content: 'Stats'; font-size: 9px; }
  .tab-caret { display: none; }
  .tab-lien .tl-long { display: none; }
  .tab-lien .tl-court { display: inline; }
  .tab-glyph { font-size: 15px; }
  .tab[data-view="accueil"]::before,
  #nav-jouer-btn::before,
  .tab[data-view="atelier"]::before,
  .tab[data-view="collection"]::before,
  .tab[data-view="marche"]::before,
  .tab[data-view="forge"]::before,
  .tab[data-view="stats"]::before {
    font-size: 14px; line-height: 1; opacity: .9;
  }
  .tab[data-view="accueil"]::before { content: '⌂'; }
  #nav-jouer-btn::before { content: '⚔'; }
  .tab[data-view="atelier"]::before { content: '✎'; }
  .tab[data-view="collection"]::before { content: '▦'; }
  .tab[data-view="marche"]::before { content: '♦'; }
  .tab[data-view="forge"]::before { content: '⚒'; }
  .tab[data-view="stats"]::before { content: '▣'; }
  .header-actions { margin-left: 0; gap: 4px; flex: none; }
  .cta-booster { padding: 2px; }
  .cta-booster-img { width: 26px; height: 26px; }
  .booster-text { display: none; }
  .wallet { margin-right: 0; }
  .wallet-btn {
    height: 32px; max-width: 84px; padding: 0 8px;
    font-size: 10px; overflow: hidden; text-overflow: ellipsis;
  }
  .wallet-btn:not(.is-connecte) { font-size: 0; width: 32px; max-width: 32px; padding: 0; }
  .wallet-btn:not(.is-connecte)::after { content: '◎'; font-size: 16px; }
  .wallet-menu {
    top: auto; bottom: calc(100% + 8px); right: 0;
    max-width: min(280px, calc(100vw - 16px));
  }
  .tab-menu {
    top: auto; bottom: calc(100% + 8px); left: 0; right: auto;
    max-width: min(280px, calc(100vw - 16px));
  }
  .profil-chip { height: 32px; padding: 2px; margin-right: 0; }
  .pc-avatar { width: 28px; height: 28px; }
  .btn-parametres { width: 32px; height: 32px; padding: 0; }
  .btn-discord { width: 32px; height: 32px; }


  /* ── LE SANCTUAIRE TIENT DANS UN ÉCRAN ──
   *
   * Il faisait 2830 px de haut pour 621 disponibles : cinq écrans à faire
   * défiler avant d'avoir rien fait. Or presque tout ce qu'il contenait
   * existe ailleurs, et mieux : le panthéon des six légendaires est une
   * vitrine du Codex, les trois pavés du menu répètent mot pour mot les
   * onglets de la barre du bas, les statistiques du royaume ne servent aucun
   * geste, et le grimoire a son propre bouton dans cette même barre.
   *
   * Ce qui reste est ce qu'on vient y chercher : qui on est, où en est son
   * deck, et les deux portes -- l'arène et le paquet. Tout le reste est
   * masqué en portrait, pas supprimé : au large, la page complète revient.
   */
  /* Une page qui ne defile pas doit se tenir au MILIEU de l'ecran, pas se
     tasser en haut : sur un grand telephone, les trois blocs laissaient
     autrement trois cents pixels de vide sous eux. */
  /* Le vide restant revient a la banniere, pas aux marges. Centrer les trois
     blocs dans une colonne trop haute laissait cent pixels de vide en haut et
     autant en bas -- de l'espace paye et pas utilise. La banniere s'etire donc
     (`flex: 1`) et centre son contenu : sur un grand telephone, elle occupe
     tout le haut de l'ecran, et sur un petit elle se contente du strict
     necessaire. */
  .home {
    margin: 6px auto 0; gap: 6px;
    justify-content: flex-start;
    /* 28 = la marge haute de `.home` (8) plus le rembourrage de `main`
       (10 en haut, 8 en bas), et deux de rab. A 24 il restait deux pixels de
       defilement -- assez pour qu'une barre apparaisse. */
    min-height: calc(100dvh - var(--topbar-h) - 24px);
  }
  body:not(.play-on):not(.atelier-on) main { padding-bottom: 8px; }
  .home-hero { padding: 12px 12px 10px; gap: 8px; border-radius: 14px; }
  /* La roue se reduit, mais ses six noeuds et son coeur etaient dimensionnes
     en pixels fixes -- 32 px de pastille et un coeur en retrait de 26 -- donc
     ils se chevauchaient des que le disque retrecissait. Ils suivent
     maintenant sa taille. */
  /* Le cadran suit la meme regle, et ses six noeuds se mesurent en POURCENTAGE
     du disque : en pixels durs, ils se chevauchaient des qu'il retrecissait. */
  .hero-roue { width: clamp(64px, 11vh, 116px); height: clamp(64px, 11vh, 116px); }
  .hero-el-node { width: 26%; height: 26%; margin: -13% 0 0 -13%; border-width: 1px; }
  .hero-el-node i.el-ico { width: 55%; height: 55%; }
  .hero-roue-coeur { inset: 23%; }
  .hero-roue-coeur .hero-crest-img { width: 30%; height: auto; }
  .hero-crest-txt { display: none; }
  .hero-cadran-wrap { margin-top: -4px; }
  .hero-title { font-size: clamp(26px, 9vw, 34px); letter-spacing: .12em; }
  .home-kicker { font-size: 8px; letter-spacing: .14em; }
  /* L'accroche explique le jeu en quatre lignes -- quatre-vingts pixels pour
     un texte qu'on lit une fois. L'eventail montre les cartes et le titre les
     nomme ; sur un ecran de telephone, cela suffit a dire ce que c'est. */
  .home-tag { display: none; }
  .hero-text-col { align-items: center; text-align: center; }
  /* UNE SEULE PORTE ICI. « Créer un Deck » et « Explorer le Codex » sont
     exactement les deux onglets voisins de la barre du bas -- même geste,
     même destination, à trois centimètres de distance. Il ne reste que
     l'arène, qui est ce pour quoi on ouvre le jeu. */
  .hero-cta-group { width: 100%; flex-direction: column; gap: 6px; }
  .hero-cta-group [data-go="atelier"],
  .hero-cta-group [data-go="collection"] { display: none; }
  .btn-hero-cta { width: 100%; justify-content: center; padding: 11px 12px; font-size: 13px; }

  /* ── L'ÉVENTAIL, EN TÊTE ──
     C'est la plus belle chose de cette page, et la seule qui montre le jeu
     lui-meme : cinq cartes peintes, etalees. Il passe donc en PREMIER, avant
     le cadran et le titre -- une image d'accroche, comme au large, mais a
     l'echelle du telephone. Les decalages de l'eventail sont ecrits en pixels
     (±96, ±48) pour des cartes de 148 : reduits a 100, ils doivent suivre,
     sinon les cartes s'ecartent trop et sortent du cadre. */
  .home-hero { display: flex; flex-direction: column; flex: 1 1 auto; justify-content: center; }
  .hero-cards-stage { order: -1; }
  /* L'ÉVENTAIL PREND LA HAUTEUR QU'ON LUI LAISSE.
     Une taille fixe gaspille : sur un grand telephone il restait cent pixels
     de vide en haut et autant en bas, pendant que les cartes tenaient en
     timbre-poste. La hauteur se lit donc sur l'ecran (`22vh`), bornee des deux
     cotes -- jamais moins de 132 pour rester lisible, jamais plus de 240 pour
     ne pas avaler la page. Tout le reste en decoule : la carte, sa largeur par
     le rapport d'une carte, et l'ecartement en pourcentage de cette largeur.
     Une seule valeur a regler, et l'eventail garde ses proportions partout. */
  .hero-cards-fan {
    --fan-h: clamp(132px, 22vh, 240px);
    --carte-h: calc(var(--fan-h) * .62);
    --carte-w: calc(var(--carte-h) * .637);
    width: 100%; max-width: 320px; height: var(--fan-h); margin: 0 auto;
  }
  .stage-card { border-radius: 9px; }
  /*  LE MEME MECANISME QU'AILLEURS : on ne redefinit que les variables.
   *
   *  Ce bloc ecrivait des `transform` entiers, ce qui ecrasait le systeme de
   *  variables et cassait le survol. Pire, il decrivait un eventail de CINQ
   *  cartes avec la troisieme au centre, alors que le HTML en porte six et
   *  marquait la quatrieme : deux des regles ne visaient personne, et deux
   *  cartes gardaient leur position de bureau au milieu d'une mise en page de
   *  telephone. C'est de la que venait le desordre.
   *
   *  Les ecarts restent en pourcentage de la largeur de carte, pour que
   *  l'eventail garde ses proportions a toute taille d'ecran. */
  /* La legende compte les cartes ; le chiffre est deja au Codex. */
  .hero-cards-caption { display: none; }
  /* L'EVENTAIL EST UNE IMAGE, PAS UN MENU.
     Chaque carte ouvrait sa fiche : sur un ecran ou l'on touche tout, cinq
     cartes empilees au milieu de la page devenaient cinq pieges entre le
     titre et le bouton -- on visait l'un et on ouvrait l'autre. Elle ne
     repond plus au doigt ; le Codex est a un onglet de la. */
  .hero-cards-stage, .stage-card { pointer-events: none; }
  .card-element-badge { font-size: 8px; padding: 2px 6px; }

  /* Le panthéon, le menu, les statistiques, le grimoire de règles : tout cela
     double la barre du bas ou n'appelle aucun geste. */
  .home-showcase-section,
  .home-menu,
  .home-stats-wrap,
  .home-help,
  .home-roue,
  .home-elements,
  .home-edition,
  .home-footer { display: none; }

  /* ── L'AUTEL : LE GRIMOIRE, ET L'APPEL ──
     Le livre a gauche, l'invitation a droite -- la meme composition qu'au
     large, en deux colonnes serrees. C'est un OBJET qu'on ouvre : le montrer
     vaut mieux que le nommer, et le bouton seul ne donnait envie de rien. */
  .home-booster-altar {
    --grimoire: clamp(84px, 13vh, 148px);
    grid-template-columns: var(--grimoire) minmax(0, 1fr);
    gap: 10px; padding: 9px 11px; border-radius: 12px; align-items: center;
  }
  .altar-pack-preview { width: var(--grimoire); height: var(--grimoire); }
  /* Sous les cent pixels, « N disponibles » passait a la ligne et ses deux
     lignes retombaient sur le grimoire. */
  .altar-pack-count-tag { font-size: 8px; padding: 2px 6px; bottom: -3px; white-space: nowrap; }
  /* Le rappel des paquets offerts double le compteur pose sur le livre. */
  .altar-free-bonus { display: none; }
  .altar-stats-side .altar-mastery-head { display: none; }
  .altar-appel { align-items: stretch; text-align: left; gap: 4px; max-width: none; }
  .appel-kicker { font-size: 7.5px; letter-spacing: .14em; }
  .appel-titre { font-size: 18px; line-height: 1.05; }
  .appel-ligne { font-size: 10.5px; line-height: 1.3; }
  .altar-appel .altar-pack-actions { margin-top: 3px; }
  .altar-pack-actions { width: 100%; align-items: stretch; }
  .btn-open-pack-main { padding: 9px 10px; font-size: 12px; }
  .vitrine-raretes { gap: 4px; }
  .vr-item { gap: 2px; }
  .vr-nom { font-size: 6.5px; letter-spacing: 0; }
  .vr-chance { font-size: 0; }
  .vr-chance b { font-size: 8.5px; }

  /* Le pupitre du deck : une ligne, l'état du deck en cours. */
  .home-deck-pedestal { padding: 6px 11px; gap: 3px; border-radius: 12px; }
  .pedestal-title { font-size: 9px; letter-spacing: .06em; }
  .pedestal-score { font-size: 13px; }
  .pedestal-head { padding-bottom: 4px; }
  .pedestal-body { flex-direction: row; align-items: baseline; gap: 8px; flex-wrap: wrap; }
  .pedestal-deck-name { font-size: 13px; }
  .pedestal-deck-stats { font-size: 11px; }
  .deck-name { min-width: 0; font-size: 13px; }
  .req { font-size: 10px; padding: 3px 8px; }
  .score-label { display: none; }
  .deck-score b { font-size: 16px; }
  .deck-els-lbl { display: none; }
  .deck-els { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; gap: 4px; }
  .el-chip, .el-note, .req, .saved-deck { flex: 0 0 auto; }
  .el-chip { font-size: 10px; padding: 3px 7px; }
  .el-note { font-size: 10px; flex: 1 1 100%; }
  .fan-peek { display: none; }
  .saved-decks-lbl { display: none; }
  .saved-deck { padding: 3px 8px 3px 10px; }
  .saved-deck .sd-name { font-size: 11px; }
  .filter-title { font-size: 10px; }
  .search-box input { padding-top: 7px; padding-bottom: 7px; font-size: 16px; }
  .f-el, .f-rar, .seg button { width: auto; flex: 0 0 auto; padding: 6px 10px; font-size: 12px; }
  .f-el i { width: 14px; height: 14px; }
  .f-rar small { display: none; }
  .filter-group { gap: 4px; }
  .filter-lbl { font-size: 9px; }
  .seed-adv { display: none; }

  /* La galerie : trois cartes de front. A une seule colonne on ne feuilletait
     plus, on défilait carte par carte -- mille trois cent soixante-quatorze
     fois. */
  .gallery {
    gap: 10px 8px; padding: 10px 8px 28px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .gal-more { font-size: 12px; padding: 0 10px 20px; }

  /* LA FICHE D'UNE CARTE, DANS L'ATELIER.
     Elle empilait deux rembourrages de 24 -- celui du voile et celui du cadre --
     puis posait une carte plafonnee a 94vw dans l'espace restant. A 375 px de
     large, 94vw font 352 alors qu'il n'en reste que 279 : la carte, les deux
     boutons et la mention du nombre d'exemplaires sortaient par la droite. On
     borne la carte a la place REELLEMENT disponible, et la barre d'actions
     passe a la ligne au lieu de pousser. */
  .card-zoom { padding: 10px; overflow-y: auto; place-items: center; }
  .zoom-wrap { padding: 10px; gap: 9px; border-radius: 12px; max-width: 100%; }
  .zoom-print { max-width: 100%; max-height: 64vh; }
  .zoom-bar { flex-wrap: wrap; justify-content: center; gap: 6px; }
  .zoom-bar button { padding: 8px 12px; font-size: 12px; }
  .zoom-bar .hint { font-size: 11px; flex: 1 1 100%; text-align: center; }
  .zoom-force { font-size: 11px; }
  /* UNE CARTE, UNE INFORMATION.
     Sur une vignette de 114 px on posait trois choses : sa puissance, un
     bouton « + », un bouton « - ». Elles couvraient le tiers de
     l'illustration -- c'est-a-dire la seule chose qui permet de reconnaitre
     une carte d'un coup d'oeil. Il ne reste que le COMPTE : combien
     d'exemplaires sont dans le deck. Toucher la carte l'ajoute ; on la retire
     depuis la feuille du deck, ou elles sont toutes cote a cote. Sa puissance
     et sa rarete sont dans sa fiche, qu'un appui long ouvre. */
  .slot-actions { display: none; }
  .slot-qty {
    top: -4px; right: -4px; min-width: 22px; height: 21px;
    font-size: 11px; padding: 0 6px;
  }

  /* ── L'OUVERTURE D'UN PAQUET ──
     La rangée de révélation était bornée à « deux cartes de 184 plus un écart
     de 24 » : 392 px, soit plus que l'écran d'un SE. Les cartes ne peuvent pas
     garder une taille fixe ici -- on leur donne une FRACTION de la largeur
     disponible, et le rapport de la carte fait le reste. Le vol depuis le
     paquet mesure les boîtes au moment du lancer : il suit sans rien savoir. */
  /* LA CHAMBRE DOIT POUVOIR DEFILER.
     La fenetre etait centree et coupee net (`place-items: center` sur un
     conteneur en `overflow: hidden`) : sept cartes en trois rangees font
     754 px de haut, l'ecran en fait 667, et les 87 qui depassaient etaient
     retranches en haut ET en bas -- l'en-tete et la derniere rangee devenaient
     inatteignables. On accroche donc le contenu en haut et on le laisse
     defiler ; le decor et la croix de fermeture, eux, restent fixes. */
  .booster-modal { overflow-y: auto; overflow-x: hidden; place-items: start center; }
  /* Le decor ne doit rien ajouter a la hauteur defilante. Le faisceau
     d'ambiance est un `inset: -50%` absolu : 1334 px de haut, qui creaient a
     eux seuls 334 px de vide sous les boutons -- un ecran de defilement pour
     regarder du noir. Fixe, il eclaire sans compter. */
  .booster-backdrop, .ambient-rarity-beam, .booster-particles { position: fixed; }
  .booster-stage { padding: 46px 10px 16px; min-height: auto; justify-content: flex-start; }
  .booster-top-controls { position: fixed; top: 8px; right: 8px; gap: 6px; }
  .booster-ctrl-btn { width: 34px; height: 34px; font-size: 14px; }
  .pack-wrapper { gap: 16px; }
  /* LES QUATORZE CARTES TIENNENT DANS UN SEUL ECRAN.
     Le paquet est passe de sept a quatorze : a quatre de front il fallait
     quatre rangees, soit 704 px de cartes seules -- on defilait au moment
     precis ou l'on veut voir son tirage d'un coup d'oeil, et les dernieres
     cartes restaient sous le pli. A CINQ de front, quatorze tiennent en trois
     rangees (5 + 5 + 4, la derniere se centre d'elle-meme) : environ 350 px
     de cartes, qui laissent la place a l'en-tete et aux boutons. */
  .cards-reveal-area { gap: 6px; padding: 6px 8px 56px; }
  .reveal-title { font-size: 15px; margin-top: 2px; }
  .reveal-kicker { font-size: 8px; letter-spacing: .18em; }
  .reveal-hint { font-size: 10px; margin-top: 3px; }
  .reveal-header::after { width: 84px; margin-top: 5px; }
  .reveal-cards-row { max-width: none; gap: 6px; padding: 0 2px; }
  .reveal-card-slot {
    width: calc((100% - 24px) / 5);
    height: auto; aspect-ratio: 320 / 503;
    border-radius: 7px;
  }
  /* LES QUATRE EQUERRES DES COINS S'EN VONT.
     Dessinees pour une chambre au large, elles tombent au telephone sur le
     bord des cartes et sur l'en-tete : quatre angles droits qui n'encadrent
     plus rien et qui contredisent les coins arrondis de tout le reste. */
  .chamber-filigree { display: none; }
  /* Le bandeau « NOUVELLE ! » etait dimensionne pour une carte de 184 : sur
     une de 112, il la barrait en entier. */
  .badge-new-card { top: -6px; font-size: 6.5px; letter-spacing: .06em; padding: 2px 6px; border-width: 1px; white-space: nowrap; }
  /* Les deux actions finales, l'une sous l'autre : cote a cote elles se
     partageaient 355 px et « Ouvrir un autre booster (2) » se cassait en
     quatre lignes. */
  .reveal-actions { flex-direction: column; gap: 6px; width: 100%; margin-top: 4px; }
  .reveal-actions > * { width: 100%; justify-content: center; text-align: center; }
  .btn-open-another, .btn-finish-pack { padding: 10px 12px; font-size: 12px; white-space: nowrap; }
  .btn-reveal-all { font-size: 12px; }
  /* LE BANDEAU DE CHANCE, EN UNE LIGNE.
     Dessine pour 840 px, il se repliait en pile a 355 et prenait 273 px de
     haut -- a lui seul, il remettait du defilement sous les cartes. Il reste
     donc une ligne : l'appreciation a gauche, la note et les etoiles a droite.
     La phrase d'explication, elle, part : le titre et la note la disent deja. */
  .pull-score-banner {
    width: 100%; padding: 7px 10px; gap: 8px;
    flex-wrap: nowrap; align-items: center;
  }
  .pull-score-left { min-width: 0; }
  .pull-score-kicker { font-size: 8px; letter-spacing: .16em; }
  .pull-rating-title { font-size: 14px; }
  .pull-rating-desc { display: none; }
  .pull-score-right { gap: 8px; flex: 0 0 auto; }
  .pull-score-badge { padding: 3px 8px; border-radius: 7px; }
  .score-val { font-size: 17px; }
  .score-lbl { font-size: 6.5px; letter-spacing: .1em; }
  .pull-score-stars { font-size: 13px; letter-spacing: 1px; }
}
/*  L'ATELIER EN FEUILLES : telephone, et tablette debout (27/09/2026). */
@media (max-width: 700px), (max-width: 1100px) and (orientation: portrait) {

  /* ── L'ATELIER ET LE CODEX ──
     La colonne de filtres passe au-dessus de la galerie : à 375 px, côte à
     côte, aucune des deux n'est lisible. Et une fois couchée elle ne peut
     plus être une LISTE -- chaque groupe devient une bande qu'on parcourt
     du doigt. */
  /* ── L'ATELIER SUR TÉLÉPHONE : LA GRILLE, ET RIEN D'AUTRE ──
     Le deck en haut (349 px), les filtres en dessous (156) et la barre de
     boutons ne laissaient qu'un tiers d'ecran aux cartes -- la seule chose
     qu'on est venu voir. Ces deux blocs deviennent des feuilles qui montent
     du bas quand on les demande. Ils gardent exactement le meme contenu :
     c'est leur PLACE qui change, pas leur nature. */
  #view-atelier.en-feuilles .atelier { grid-template-rows: minmax(0, 1fr); }

  /* Une seule feuille : le rail. Les filtres vivent DEDANS, ce n'est plus
     une deuxieme feuille independante -- sinon elle se leviait dans un
     parent encore translate hors ecran. */
  #view-atelier.en-feuilles .deck-rail {
    position: fixed; left: 0; right: 0; bottom: var(--topbar-h); z-index: 72;
    max-height: 72vh; overflow-y: auto; overflow-x: hidden;
    border: 1px solid var(--line-gold); border-bottom: 0;
    border-radius: 14px 14px 0 0;
    padding: 12px 12px 16px;
    box-shadow: 0 -18px 44px rgba(0, 0, 0, .7);
    transform: translateY(101%);
    transition: transform .26s cubic-bezier(.16, 1, .3, 1);
    visibility: hidden;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  #view-atelier.en-feuilles .deck-rail::before {
    content: ''; display: block; width: 38px; height: 4px;
    margin: 0 auto 10px; border-radius: 2px;
    background: rgba(201, 162, 70, .45);
  }
  #view-atelier.en-feuilles .filters {
    position: static;
    transform: none;
    visibility: visible;
    max-height: none;
    overflow: visible;
    box-shadow: none;
    border: 0;
    padding: 0;
    border-radius: 0;
  }
  #view-atelier.en-feuilles.feuille-deck .deck-rail,
  #view-atelier.en-feuilles.feuille-filtres .deck-rail {
    transform: none;
    visibility: visible;
  }
  #view-atelier.en-feuilles.feuille-filtres .dk-haut { display: none; }
  #view-atelier.en-feuilles.feuille-deck .filters { display: none; }

  .voile-feuille {
    position: fixed; left: 0; right: 0; top: 0; bottom: var(--topbar-h); z-index: 70;
    background: rgba(4, 3, 6, .62);
    backdrop-filter: blur(2px);
  }

  /* ── LA BARRE BASSE ──
     Trois gestes, pas un de plus : voir son deck, filtrer, jouer. */
  /* ── LA BARRE DE L'ATELIER PASSE EN HAUT ──
     Elle est dans le FLUX, premiere rangee de la grille : elle n'a plus besoin
     d'etre fixee, et la galerie n'a plus besoin de lui reserver de la place
     par un rembourrage qui aurait a suivre sa hauteur. */
  #view-atelier.en-feuilles .atelier {
    grid-template-rows: auto minmax(0, 1fr);
  }
  #view-atelier.en-feuilles .barre-atelier { grid-row: 1; }
  #view-atelier.en-feuilles .atelier-body { grid-row: 2; }
  .barre-atelier {
    position: relative; z-index: 74;
    display: grid; grid-template-columns: 1fr 1fr 1.1fr; gap: 6px;
    padding: 7px 8px;
    background: linear-gradient(180deg, rgba(12, 9, 14, .96), rgba(6, 4, 8, .99));
    border-bottom: 1px solid rgba(201, 162, 70, .32);
  }
  .ba-btn {
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    padding: 6px 4px; border-radius: 8px;
    border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
    color: var(--ink-dim); font-size: 10px; font-weight: 700;
    box-shadow: none;
  }
  .ba-ico { font-size: 15px; line-height: 1; color: var(--accent); }
  .ba-btn b { color: var(--ink-bright); font-family: var(--font-num); }
  .barre-atelier.avec-auto { grid-template-columns: 1fr 1.15fr 1fr 1.1fr; }
  .ba-auto { border-color: rgba(201, 162, 70, .55); color: #f3dc9a; background: rgba(201, 162, 70, .12); }
  .ba-auto[hidden] { display: none; }
  .ba-jouer {
    background: var(--gold-grad); color: #1a1202;
    border-color: #ffe082; font-weight: 850;
  }
  .ba-jouer .ba-ico { color: #1a1202; }
  .ba-jouer:disabled { background: #181b23; color: var(--ink-faint); border-color: var(--line); }
  .ba-jouer:disabled .ba-ico { color: var(--ink-faint); }

  /* Dans la feuille du deck, l'eventail se deplie en grille : on vient y
     chercher une carte a retirer, pas admirer un eventail. */
  #view-atelier.en-feuilles .deck-meta { gap: 8px; }
  #view-atelier.en-feuilles .deck-name-group { flex: 1 1 100%; padding: 2px 6px; }
  #view-atelier.en-feuilles .reqs { flex: 1 1 100%; flex-wrap: wrap; gap: 4px; }
  #view-atelier.en-feuilles .deck-score { flex: 0 0 auto; flex-direction: row; align-items: baseline; gap: 4px; padding: 3px 8px; }
  #view-atelier.en-feuilles .deck-els-wrap { flex: 1 1 100%; min-width: 0; flex-wrap: wrap; }
  #view-atelier.en-feuilles .deck-actions { flex: 1 1 100%; margin-left: 0; gap: 6px; flex-wrap: wrap; }
  #view-atelier.en-feuilles .deck-actions button { flex: 1 1 auto; padding: 9px 8px; font-size: 11px; justify-content: center; }
  /* Les pictos n'ont une taille que dans le media large : sans ca, le SVG
     de « Vider » s'etale a 300 px et mange la feuille. */
  #view-atelier.en-feuilles .dk-ico {
    width: 16px; height: 16px; flex: none;
    fill: none; stroke: #e8c25a;
    stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  }
  #view-atelier.en-feuilles #deck-clear .dk-ico { stroke: #f0a39b; }
  #view-atelier.en-feuilles .dk-outils {
    flex-direction: row; flex-wrap: wrap; align-items: center;
    min-width: 0; gap: 6px;
  }
  #view-atelier.en-feuilles .dk-outils-titre { flex: 1 1 100%; margin: 0; }
  #view-atelier.en-feuilles .dk-outils .dk-outil,
  #view-atelier.en-feuilles .dk-outils .auto-group button {
    display: inline-flex; align-items: center; gap: 6px;
    min-height: 40px; height: auto;
  }
  /* Jouer vit dans la barre basse : le repeter ici ferait deux boutons pour
     un seul geste, dont un que l'on ne voit qu'apres avoir ouvert la feuille. */
  #view-atelier.en-feuilles .deck-actions .play-btn,
  #view-atelier.en-feuilles .play-why { display: none; }
  #view-atelier.en-feuilles .fan {
    --fan-card-w: 62px;
    display: grid; grid-template-columns: repeat(5, 1fr);
    gap: 5px; height: auto; padding: 0; margin-top: 2px;
    overflow: visible;
  }
  #view-atelier.en-feuilles .fan.is-idle { display: flex; height: 54px; font-size: 12px; }
  #view-atelier.en-feuilles .fan-card {
    width: 100%; height: auto; aspect-ratio: 1024 / 1610;
    margin: 0 !important; border-radius: 5px;
  }
  #view-atelier.en-feuilles .saved-decks-bar { flex: 1 1 100%; gap: 6px; margin-top: 4px; }

  /* ── LA FEUILLE DES FILTRES ── */
  #view-atelier.en-feuilles .filters {
    flex-direction: column; gap: 9px; max-height: 74vh;
    border-right: none;
  }
  #view-atelier.en-feuilles .f-els,
  #view-atelier.en-feuilles .f-rars,
  #view-atelier.en-feuilles .seg,
  #view-atelier.en-feuilles .filter-toggles {
    flex-direction: row; flex-wrap: wrap; gap: 5px;
  }

  /* Plus rien ne flotte au-dessus de la galerie : elle garde son rembourrage
     ordinaire. */
  #view-atelier.en-feuilles .gallery { padding-bottom: 20px; }

  /* AU CODEX, ON NE CONSTRUIT PAS DE DECK. L'onglet Collection reutilise le
     meme ecran, mais sans deck : « Deck » et « Jouer » n'y mènent nulle part.
     Il ne reste que le filtre, en pleine largeur. */
  body.collection-mode .barre-atelier { grid-template-columns: 1fr; }
  body.collection-mode .ba-deck,
  body.collection-mode .ba-jouer { display: none; }
}

/* UN ÉCRAN COURT (568 de haut au lieu de 667 : SE de première génération, ou
 * un navigateur qui garde sa barre d'adresse). L'accueil y depassait de 41 px,
 * et 41 px de defilement suffisent a casser la promesse d'une page qui tient
 * d'un coup d'oeil. On resserre la roue, l'accroche, et on retire le rappel
 * des paquets offerts -- le bouton principal les annonce deja. */
@media (max-width: 700px) and (max-height: 640px) {
  /* Entre le cadran et l'eventail, c'est l'eventail qui reste : il montre le
     jeu, le cadran ne fait que le symboliser -- et la Roue se lit en vrai a
     chaque partie. Les tailles, elles, n'ont plus a etre figees ici : les
     bornes basses des `clamp` s'en chargent toutes seules. */
  .home-hero { padding: 10px 10px; gap: 6px; }
  .hero-cadran-wrap { display: none; }
  .appel-ligne { display: none; }
  .home-tag { font-size: 11px; line-height: 1.3; margin: 4px 0 8px; }
  .altar-free-bonus { display: none; }
  .home-booster-altar { padding: 8px 10px; }
  .home-deck-pedestal { padding: 8px 10px; gap: 4px; }
}

/* Les très petits écrans. Le seuil est a 340, pas a 380 : l'iPhone SE fait
   375 de large et doit rester a trois vignettes de front -- une carte de 113
   s'y reconnait tres bien. En dessous de 340 on retombe a deux. */
@media (max-width: 340px) {
  .showcase-grid { grid-template-columns: repeat(2, 1fr); }
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero-title { font-size: clamp(26px, 9.5vw, 34px); }
  .reveal-cards-row { gap: 4px; }
  .reveal-card-slot { width: calc((100% - 16px) / 5); }
}

/* ══ LE SALON EN LIGNE ══════════════════════════════════════════════════════
 * Un code, et rien d'autre : pas de compte, pas de liste de parties. On ouvre
 * un salon, on dicte quatre lettres, l'autre les tape. */
.salon-join { display: flex; gap: 6px; }
.salon-join input {
  width: 108px; text-align: center;
  font-family: var(--font-num); font-size: 17px; font-weight: 800;
  letter-spacing: .22em; text-transform: uppercase;
}
.salon-etat { display: flex; flex-direction: column; align-items: center; gap: 12px; }
/* Le code se lit a voix haute : il doit etre gros, espace, et sans rien autour. */
.salon-code-vitre {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 26px; border-radius: 6px;
  border: 1px solid rgba(201, 162, 70, .45);
  background: rgba(245, 185, 66, .08);
}
.salon-code-lbl {
  font-size: 8px; font-weight: 800; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-faint);
}
.salon-code-vitre b {
  font-family: var(--font-num); font-size: 30px; font-weight: 800;
  letter-spacing: .3em; color: var(--accent); text-indent: .3em;
  text-shadow: 0 0 18px rgba(245, 185, 66, .35);
}
.salon-boutons { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.salon-message { font-size: 12px; color: var(--ink-dim); text-align: center; max-width: 320px; }
.salon-message.est-erreur { color: #fca5a5; }

@media (max-width: 700px) {
  .salon-join { width: 100%; }
  .salon-join input { flex: 1 1 auto; width: auto; font-size: 15px; }
  .salon-code-vitre b { font-size: 24px; }
  .salon-boutons { width: 100%; flex-direction: column; }
  .salon-boutons > * { width: 100%; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   LE MULTIJOUEUR — LE SALON DEVENU UN LIEU
   ═══════════════════════════════════════════════════════════════════════════
   Le duel en ligne tenait dans un encart sous « l'arène est close » : quatre
   lettres à dicter, deux étiquettes, et rien à regarder pendant qu'on attend.
   Il a maintenant son onglet et sa vue — deux fiches face à face, les decks
   lisibles des deux côtés, et de quoi se parler.

   Rien n'est inventé ici : les cartes reprennent le verre sombre et le liseré
   d'or de `.home-card`, les paliers reprennent les couleurs du pupitre de
   duel, et l'or reste la seule couleur qui appelle l'action. */

/* ── L'onglet, et sa pastille ────────────────────────────────────────────── */
.tab { position: relative; }
.tab-pastille {
  position: absolute; top: 2px; right: 2px;
  min-width: 15px; height: 15px; padding: 0 4px;
  border-radius: 999px;
  background: var(--bad); color: #1a0505;
  font-size: 9px; font-weight: 900; line-height: 15px; text-align: center;
  box-shadow: 0 0 0 2px var(--bg-2), 0 0 10px var(--bad-glow);
  pointer-events: none;
}

.no-match-multi { margin-top: 10px; }

/* ── La vue ──────────────────────────────────────────────────────────────── */
.multi {
  max-width: 1000px; margin: 0 auto; padding: 8px 0 32px;
  display: flex; flex-direction: column; gap: 22px;
}
.multi-head { text-align: center; display: flex; flex-direction: column; gap: 6px; }
.multi-kicker {
  font-size: 10px; font-weight: 800; letter-spacing: .26em;
  color: var(--accent); text-transform: uppercase;
}
.multi-title {
  font-family: var(--font-ornate), var(--font-title), serif;
  font-size: clamp(26px, 4vw, 38px); font-weight: 700; margin: 0;
  background: var(--gold-grad); -webkit-background-clip: text;
  background-clip: text; color: transparent;
}
.multi-tag {
  margin: 0 auto; max-width: 52ch;
  font-size: 13px; line-height: 1.6; color: var(--ink-dim);
}

.multi-profil { display: flex; flex-direction: column; gap: 8px; align-items: center; }
.multi-profil-lbl {
  font-size: 9px; font-weight: 800; letter-spacing: .22em;
  text-transform: uppercase; color: var(--ink-faint);
}
.multi-profil .dl-carte { width: min(460px, 100%); }

/* ── La porte : ouvrir, ou rejoindre ─────────────────────────────────────── */
.salon-porte {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; align-items: stretch;
}
.porte-carte {
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  text-align: center; padding: 24px 22px; border-radius: 16px;
  background: linear-gradient(165deg, rgba(22, 30, 48, .88) 0%, rgba(12, 16, 26, .95) 100%);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .4);
  transition: border-color .28s ease, box-shadow .28s ease;
}
.porte-carte:hover { border-color: rgba(245, 185, 66, .45); }
.porte-hote {
  border-color: rgba(245, 185, 66, .45);
  background: linear-gradient(165deg, rgba(46, 34, 10, .82) 0%, rgba(16, 13, 8, .95) 100%);
}
.porte-ico { font-size: 24px; color: var(--accent); line-height: 1; }
.porte-carte h3 {
  margin: 0; font-family: var(--font-title), serif;
  font-size: 17px; font-weight: 800; letter-spacing: .03em; color: var(--ink-bright);
}
.porte-carte p { margin: 0; font-size: 12px; line-height: 1.55; color: var(--ink-dim); max-width: 30ch; }
.porte-carte button { margin-top: 4px; }
/* Le « ou » n'est pas un choix par défaut : c'est un aiguillage. Un simple
   filet vertical suffit à le dire, sans le peindre. */
.porte-ou {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; color: var(--ink-faint);
  font-size: 10px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase;
}
.porte-ou::before, .porte-ou::after {
  content: ''; flex: 1 1 18px; width: 1px; min-height: 18px;
  background: linear-gradient(180deg, transparent, var(--line), transparent);
}

/* ── Dans le salon ───────────────────────────────────────────────────────── */
.salon-etat { display: flex; flex-direction: column; align-items: center; gap: 18px; }

.salon-code-vitre { position: relative; }
.salon-copier {
  position: absolute; top: 50%; right: -6px; transform: translate(100%, -50%);
  padding: 5px 10px; border-radius: 6px;
  border: 1px solid var(--line-gold); background: rgba(255, 255, 255, .04);
  color: var(--ink-dim); font-size: 10px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; cursor: pointer;
  transition: color .2s ease, border-color .2s ease;
}
.salon-copier:hover { color: var(--accent); border-color: rgba(245, 185, 66, .6); }

.salon-duo {
  width: 100%;
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 14px;
  /* Étirées, pas centrées : deux fiches de hauteurs différentes de part et
     d'autre du « VS » se liraient comme un déséquilibre. Le bloc du deck se
     cale en bas de chacune (`margin-top: auto`), donc les deux lignes de
     points s'alignent — c'est ce qu'on vient comparer. */
  align-items: stretch;
}
/*  LES DEUX FICHES FONT LA MEME HAUTEUR.
 *
 *  `align-items: stretch` etirait bien les deux CASES de la grille -- mais
 *  pas les fiches qui sont dedans. Un bloc ordinaire prend la hauteur de son
 *  contenu, et ma fiche en a davantage : la jauge d'experience, puis la
 *  rangee « Modifier le profil / Modifier le deck » que l'autre n'a pas. La
 *  mienne depassait donc de pres de cent pixels, et le duo se lisait comme un
 *  desequilibre alors que les deux decks pesent le meme poids.
 *
 *  La case devient une colonne, et la fiche y prend toute la place. Le bloc
 *  du deck, qui porte deja `margin-top: auto`, tombe alors au bas de chacune
 *  -- c'est la ligne des points, celle qu'on vient comparer. */
.salon-duo > .duelliste { display: flex; flex-direction: column; min-width: 0; }
.salon-duo > .duelliste > .dl-carte { flex: 1 1 auto; min-width: 0; }
.salon-versus {
  display: grid; place-items: center;
  font-family: var(--font-ornate), var(--font-title), serif;
  font-size: 20px; font-weight: 700; letter-spacing: .1em;
  color: var(--accent); text-shadow: 0 0 18px var(--gold-glow);
}
.salon-versus span {
  display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: 50%; border: 1px solid var(--line-gold);
  background: radial-gradient(circle, rgba(245, 185, 66, .12), transparent 70%);
}

/* ── La fiche de duelliste ───────────────────────────────────────────────── */
.dl-carte {
  display: flex; flex-direction: column; gap: 10px;
  padding: 18px; border-radius: 14px;
  background: linear-gradient(165deg, rgba(22, 30, 48, .88) 0%, rgba(12, 16, 26, .95) 100%);
  border: 1px solid var(--line);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .38);
}
.dl-carte.est-moi { border-color: rgba(245, 185, 66, .42); }
/* La place vide n'est pas une erreur : elle attend. Le trait interrompu le dit
   mieux qu'une phrase, et le halo tourne pour montrer que rien n'est bloqué. */
.dl-carte.attend {
  align-items: center; justify-content: center; text-align: center;
  border-style: dashed; min-height: 176px; gap: 6px;
  background: rgba(255, 255, 255, .015);
}
.dl-vide-ico { font-size: 26px; color: var(--ink-faint); animation: dl-tourne 3.6s linear infinite; }
@keyframes dl-tourne { to { transform: rotate(360deg); } }
.dl-vide-t {
  font-family: var(--font-title), serif; font-size: 14px;
  font-weight: 800; color: var(--ink-dim);
}
.dl-vide-d { font-size: 11px; line-height: 1.5; color: var(--ink-faint); max-width: 28ch; }

.dl-tete { display: flex; align-items: center; gap: 12px; min-width: 0; }
.dl-avatar {
  position: relative; flex: 0 0 auto;
  width: 58px; height: 58px; border-radius: 50%;
  display: grid; place-items: center; overflow: visible;
  border: 2px solid var(--line-gold);
  background: radial-gradient(circle at 30% 25%, rgba(245, 185, 66, .18), rgba(12, 16, 26, .9));
  box-shadow: 0 0 18px rgba(0, 0, 0, .5);
}
.dl-avatar img {
  width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block;
}
.dl-initiales {
  font-family: var(--font-title), serif; font-size: 20px; font-weight: 800;
  letter-spacing: .04em; color: var(--accent);
}
/* L'étoile de l'hôte : c'est lui qui lance, il faut savoir lequel c'est. */
.dl-couronne {
  position: absolute; top: -5px; right: -5px;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--gold-grad); color: #1a1202;
  font-size: 11px; line-height: 1;
  box-shadow: 0 0 12px var(--gold-glow);
}

.dl-ident { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 3px; }
.dl-nom {
  font-family: var(--font-title), serif; font-size: 17px; font-weight: 800;
  color: var(--ink-bright); letter-spacing: .02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dl-rang { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.dl-niveau {
  padding: 2px 8px; border-radius: 999px;
  border: 1px solid rgba(245, 185, 66, .4); background: rgba(245, 185, 66, .1);
  font-family: var(--font-num), Georgia, serif;
  font-size: 11px; font-weight: 800; color: var(--accent);
}
.dl-titre {
  font-size: 10px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint);
}
.dl-jauge {
  margin-top: 3px; height: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, .07); overflow: hidden;
}
.dl-jauge i {
  display: block; height: 100%; border-radius: 999px;
  background: var(--gold-grad); box-shadow: 0 0 10px var(--gold-glow);
  transition: width .45s cubic-bezier(.16, 1, .3, 1);
}

.dl-desc {
  margin: 0; font-size: 12px; line-height: 1.55; color: var(--ink-dim);
  font-style: italic;
}
.dl-stats { font-size: 11px; color: var(--ink-faint); letter-spacing: .03em; }

/* Le deck : une seule ligne, lisible d'un coup — nom, points, palier. */
.dl-deck {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: auto; padding: 9px 11px; border-radius: 9px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
}
.dl-deck.est-invalide { border-color: rgba(248, 113, 113, .4); background: rgba(248, 113, 113, .06); }
.dl-deck-lbl {
  font-size: 9px; font-weight: 800; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-faint);
}
.dl-deck-nom {
  font-size: 12px; font-weight: 700; color: var(--ink);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dl-deck-poids {
  margin-left: auto; font-family: var(--font-num), Georgia, serif;
  font-size: 13px; font-weight: 800; color: var(--ink-bright);
}
.dl-deck-palier {
  padding: 2px 8px; border-radius: 999px;
  font-size: 9px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  border: 1px solid currentColor; opacity: .95;
}
.palier-bronze  { color: #c98a4b; }
.palier-argent  { color: #c9d3e0; }
.palier-or      { color: var(--accent); }
.palier-platine { color: #8fe3ea; }
.palier-mythe   { color: #d6a3ff; }
.dl-deck-alerte {
  flex: 1 1 100%; font-size: 10px; font-weight: 700; color: #fca5a5;
}
.dl-deck-attente { font-size: 11px; color: var(--ink-faint); font-style: italic; }

/*  L'ETAT DE CHACUN. Un mot discret tant qu'on attend, une pastille verte
    des que c'est coche : on doit pouvoir lire le salon d'un coup d'oeil sans
    chercher qui manque. */
.dl-pret {
  align-self: flex-start;
  padding: 3px 10px; border-radius: 999px;
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-faint); border: 1px solid rgba(255,255,255,.14);
}
.dl-pret.est-pret {
  color: #86efac; border-color: rgba(134,239,172,.45);
  background: rgba(134,239,172,.10);
}
.dl-carte.est-pret { box-shadow: 0 0 0 1px rgba(134,239,172,.35) inset; }

#salon-pret.est-pret { filter: saturate(.55) brightness(.9); }

/*  LE DECOMPTE. Il passe par-dessus le salon : trois secondes ou il n'y a
    plus rien a decider, et ou l'on regarde ce qui commence. */
.salon-compte {
  position: fixed; inset: 0; z-index: 90;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; background: rgba(6, 8, 14, .78); backdrop-filter: blur(3px);
  pointer-events: none;
}
.salon-compte[hidden] { display: none; }
.salon-compte b {
  font-size: clamp(72px, 18vw, 160px); line-height: 1;
  color: var(--accent); text-shadow: 0 0 30px rgba(0,0,0,.6);
}
.salon-compte span {
  font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-faint);
}
.salon-compte b.bat { animation: compte-bat .55s ease-out; }
@keyframes compte-bat {
  from { transform: scale(1.5); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .salon-compte b.bat { animation: none; }
}

.dl-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.dl-actions button { flex: 1 1 auto; font-size: 11px; padding: 7px 10px; }

/* ── La discussion ───────────────────────────────────────────────────────── */
.salon-chat {
  width: 100%; display: flex; flex-direction: column; gap: 8px;
  padding: 14px; border-radius: 14px;
  border: 1px solid var(--line); background: rgba(12, 16, 26, .6);
}
.chat-titre {
  font-size: 9px; font-weight: 800; letter-spacing: .22em;
  text-transform: uppercase; color: var(--accent);
}
.chat-fil {
  display: flex; flex-direction: column; gap: 6px;
  height: 168px; overflow-y: auto; padding-right: 4px;
  scrollbar-width: thin;
}
.chat-vide {
  margin: auto; font-size: 11px; color: var(--ink-faint); font-style: italic;
}
.chat-ligne {
  align-self: flex-start; max-width: 78%;
  padding: 6px 11px; border-radius: 11px 11px 11px 3px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .04);
  font-size: 12.5px; line-height: 1.45; color: var(--ink);
  display: flex; flex-direction: column; gap: 1px;
  overflow-wrap: anywhere;
}
/* Mes mots à droite, les siens à gauche : la place dit qui parle, on n'a pas
   besoin de lire le nom pour le savoir. */
.chat-ligne.est-moi {
  align-self: flex-end; border-radius: 11px 11px 3px 11px;
  border-color: rgba(245, 185, 66, .35); background: rgba(245, 185, 66, .1);
}
.chat-ligne.est-systeme {
  align-self: center; max-width: 100%;
  border: 0; background: none; padding: 2px 0;
  font-size: 10.5px; color: var(--ink-faint); font-style: italic;
}
.chat-qui {
  font-size: 9px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint);
}
.chat-saisie { display: flex; gap: 6px; }
.chat-saisie input { flex: 1 1 auto; min-width: 0; }

/* ── La fiche qu'on modifie ──────────────────────────────────────────────── */
.profil-modale { position: fixed; inset: 0; z-index: 120; display: grid; place-items: center; }
.pm-voile {
  position: absolute; inset: 0;
  background: rgba(4, 6, 11, .78); backdrop-filter: blur(6px);
}
.pm-panneau {
  position: relative; z-index: 1;
  width: min(460px, calc(100vw - 28px)); max-height: calc(100dvh - 40px);
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 13px;
  padding: 26px 24px; border-radius: 18px;
  background: linear-gradient(165deg, rgba(24, 32, 50, .97) 0%, rgba(10, 13, 20, .99) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 26px 70px rgba(0, 0, 0, .7), 0 0 40px rgba(245, 185, 66, .1);
  transform: translateY(10px) scale(.985); opacity: 0;
  transition: transform .26s cubic-bezier(.16, 1, .3, 1), opacity .26s ease;
}
.profil-modale.est-ouvert .pm-panneau { transform: none; opacity: 1; }
.pm-fermer {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .04);
  color: var(--ink-dim); font-size: 18px; line-height: 1; cursor: pointer;
}
.pm-fermer:hover { color: var(--ink-bright); border-color: var(--line-gold); }
.pm-kicker {
  font-size: 9px; font-weight: 800; letter-spacing: .24em;
  text-transform: uppercase; color: var(--accent);
}
.pm-titre {
  margin: 0; font-family: var(--font-title), serif;
  font-size: 22px; font-weight: 800; color: var(--ink-bright);
}
.pm-avatar-rang { display: flex; align-items: center; gap: 14px; }
.pm-avatar {
  flex: 0 0 auto; width: 72px; height: 72px; border-radius: 50%;
  display: grid; place-items: center; overflow: hidden;
  border: 2px solid var(--line-gold);
  background: radial-gradient(circle at 30% 25%, rgba(245, 185, 66, .18), rgba(12, 16, 26, .9));
}
.pm-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pm-avatar .dl-initiales { font-size: 24px; }
.pm-avatar-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.pm-choisir { cursor: pointer; font-size: 11px; padding: 7px 11px; }
.pm-retirer { font-size: 11px; padding: 7px 11px; }
.pm-avatar-aide { flex: 1 1 100%; font-size: 10px; color: var(--ink-faint); }

.pm-champ { position: relative; display: flex; flex-direction: column; gap: 5px; }
.pm-champ > span {
  font-size: 9px; font-weight: 800; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-faint);
}
.pm-champ textarea {
  resize: vertical; min-height: 62px; font: inherit; font-size: 13px; line-height: 1.5;
}
.pm-compte {
  position: absolute; right: 2px; top: 0;
  font-size: 9px; font-weight: 700; color: var(--ink-faint);
}
.pm-erreur { font-size: 11.5px; color: #fca5a5; }
.pm-boutons { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }

/* LA MODALE HABILLEE COMME LE PROFIL DE LA PREMIERE VISITE (27/09/2026).
   Meme boite que `.tuto-ecran-boite`, meme visage cercle d'or a cote du nom,
   meme grille de personnages : on ne change pas de monde en revenant
   modifier ce qu'on a choisi a l'accueil. */
.profil-modale .pm-panneau {
  width: min(600px, calc(100vw - 28px));
  gap: 14px; padding: 30px 32px 26px; border-radius: 6px;
  border: 1px solid rgba(201, 162, 70, .5);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(201, 162, 70, .13), transparent 60%),
    linear-gradient(180deg, rgba(26, 20, 30, .98), rgba(11, 8, 14, .98));
  box-shadow: 0 30px 80px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 232, 180, .12);
}
.profil-modale .pm-kicker {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .3em; color: #c9a246;
}
.profil-modale .pm-titre {
  margin: -4px 0 2px; font-size: 27px; letter-spacing: .03em; line-height: 1.15;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pm-tete { display: flex; align-items: center; gap: 16px; }
.pm-champ-nom { flex: 1; min-width: 0; }
.profil-modale .pm-avatar {
  width: 76px; height: 76px; padding: 3px; overflow: visible;
  border: 0; background: var(--gold-grad);
  box-shadow: 0 0 22px rgba(245, 185, 66, .3);
}
.profil-modale .pm-avatar .dl-rond { background: radial-gradient(circle at 30% 25%, rgba(245, 185, 66, .14), rgba(12, 16, 26, .95)); }
/* LES CARTES DE PERSONNAGE (25/10/2026, js/carte_perso.js). Une rangee qui
   defile, cette fois : une grille de cartes debout prendrait trois etages
   pour treize personnages, et le profil doit tenir dans un ecran. La carte
   choisie est ramenee au centre a l'ouverture. */
.profil-modale .pm-persos,
.acc-persos {
  display: flex; gap: 9px;
  overflow-x: auto; overflow-y: hidden;
  padding: 8px 6px 12px; margin: -4px -6px 0;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: rgba(245, 185, 66, .35) transparent;
}
.pm-carte {
  flex: 0 0 auto; width: 98px;
  cursor: pointer;
  scroll-snap-align: center;
}
.pm-carte:focus-visible { outline: 2px solid var(--accent-light); outline-offset: 3px; }
.pm-carte.choisi,
button.pm-carte.choisi:hover:not(:disabled) {
  box-shadow: 0 0 0 2px var(--accent), 0 0 18px rgba(245, 185, 66, .5), 0 6px 16px rgba(0, 0, 0, .55);
}
.profil-modale .pm-perso { width: auto; }
.profil-modale .pm-champ textarea {
  background: rgba(10, 14, 23, 0.85); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; padding: 9px 13px;
  resize: none; transition: border-color .18s ease, box-shadow .18s ease;
}
.profil-modale .pm-champ textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(245, 185, 66, 0.18);
}
.profil-modale .pm-champ textarea::placeholder { color: var(--ink-faint); }
.profil-modale .pm-boutons button { min-height: 42px; padding: 0 22px; }

/* ── L'expérience gagnée, sur l'écran de fin ─────────────────────────────── */
.match-result-xp {
  display: flex; align-items: center; gap: 10px;
  margin-top: 4px; padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--line-gold); background: rgba(245, 185, 66, .09);
  font-size: 12px; color: var(--ink-dim);
}
.match-result-xp b { font-family: var(--font-num), Georgia, serif; color: var(--accent); font-size: 14px; }
.match-result-xp.est-montee {
  border-color: rgba(245, 185, 66, .8);
  box-shadow: 0 0 26px var(--gold-glow);
  color: var(--ink-bright);
}

/* ── Le bilan de fin de partie (points.js) ──────────────────────────────────
   L'issue, puis chaque critère qui entre à son tour, ses points qui montent ;
   le total, puis la jauge du niveau. Rien ne bouge en rAF : main.js pose les
   classes au minuteur (est-la, est-compte), les transitions font le reste. */
.match-result-panel:has(.bilan) {
  width: min(760px, 94vw);
  padding: 20px 30px 18px;
}
/*  L'en-tete et les vitres du bilan ne sont des blocs qu'en jeu (duel_jeu.css) :
    ici, leurs enfants restent a plat dans le panneau, et leurs titres caches. */
.match-result-tete, .bilan-col { display: contents; }
.bilan-entete, .rc-entete, .rc-attente { display: none; }
.bilan-resultat {
  display: flex; flex-direction: column; align-items: center; width: 100%;
}
/*  Rien ne defile : main.js (`ajusterFin`) reduit le panneau a l'echelle
    quand la place manque. */
.match-result-panel:has(.bilan) .match-result-sigil { font-size: 24px; margin-top: 6px; }
.match-result-panel:has(.bilan) .match-result-title { font-size: clamp(34px, 5vw, 54px); }
.match-result-panel:has(.bilan) .match-result-reason { margin-top: 8px; }
.bilan { width: 100%; margin-top: 14px; display: flex; flex-direction: column; align-items: center; }
.bilan-lignes {
  list-style: none; margin: 0; padding: 0; width: 100%;
  display: grid; grid-template-columns: 1fr 1fr; gap: 5px 6px;
}
.bilan-ligne.est-issue { grid-column: 1 / -1; }
.bilan-ligne {
  position: relative; overflow: hidden;
  display: grid; grid-template-columns: 30px 1fr auto; align-items: center; gap: 12px;
  padding: 7px 14px 7px 10px; border-radius: 8px;
  text-align: left;
  background: linear-gradient(90deg, rgba(255,255,255,.045), rgba(255,255,255,.015));
  border: 1px solid rgba(255,255,255,.06);
  opacity: 0; transform: translateX(-22px);
  transition: opacity .32s ease, transform .42s cubic-bezier(.2,.9,.25,1.15), border-color .3s, background .3s;
}
.bilan-ligne.est-la { opacity: 1; transform: none; }
.bilan-ligne.est-vide.est-la { opacity: .42; }
.bilan-ligne::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(245,185,66,.22) 50%, transparent 70%);
  transform: translateX(-110%);
}
.bilan-ligne.est-compte::after { animation: bilanBalaye .7s ease-out; }
.bilan-ligne.est-compte { border-color: var(--line-gold); }
.bilan-ligne.est-issue {
  border-color: color-mix(in srgb, var(--result) 45%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--result) 16%, transparent), rgba(255,255,255,.02));
}
.bilan-ico {
  width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 50%; font-style: normal; font-size: 15px;
  color: var(--accent);
  background: radial-gradient(circle, rgba(245,185,66,.16), rgba(245,185,66,.03) 70%);
  border: 1px solid var(--line-gold);
}
.est-issue .bilan-ico {
  color: var(--result);
  border-color: color-mix(in srgb, var(--result) 60%, transparent);
  background: radial-gradient(circle, color-mix(in srgb, var(--result) 22%, transparent), transparent 70%);
}
.bilan-quoi { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.bilan-quoi strong {
  color: #f5f0e7; font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.est-issue .bilan-quoi strong { color: var(--result); }
.bilan-quoi small { color: var(--ink-dim); font-size: 12px; margin-top: 2px; }
.bilan-pts {
  min-width: 46px; text-align: right;
  font: 800 18px/1 var(--font-num); color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.bilan-ligne.est-vide .bilan-pts { color: var(--ink-dim); font-weight: 600; }
.bilan-ligne.est-compte .bilan-pts { animation: bilanPop .38s cubic-bezier(.2,.9,.3,1.4); }
.est-issue .bilan-pts { color: var(--result); }

.bilan-total {
  display: flex; align-items: baseline; justify-content: center; gap: 12px;
  width: 100%; margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--line-gold);
  opacity: 0; transform: scale(.9);
  transition: opacity .35s ease, transform .5s cubic-bezier(.2,.9,.3,1.3);
}
.bilan-total.est-la { opacity: 1; transform: none; }
.bilan-total-lib, .bilan-total-unite {
  color: var(--ink-dim); font-size: 11px; font-weight: 800; letter-spacing: .24em; text-transform: uppercase;
}
.bilan-total-chiffre {
  font: 850 44px/1 var(--font-num); color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 22px var(--gold-glow);
}

/*  LES JAUGES D'EXPERIENCE (23/10/2026) : le profil, et la saison en partie
    classee, l'une sous l'autre. Chacune : son nom, son niveau, le gain qui
    compte, et la barre qui monte -- et qui eclate a chaque niveau franchi. */
.bilan-jauges {
  display: flex; flex-direction: column; gap: 9px; width: min(420px, 100%); margin-top: 12px;
  opacity: 0; transform: translateY(6px); transition: opacity .4s ease, transform .4s ease;
}
.bilan-jauges.est-la { opacity: 1; transform: none; }
.bilan-niveau { display: flex; flex-direction: column; gap: 5px; width: 100%; }
.bilan-niveau-tete { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.bilan-niveau-nom {
  color: var(--ink-dim); font-size: 10px; font-weight: 850; letter-spacing: .22em; text-transform: uppercase;
}
.bilan-niveau-lib { color: #f5f0e7; font-size: 12px; font-weight: 700; }
.bilan-niveau-gain {
  margin-left: auto; font: 800 16px/1 var(--font-num); color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.bilan-niveau-unite {
  color: var(--ink-dim); font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
}
.bilan-niveau.est-nulle { opacity: .55; }
.bilan-niveau.est-nulle .bilan-niveau-gain { color: var(--ink-dim); }
.bilan-niveau.est-franchie .bilan-niveau-lib { color: var(--accent); text-shadow: 0 0 12px var(--gold-glow); animation: bilanNiveauNeuf .5s cubic-bezier(.2,.9,.3,1.4); }
.bilan-barre {
  position: relative; display: block; height: 10px; border-radius: 999px; overflow: hidden;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.1);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.5);
}
.bilan-barre-pleine {
  position: absolute; inset: 0 auto 0 0; width: 0; overflow: hidden;
  border-radius: inherit;
  background: linear-gradient(90deg, #b9832b, var(--accent), #ffe3a3);
  box-shadow: 0 0 12px var(--gold-glow);
  transition: width .5s cubic-bezier(.3,.8,.3,1);
}
/*  La saison a sa propre couleur : on voit d'un coup d'oeil que deux
    choses montent. */
.bilan-niveau + .bilan-niveau .bilan-barre-pleine {
  background: linear-gradient(90deg, #5b3aa8, #9b7bff, #e2d6ff);
  box-shadow: 0 0 12px rgba(155, 123, 255, .55);
}
/*  Un reflet court sur la barre tant qu'elle monte. */
.bilan-niveau.est-monte .bilan-barre-pleine::after {
  content: ''; position: absolute; inset: 0; width: 40%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: bilanReflet .9s ease-in-out 2;
}
.bilan-barre-pleine.sans-transition { transition: none; }
.bilan-niveau.est-franchie .bilan-barre { animation: bilanFranchi 1.2s ease-out; }

.bilan-note {
  margin: 10px 0 0; color: #8f99ab; font-size: 11px;
  opacity: 0; transition: opacity .4s ease;
}
.bilan-note.est-la { opacity: 1; }
.match-result-boutons {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 20px;
}
.match-result-boutons .match-result-replay { margin-top: 0; }
.match-result-accueil { min-width: 130px; }
.match-result-boutons.bilan-rejouer {
  margin-top: 14px;
  opacity: 0; transform: translateY(6px); transition: opacity .35s ease, transform .35s ease;
}
.match-result-boutons.bilan-rejouer.est-la { opacity: 1; transform: none; }

/*  La partie finie, « Abandonner » n'a plus de sens -- et il flottait sur le
    bilan (il vit dans la barre de la Roue, au-dessus du cadre de la table). */

/*  PEU DE HAUTEUR (telephone couche, petite fenetre). On retire ce qui se
    devine (sur-titre, sigle, manche), les criteres passent sur trois
    colonnes, le total et la jauge sur une seule rangee. Ce qui manque encore,
    `ajusterFin` (main.js) le rattrape a l'echelle. */
@media (max-height: 560px) {
  .match-result:has(.bilan) { padding: 6px; }
  .match-result-panel:has(.bilan) { width: min(860px, 98%); padding: 8px 14px 10px; }
  .match-result-panel:has(.bilan) .match-result-kicker,
  .match-result-panel:has(.bilan) .match-result-sigil,
  .match-result-panel:has(.bilan) .match-result-meta { display: none; }
  .match-result-panel:has(.bilan) .match-result-title { font-size: 26px; margin-top: 0; }
  .match-result-panel:has(.bilan) .match-result-reason { margin-top: 2px; font-size: 12px; }
  .bilan { margin-top: 6px; }
  .bilan-lignes { grid-template-columns: repeat(3, 1fr); gap: 3px 5px; }
  .bilan-ligne { padding: 3px 8px 3px 6px; gap: 7px; grid-template-columns: 22px 1fr auto; }
  .bilan-ico { width: 22px; height: 22px; font-size: 11px; }
  .bilan-quoi strong { font-size: 10.5px; }
  .bilan-quoi small { font-size: 10px; margin-top: 0; }
  .bilan-pts { font-size: 14px; min-width: 30px; }
  .bilan-resultat { flex-direction: row; justify-content: center; gap: 22px; margin-top: 6px;
    padding-top: 6px; border-top: 1px solid var(--line-gold); }
  .bilan-total { width: auto; margin: 0; padding: 0; border: 0; }
  .bilan-total-chiffre { font-size: 26px; }
  .bilan-jauges { width: min(330px, 48%); margin: 0; gap: 5px; }
  .bilan-barre { height: 8px; }
  .bilan-note { margin-top: 4px; font-size: 10.5px; }
  .match-result-boutons.bilan-rejouer { margin-top: 6px; }
  .match-result-boutons button { min-height: 32px; padding-top: 3px; padding-bottom: 3px; }
}

@keyframes bilanBalaye { from { transform: translateX(-110%); } to { transform: translateX(110%); } }
@keyframes bilanPop { 0% { transform: scale(1); } 45% { transform: scale(1.32); } 100% { transform: scale(1); } }
@keyframes bilanFranchi {
  0% { box-shadow: 0 0 0 rgba(245,185,66,0); }
  30% { box-shadow: 0 0 22px rgba(245,185,66,.75); }
  100% { box-shadow: 0 0 0 rgba(245,185,66,0); }
}

/* ── LA FETE DE FIN (23/10/2026) ──────────────────────────────────────────
   Avant le bilan, le titre seul (main.js, `sceneDeFin`) : `fin-fete` le
   montre, `fin-bilan` le fait partir pendant que le panneau entre. Victoire :
   il claque dans deux ondes d'or et des eclats ; defaite : il tombe, lourd,
   dans une pluie de cendres ; egalite : il se pose. Le panneau reste mesure
   (visibility, pas display) : `ajusterFin` le cadre avant qu'il n'entre. */
.match-result { --fete: #ffd36a; }
.match-result.defeat { --fete: #ff5247; }
.match-result.draw { --fete: #d3b56f; }
.match-result.fin-fete .match-result-panel { visibility: hidden; }
.match-result.fin-bilan .match-result-panel { animation: resultReveal .85s cubic-bezier(.18,.8,.2,1.05) both; }
.match-result.defeat.fin-fete { backdrop-filter: blur(3px) saturate(.2); }

.fin-scene {
  position: absolute; inset: 0; z-index: 2; pointer-events: none; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  visibility: hidden;
}
.fin-fete .fin-scene, .fin-bilan .fin-scene { visibility: visible; }
.fin-bilan .fin-scene { animation: finSceneSort .55s ease forwards; }
.fin-onde, .fin-halo, .fin-eclats {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
}
/*  PAS DE SOLEIL MANGA (Alexandre, 01/11/2026) : les rayons coniques sont
 *  partis. Deux ondes d'or s'ouvrent depuis le titre, un anneau fin et net
 *  qui s'efface en grandissant. */
.fin-onde {
  width: 40vmin; height: 40vmin; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--fete) 80%, #fff);
  box-shadow: 0 0 24px color-mix(in srgb, var(--fete) 60%, transparent),
    inset 0 0 24px color-mix(in srgb, var(--fete) 40%, transparent);
  opacity: 0;
}
.fin-fete .fin-onde { animation: finOnde 1.6s cubic-bezier(.15,.7,.3,1) .2s both; }
.fin-fete .fin-onde-2 { animation-delay: .5s; border-width: 1px; }
@keyframes finOnde {
  0% { opacity: 0; transform: scale(.25); }
  15% { opacity: .95; }
  100% { opacity: 0; transform: scale(3.6); }
}
.defeat .fin-onde { border-color: rgba(255, 120, 100, .5); }
/*  LA POUSSIERE D'OR : des grains qui montent lentement, de toute la largeur ;
 *  en defaite, des cendres qui descendent. Elle reste pendant le bilan. */
.fin-poussiere { position: absolute; inset: 0; opacity: 0; }
.fin-fete .fin-poussiere, .fin-bilan .fin-poussiere { opacity: 1; transition: opacity 1.2s; }
.fin-poussiere i {
  position: absolute; left: var(--x); bottom: -2%;
  width: calc(6px * var(--s)); height: calc(6px * var(--s)); border-radius: 50%;
  background: radial-gradient(circle, #fff6d8, color-mix(in srgb, var(--fete) 80%, transparent) 50%, transparent 72%);
  box-shadow: 0 0 calc(10px * var(--s)) color-mix(in srgb, var(--fete) 70%, transparent);
  animation: finPoussiere var(--dur) linear var(--t) infinite;
}
@keyframes finPoussiere {
  0% { transform: translate(0, 0); opacity: 0; }
  12% { opacity: .9; }
  70% { opacity: .7; }
  100% { transform: translate(var(--dx), -104vh); opacity: 0; }
}
.defeat .fin-poussiere i {
  top: -2%; bottom: auto;
  background: radial-gradient(circle, #d9a49a, #5a1c16 60%, transparent 75%);
  box-shadow: none;
  animation-name: finCendrePoussiere;
}
@keyframes finCendrePoussiere {
  0% { transform: translate(0, 0) rotate(0); opacity: 0; }
  15% { opacity: .6; }
  100% { transform: translate(var(--dx), 104vh) rotate(200deg); opacity: 0; }
}
.fin-halo {
  width: 80vmin; height: 80vmin; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--fete) 42%, transparent), transparent 62%);
  opacity: 0;
}
.fin-fete .fin-halo { animation: finHalo 1.9s ease-out both; }
.fin-eclats { width: 0; height: 0; }
.fin-eclats i {
  position: absolute; left: 0; top: 0;
  width: calc(7px * var(--s)); height: calc(7px * var(--s)); margin: calc(-3.5px * var(--s));
  border-radius: 50%; opacity: 0;
  background: radial-gradient(circle, #fff, var(--fete) 55%, transparent 72%);
  box-shadow: 0 0 10px var(--fete);
}
.fin-fete .fin-eclats i { animation: finEclat 1.25s cubic-bezier(.1,.75,.3,1) calc(.12s + var(--t)) both; }
.fin-kicker {
  position: relative; color: color-mix(in srgb, var(--fete) 55%, #fff);
  font-size: 12px; font-weight: 850; letter-spacing: .34em;
  text-shadow: 0 2px 10px rgba(0,0,0,.9);
  opacity: 0;
}
.fin-fete .fin-kicker { animation: finKicker .6s ease-out .1s both; }
.fin-titre {
  position: relative;
  font: 850 clamp(58px, 12vw, 136px)/.9 "Fraunces", Georgia, serif;
  letter-spacing: .14em; margin-right: -.14em;
  color: color-mix(in srgb, var(--fete) 30%, #fff8ea);
  -webkit-text-stroke: 1px rgba(40, 20, 0, .55);
  paint-order: stroke fill;
  text-shadow:
    0 0 2px rgba(0,0,0,.9),
    0 5px 0 rgba(0,0,0,.55),
    0 0 34px var(--fete),
    0 0 80px color-mix(in srgb, var(--fete) 55%, transparent),
    0 10px 30px rgba(0,0,0,.9);
  opacity: 0;
}
.fin-fete .fin-titre { animation: finTitre 1s cubic-bezier(.2,.8,.25,1) .18s both; }
.fin-trait {
  position: relative; display: block; height: 2px; width: min(560px, 74vw);
  background: linear-gradient(90deg, transparent, var(--fete), #fff, var(--fete), transparent);
  box-shadow: 0 0 14px var(--fete);
  transform: scaleX(0); opacity: 0;
}
.fin-fete .fin-trait { animation: finTrait .7s cubic-bezier(.2,.8,.3,1) .45s both; }

/*  LA DEFAITE : le titre tombe, et des cendres descendent. */
.defeat .fin-eclats i {
  background: radial-gradient(circle, #ffb3a0, #6a1d16 60%, transparent 75%);
  box-shadow: 0 0 6px rgba(255, 70, 50, .55);
}
.defeat.fin-fete .fin-eclats i { animation: finCendre 2.2s linear calc(var(--t) * 2) both; }
.defeat.fin-fete .fin-titre { animation: finTitreChute .9s cubic-bezier(.5,0,.75,0) .15s both, finTitreAssise .5s ease-out 1.05s forwards; }
.draw.fin-fete .fin-titre { animation: finTitrePose 1s ease-out .15s both; }
.draw .fin-eclats { display: none; }

@keyframes finHalo {
  0% { opacity: 0; transform: scale(.2); }
  25% { opacity: 1; transform: scale(1.05); }
  100% { opacity: .7; transform: scale(1); }
}
@keyframes finEclat {
  0% { opacity: 1; transform: rotate(var(--a)) translateX(0) scale(1.3); }
  100% { opacity: 0; transform: rotate(var(--a)) translateX(var(--d)) scale(.25); }
}
@keyframes finCendre {
  0% { opacity: 0; transform: translate(var(--x), -46vh); }
  15% { opacity: .85; }
  100% { opacity: 0; transform: translate(calc(var(--x) * 1.15), 36vh); }
}
@keyframes finKicker {
  0% { opacity: 0; letter-spacing: .9em; transform: translateY(8px); }
  100% { opacity: 1; letter-spacing: .34em; transform: none; }
}
@keyframes finTitre {
  0% { opacity: 0; transform: scale(2.3); letter-spacing: .5em; }
  24% { opacity: 1; transform: scale(.93); letter-spacing: .14em; }
  36% { transform: scale(1.05); }
  50% { transform: scale(.99); }
  64%, 100% { opacity: 1; transform: scale(1); letter-spacing: .14em; }
}
@keyframes finTitreChute {
  0% { opacity: 0; transform: translateY(-70px) scale(1.2); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes finTitreAssise {
  0% { transform: translateY(0) scale(1); }
  25% { transform: translateY(6px) scale(1.02, .96); }
  55% { transform: translateY(-2px) scale(1); }
  100% { opacity: 1; transform: none; }
}
@keyframes finTitrePose {
  0% { opacity: 0; transform: scale(.9); }
  100% { opacity: 1; transform: none; }
}
@keyframes finTrait {
  0% { opacity: 0; transform: scaleX(0); }
  100% { opacity: 1; transform: scaleX(1); }
}
@keyframes finSceneSort {
  0% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(-26px) scale(.94); }
}
@keyframes bilanBat {
  0% { transform: scale(1); }
  40% { transform: scale(1.14); text-shadow: 0 0 30px var(--gold-glow); }
  100% { transform: scale(1); }
}
@keyframes bilanFinal {
  0% { transform: scale(1.5); filter: brightness(2); }
  40% { transform: scale(.94); filter: brightness(1.3); }
  70% { transform: scale(1.04); }
  100% { transform: scale(1); filter: none; }
}
@keyframes bilanNiveauNeuf {
  0% { transform: scale(1); }
  45% { transform: scale(1.18); }
  100% { transform: scale(1); }
}
@keyframes bilanReflet { from { translate: -110% 0; } to { translate: 260% 0; } }
.bilan-total-chiffre { display: inline-block; }
.bilan-total.est-bat .bilan-total-chiffre { animation: bilanBat .34s cubic-bezier(.2,.9,.3,1.4); }
.bilan-total.est-final .bilan-total-chiffre {
  animation: bilanFinal .6s cubic-bezier(.2,.8,.3,1);
  text-shadow: 0 0 26px var(--gold-glow), 0 0 4px rgba(0,0,0,.8);
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .fin-onde, :where(html:not(.mouvement-plein)) .fin-eclats, :where(html:not(.mouvement-plein)) .fin-poussiere { display: none; }
  :where(html:not(.mouvement-plein)) .fin-fete .fin-titre, :where(html:not(.mouvement-plein)) .defeat.fin-fete .fin-titre, :where(html:not(.mouvement-plein)) .fin-fete .fin-kicker, :where(html:not(.mouvement-plein)) .fin-fete .fin-trait { animation: finTitrePose .4s ease-out both; }
  :where(html:not(.mouvement-plein)) .bilan-total.est-bat .bilan-total-chiffre, :where(html:not(.mouvement-plein)) .bilan-total.est-final .bilan-total-chiffre { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .bilan-ligne, :where(html:not(.mouvement-plein)) .bilan-total, :where(html:not(.mouvement-plein)) .bilan-barre-pleine { transition: opacity .2s ease; transform: none; }
  :where(html:not(.mouvement-plein)) .bilan-ligne.est-compte::after, :where(html:not(.mouvement-plein)) .bilan-ligne.est-compte .bilan-pts, :where(html:not(.mouvement-plein)) .bilan-niveau.est-franchie .bilan-barre { animation: none; }
}
@media (max-width: 700px) {
  .match-result-panel:has(.bilan) { padding: 20px 14px 18px; }
  .match-result-panel:has(.bilan) .match-result-title { font-size: 34px; }
  .match-result-panel:has(.bilan) .match-result-sigil { font-size: 24px; margin-top: 6px; }
  .bilan { margin-top: 12px; }
  .bilan-lignes { grid-template-columns: 1fr; gap: 4px; }
  .bilan-ligne { padding: 5px 10px 5px 8px; gap: 9px; grid-template-columns: 24px 1fr auto; }
  .bilan-ico { width: 24px; height: 24px; font-size: 12px; }
  .bilan-quoi strong { font-size: 11.5px; }
  .bilan-quoi small { font-size: 11px; }
  .bilan-pts { font-size: 15px; min-width: 38px; }
  .bilan-total-chiffre { font-size: 34px; }
}

/* ── Au téléphone ────────────────────────────────────────────────────────── */
@media (max-width: 700px) {
  /* LA PLACE DE LA BANQUE REVIENT AU MULTIJOUEUR. Le blason, tout à gauche de
     la barre, ramène déjà au sanctuaire : l'onglet 🏛️ juste à côté faisait
     doublon, et il occupait une des cinq places atteignables au pouce. Il est
     masqué en portrait — pas supprimé : au large, la barre complète revient. */
  .tab[data-view="accueil"] { display: none; }

  .multi { gap: 16px; padding: 4px 0 20px; }
  .multi-tag { font-size: 12px; }
  .salon-porte { grid-template-columns: 1fr; gap: 12px; }
  .porte-carte { padding: 18px 16px; }
  .porte-carte button, .porte-carte .salon-join { width: 100%; }
  .porte-ou { flex-direction: row; gap: 10px; }
  .porte-ou::before, .porte-ou::after {
    flex: 1 1 40px; width: auto; height: 1px; min-height: 0;
    background: linear-gradient(90deg, transparent, var(--line), transparent);
  }

  /* Deux fiches côte à côte tiendraient sur 360 px de large, mais chacune y
     serait illisible. Elles s'empilent, et le « VS » devient le trait qui les
     sépare plutôt que l'objet qui les oppose. */
  .salon-duo { grid-template-columns: 1fr; gap: 10px; }
  .salon-versus { font-size: 15px; }
  .salon-versus span { width: 34px; height: 34px; }

  .salon-code-vitre { width: 100%; }
  .salon-copier { position: static; transform: none; margin-top: 6px; }

  .dl-carte { padding: 14px; }
  .dl-avatar { width: 48px; height: 48px; }
  .dl-initiales { font-size: 17px; }
  .dl-nom { font-size: 15px; }
  .chat-fil { height: 132px; }
  .pm-panneau { padding: 22px 18px; gap: 11px; }
}

/* ── LA BARRE DU HAUT TIENT SUR UNE LIGNE ──────────────────────────────────
 * Un cinquième onglet, et elle passait de 58 à 125 px de haut sur un écran de
 * 1280. Ce n'était pas la rangée d'onglets qui débordait, mais l'étiquette
 * d'état — « KAIROS · 137 cartes · 228 familles » — qui, comprimée, s'écrivait
 * sur trois lignes et poussait tout le reste vers le bas. Elle est purement
 * décorative : elle ne survit que tant qu'il reste de la place pour elle, et
 * `--topbar-h` redevient une mesure vraie. */
.topbar { flex-wrap: nowrap; }
.status-container { min-width: 0; }
.status { white-space: nowrap; overflow: hidden; }
.status .status-label { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 1400px) { .status-container { display: none; } }
@media (max-width: 1150px) {
  .topbar { gap: 14px; padding: 10px 16px; }
  .tab { padding: 8px 11px; font-size: 12px; }
  .brand-sub { display: none; }
}

/* ── ET ELLE NE DEBORDE PLUS A DROITE (25/09/2026) ──────────────────────────
 * Mesure sur le site en ligne : de 901 a ~1600 px de large, la barre
 * debordait -- jusqu'a 490 px de trop. L'engrenage des reglages (et le
 * grimoire) sortaient de l'ecran sur la plupart des portables (1366, 1440,
 * 1536), et la page defilait de cote. Les textes secondaires cedent d'abord,
 * dans cet ordre : le grimoire garde son image, le profil son visage. */
@media (max-width: 1700px) {
  .cta-booster-txt { display: none; }
  .profil-chip .pc-txt { display: none; }
  /* Sans leur texte, les deux pastilles gardaient le rembourrage droit prevu
     pour lui : l'avatar et le grimoire se collaient a gauche d'une pilule a
     moitie vide. Rembourrage egal, contenu au centre. */
  /* `.topbar` devant : la regle de base de la pastille (`.profil-chip`,
     plus loin dans la feuille) l'emportait a poids egal, et l'avatar restait
     decale entre 1150 et 1700 px. */
  .topbar .profil-chip { padding: 3px; }
  .topbar .cta-booster { padding: 4px 8px; }
}
@media (max-width: 1400px) {
  .topbar { gap: 16px; }
  .tab { padding: 8px 10px; }
}
/* Sous 1150 (tablette a l'horizontale, petit portable) : les onglets n'ont
 * pas d'icone au large, on ne peut donc pas les reduire a leur signe. Ce qui
 * se retrouve ailleurs cede : le nom a cote du blason, le rond Discord (il est
 * dans les Parametres), et « Statistiques » se dit « Stats », comme au
 * telephone. Sous 1000, le Livre blanc se dit « Livre » : il reste dans la
 * barre a tous les formats (demande d'Alexandre, 26/09/2026 -- il manquait au
 * telephone et a la tablette). */
@media (max-width: 1150px) {
  .brand-text { display: none; }
  /* Le rond Discord ne cede plus ici : c'est `tasserBarre` qui le retire,
     au dernier cran, si la place manque vraiment (demande d'Alexandre). */
  .tab { padding: 8px 8px; }
  .tab[data-view="stats"] .tab-text { font-size: 0; }
  .tab[data-view="stats"] .tab-text::after { content: 'Stats'; font-size: 12px; }
}
@media (max-width: 1000px) {
  .tab-lien .tl-long { display: none; }
  .tab-lien .tl-court { display: inline; }
}

/* ── LES CRANS DE TASSEMENT (poses par `tasserBarre`, main.js) ──────────────
 * Les paliers ci-dessus sont un plancher ; ceux-ci s'ajoutent un par un tant
 * que la barre deborde REELLEMENT. Meme ordre de sacrifice : textes
 * secondaires, marges, libelle du portefeuille (cran 3, cote JS), nom du jeu,
 * Livre blanc raccourci en « Livre », puis les onglets se resserrent. */
@media (min-width: 701px) {
  /* Un onglet qui passe sur deux lignes (« Livre / blanc ») ne deborde pas :
     il grandit, et la barre avec lui. Insecable, il deborde -- et se mesure. */
  .topbar .tab, .topbar .tab-text { white-space: nowrap; }
  .topbar.serre-1 .cta-booster-txt,
  .topbar.serre-1 .profil-chip .pc-txt { display: none; }
  .topbar.serre-1 .profil-chip { padding: 3px; }
  .topbar.serre-1 .cta-booster { padding: 4px 8px; }
  .topbar.serre-2 { gap: 12px; }
  .topbar.serre-2 .tab { padding: 8px 9px; }
  .topbar.serre-4 .brand-text { display: none; }
  .topbar.serre-4 .tab[data-view="stats"] .tab-text { font-size: 0; }
  .topbar.serre-4 .tab[data-view="stats"] .tab-text::after { content: 'Stats'; font-size: 12px; }
  .topbar.serre-5 .tab-lien .tl-long { display: none; }
  .topbar.serre-5 .tab-lien .tl-court { display: inline; }
  .topbar.serre-6 { gap: 8px; padding-left: 12px; padding-right: 12px; }
  .topbar.serre-6 .tab { padding: 7px 6px; font-size: 12px; }
  .topbar.serre-6 .header-actions { gap: 6px; }
  .topbar.serre-6 :is(.btn-parametres, .btn-discord) { margin-left: 4px; }
  .topbar.serre-7 .tab { padding: 6px 4px; font-size: 11px; letter-spacing: 0; }
  .topbar.serre-7 .tab-caret { display: none; }
  /* Discord cede en tout dernier, apres les onglets resserres. */
  .topbar.serre-7 .btn-discord { display: none; }
}
.topbar.barre-mesure, .topbar.barre-mesure * { transition: none !important; }

/* ══ LA TABLETTE EN PORTRAIT : LES ONGLETS PRENNENT LEUR ICONE ═════════════
 * Entre 701 et 820 px de large en portrait (iPad, iPad mini, tablettes
 * Android), la barre masquait le texte des onglets en comptant sur des
 * glyphes `.tab-glyph`... qui n'existaient plus dans la page : il ne restait
 * qu'un « ▾ » et des boutons vides, AUCUNE navigation (signale le 25/09/2026).
 * Les onglets reprennent les icones dessinees de la barre du telephone, le
 * libelle dessous -- meme langage d'un format a l'autre -- mais restent en
 * haut : une tablette se tient a deux mains, pas au pouce.
 * Les icones sont ici, hors media query : le telephone (mobile.css) et la
 * tablette les partagent. */
#nav-jouer-btn { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.5 17.5 3 6V3h3l11.5 11.5'/%3E%3Cpath d='m13 19 6-6M16 16l4 4M19 21l2-2'/%3E%3Cpath d='M9.5 17.5 21 6V3h-3L6.5 14.5'/%3E%3Cpath d='m11 19-6-6M8 16l-4 4M5 21l-2-2'/%3E%3C/svg%3E"); }
.tab[data-view="accueil"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11 12 4l9 7'/%3E%3Cpath d='M5 10v10h14V10'/%3E%3Cpath d='M10 20v-6h4v6'/%3E%3C/svg%3E"); }
  #nav-jouer-btn { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.5 17.5 3 6V3h3l11.5 11.5'/%3E%3Cpath d='m13 19 6-6M16 16l4 4M19 21l2-2'/%3E%3Cpath d='M9.5 17.5 21 6V3h-3L6.5 14.5'/%3E%3Cpath d='m11 19-6-6M8 16l-4 4M5 21l-2-2'/%3E%3C/svg%3E"); }
  .tab[data-view="atelier"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'%3E%3Crect x='3' y='6' width='11' height='15' rx='2'/%3E%3Cpath d='M8 3h11a2 2 0 0 1 2 2v13'/%3E%3C/svg%3E"); }
  .tab[data-view="collection"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'%3E%3Cpath d='M4 4h7v16H4zM13 4h7v16h-7z'/%3E%3Cpath d='M7 8h1M7 12h1M16 8h1M16 12h1'/%3E%3C/svg%3E"); }
  .tab[data-view="marche"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l2-5h14l2 5'/%3E%3Cpath d='M3 9h18v2a3 3 0 0 1-6 0 3 3 0 0 1-6 0 3 3 0 0 1-6 0z'/%3E%3Cpath d='M5 13v8h14v-8M10 21v-5h4v5'/%3E%3C/svg%3E"); }
  .tab[data-view="forge"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3c1 3 4 4.5 4 8a4 4 0 0 1-8 0c0-1.5.7-2.6 1.5-3.5.2 1.3 1 2 1.8 2C11 7 11 5 12 3z'/%3E%3Cpath d='M4 17h16l-2 4H6z'/%3E%3C/svg%3E"); }
  .tab[data-view="stats"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 20h16'/%3E%3Cpath d='M7 16v-5M12 16V6M17 16v-8'/%3E%3C/svg%3E"); }
.tab.tab-lien { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 6c-2-1.5-5-2-8-2v14c3 0 6 .5 8 2 2-1.5 5-2 8-2V4c-3 0-6 .5-8 2z'/%3E%3Cpath d='M12 6v14'/%3E%3C/svg%3E"); }
@media (min-width: 701px) and (max-width: 820px) and (orientation: portrait) {
  .tabs { flex: 1 1 auto; gap: 0; min-width: 0; justify-content: space-between; }
  .tabs > .tab, .tabs > .tab-groupe { flex: 1 1 0; min-width: 0; }
  .tab-groupe { display: flex; }
  .tab-groupe > .tab { flex: 1 1 auto; }
  /* `[class]` pese plus que les crans du bureau (`.topbar.serre-6 .tab`),
     qui redonnaient du rembourrage aux onglets et annulaient le gain. */
  .topbar[class] .tabs .tab {
    flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; padding: 5px 2px 4px; min-width: 0;
  }
  .tabs .tab-text {
    display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .01em;
    line-height: 1; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tab[data-view="stats"] .tab-text { font-size: 0; }
  .tab[data-view="stats"] .tab-text::after { content: 'Stats'; font-size: 10.5px; }
  .tab-caret, .tab-lien .tl-long { display: none; }
  .tab-lien .tl-court { display: inline; }
  /* « Livre » est court : il cede de sa part a « Cartable », qui se coupait. */
  .tabs > .tab.tab-lien { flex-grow: .7; }
  .tabs > .tab.tab-boutique { flex-grow: 1.25; }
  .tabs .tab::before,
  .tabs #nav-jouer-btn::before {
    content: '' !important;
    display: block; width: 20px; height: 20px; flex: none;
    background: currentColor;
    -webkit-mask: var(--ico) center / contain no-repeat;
            mask: var(--ico) center / contain no-repeat;
  }
  .tab-pastille { top: 3px; right: calc(50% - 18px); }
  .wallet-btn { padding: 0 12px; }
  /* Comme au telephone, pas d'onglet Accueil : le blason y ramene. La
     place revient au rond Discord. */
  .tabs .tab[data-view="accueil"] { display: none; }
  /* Les crans de la tablette : les libelles, puis les ecarts. */
  .topbar.serre-5 .tabs .tab-text,
  .topbar.serre-5 .tab[data-view="stats"] .tab-text::after { font-size: 10px; letter-spacing: 0; }
  .topbar.serre-6 .header-actions { gap: 4px; }
  .topbar.serre-6 .wallet-btn { padding: 0 9px; }
}


/* ── Le choix de la matiere des des, a l'atelier ──────────────────────────
   La pastille MONTRE la matiere : sa couleur, et l'encre de ses chiffres.
   Un nom seul -- « obsidienne », « givre » -- ne dit rien tant qu'on n'a pas
   vu le de tomber une fois. */
.de-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px 5px 6px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .14);
  background: rgba(255, 255, 255, .04);
  color: var(--ink-dim); font-size: 12px; cursor: pointer;
}
.de-chip:hover { border-color: rgba(201, 162, 70, .5); color: var(--ink); }
.de-chip.is-on {
  border-color: var(--accent); color: var(--ink);
  box-shadow: 0 0 14px rgba(255, 190, 77, .25);
}
/*  LA PASTILLE DU TAPIS MONTRE UN MORCEAU DE PLANCHE, pas une couleur.
 *  Un de EST une couleur, une dalle ne l'est pas : elle a un grain, des
 *  fissures, et l'or s'y pose d'une certaine facon. Six carres unis les
 *  auraient rendus interchangeables. La vignette est decoupee par la
 *  fabrique, centree sur une arene (plateau_cartoon.py).
 *  Elle est un peu plus grande et ronde -- comme l'arene qu'elle montre. */
.de-pastille.est-tapis {
  width: 26px; height: 26px; border-radius: 50%;
  background-size: cover; background-position: center;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .1), 0 1px 3px rgba(0, 0, 0, .5);
}

.de-pastille {
  width: 18px; height: 18px; border-radius: 5px;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 800; line-height: 1;
  border: 1px solid rgba(0, 0, 0, .45);
  box-shadow: inset 0 1px 3px rgba(255, 255, 255, .35), 0 1px 3px rgba(0, 0, 0, .5);
}

/* ══ LES VISAGES ═══════════════════════════════════════════════════════════
   Les personnages sont dessines en BUSTE : la tete occupe le haut du carre, la
   veste tout le bas. Poses tels quels dans un rond, ils montrent un col de
   blouson et coupent les cheveux.

   ON A D'ABORD CORRIGE CA ICI, avec un agrandissement de 1,7 et une descente
   de 22 % -- deux nombres regles a l'oeil sur Zephyr. Ils ne valaient que pour
   lui : un ogre a la tete plus large, un golem de pierre n'a pas de cou, un
   alien est une tete posee sur un col, et le meme recadrage leur coupait le
   visage en deux. Un reglage par personnage dans la feuille de style aurait
   ete vingt nombres a tenir a jour.

   Le cadrage est donc CALCULE et cuit dans l'image, une fois par personnage
   (`outils/avatars/cadrer.py`, qui trouve le cou et met toutes les tetes a la
   meme taille). Ici, on n'agrandit plus rien -- et c'est pour ca qu'il n'y a
   plus de nombre magique a lire dans cette section. */
.dp-cadre img.dp-perso,
.dl-rond img.dl-perso,
.pm-perso img,
.pm-humeur img {
  object-fit: contain;
}

/* LE ROGNEUR. Les ronds qui accueillent un personnage laissent deliberement
   deborder leur contenu -- c'est comme cela que la couronne de l'hote tient
   sur le bord. Le portrait, lui, doit rester dans le cercle : il lui faut son
   propre disque, a l'interieur. */
.dl-rond {
  width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  display: block;
}
.dl-rond img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* LA MUE. Le visage change d'humeur sans que le cadre bouge : un fondu court
   sur l'image seule. Assez rapide pour appartenir au coup qui vient de tomber
   (une attaque entiere dure 1,15 s), assez visible pour qu'on comprenne que
   c'est une REACTION et non un rechargement. */
@keyframes dp-mue {
  0%   { opacity: .35; filter: brightness(1.5); }
  100% { opacity: 1;   filter: none; }
}
.dp-cadre img.dp-mue { animation: dp-mue .28s ease-out both; }

/* ── LE CHOIX DU PERSONNAGE, DANS LE PANNEAU DE PROFIL ──────────────────── */
.pm-persos-bloc { display: grid; gap: 8px; }
.pm-persos-titre {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-family: var(--font-title); font-size: 11px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-dim);
}
.pm-persos-note {
  font-family: var(--font-body); font-size: 10px; font-weight: 500;
  letter-spacing: 0; text-transform: none; color: var(--ink-faint);
}
/* Une rangee qui defile, et non une grille qui grandit : le catalogue passera
   de deux personnages a vingt, et le panneau ne doit pas grandir avec lui. */
.pm-persos {
  display: flex; gap: 8px; overflow-x: auto; padding: 2px 2px 6px;
  scrollbar-width: thin;
}
.pm-perso {
  flex: 0 0 auto; width: 66px;
  display: grid; justify-items: center; gap: 4px;
  padding: 5px 3px; border-radius: 10px; cursor: pointer;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(150, 168, 190, .18);
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}
.pm-perso:hover { transform: translateY(-2px); border-color: rgba(245, 185, 66, .45); }
.pm-perso .dl-rond {
  width: 46px; height: 46px;
  background: radial-gradient(circle at 30% 25%, rgba(245, 185, 66, .14), rgba(12, 16, 26, .9));
}
.pm-perso-vide {
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center; font-size: 18px; color: var(--ink-faint);
  border: 1px dashed rgba(150, 168, 190, .3);
}
.pm-perso-nom {
  font-size: 9px; letter-spacing: .04em; color: var(--ink-dim);
  max-width: 60px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pm-perso.choisi {
  background: rgba(245, 185, 66, .1);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(255, 190, 77, .25), 0 0 14px rgba(255, 190, 77, .2);
}
.pm-perso.choisi .pm-perso-nom { color: var(--accent); }
/* La case qui renvoie a la Saison : les personnages a gagner (13/10/2026). */
.pm-perso-saison { border-style: dashed; border-color: rgba(245, 185, 66, .4); }
.pm-perso-saison .dl-rond { display: grid; place-items: center; }
.pm-perso-cadenas { font-family: var(--font-title); font-size: 15px; font-weight: 800; color: var(--accent-light); }
.pm-perso-saison .pm-perso-nom { color: var(--accent); }

/* LES SEPT TETES, MONTREES. Annoncer « sept humeurs » est une promesse ; les
   montrer est le contrat -- et celles qui manquent encore se voient. */
.pm-humeurs {
  display: flex; gap: 6px; overflow-x: auto; padding: 2px 2px 4px;
  scrollbar-width: thin;
}
.pm-humeur {
  flex: 0 0 auto; display: grid; justify-items: center; gap: 2px;
  font-size: 8px; letter-spacing: .04em; color: var(--ink-faint);
}
.pm-humeur .dl-rond {
  width: 34px; height: 34px;
  background: rgba(12, 16, 26, .6);
  border: 1px solid rgba(150, 168, 190, .2);
}
/* Une humeur pas encore dessinee montre le visage neutre : on l'ETEINT pour
   qu'elle ne se fasse pas passer pour une vraie. */
.pm-humeur.absente { opacity: .34; }
.pm-humeur.absente span { text-decoration: line-through; }

/* ══ LE PANNEAU DU DUEL, EN CELL-SHADING ═══════════════════════════════════
 *
 * Le panneau etait construit en matiere : un verre depoli (`backdrop-filter`),
 * deux degrades superposes, trois ombres internes et un halo. C'est le
 * vocabulaire d'un objet PHOTOGRAPHIE -- et il ne peut pas cohabiter avec une
 * table dont la lumiere tombe desormais par paliers : a cote d'un plateau
 * dessine, un panneau en verre se lit comme un element d'une autre image.
 *
 * CE QU'ON RETIRE, ET CE QUI LE REMPLACE :
 *
 *   . le FLOU d'arriere-plan. Il n'existe pas en dessin. Un aplat opaque
 *     remplit le meme office -- detacher le panneau du fond -- et il le fait
 *     mieux maintenant que le fond est un pavage contraste : le verre laissait
 *     transparaitre les cellules et le texte passait dessus ;
 *   . les DEGRADES de fond. Un aplat. C'est ce qui garde la couleur vive ;
 *   . les OMBRES FLOUES et le halo. Une ombre PORTEE NETTE, decalee, sans
 *     rayon de flou : le panneau est une decoupe posee sur l'image, et ce
 *     decalage franc est ce qui le dit. C'est le meme geste que le cerne des
 *     des -- du trait, pas de la lumiere ;
 *   . le FILET d'or a 42 % d'opacite devient un TRAIT PLEIN de deux pixels.
 *     Un cerne se voit ou n'existe pas ; a moitie transparent il faisait un
 *     bord sale plutot qu'un contour.
 *
 * Ces regles sont posees APRES celles qu'elles corrigent, a specificite egale :
 * les originales restent lisibles a leur place, avec leurs raisons d'alors. */

.game-module {
  border: 2px solid #e8b64a;
  border-radius: 3px;
  background: #14101c;
  box-shadow: 5px 6px 0 rgba(0, 0, 0, .55);
  backdrop-filter: none;
}
/* Le second filet, a l'interieur : plein lui aussi, mais plus sombre que le
   fond. Deux traits de meme couleur se lisent comme une bavure ; un trait
   clair puis un trait sombre se lisent comme une gorge. */
.game-module::before {
  inset: 6px;
  border: 1px solid #2c2338;
  border-radius: 1px;
}

.game-module .turn-info {
  border: 2px solid #3b3050;
  border-radius: 2px;
  background: #0d0a15;
}

/* Le filet de separation : il s'evanouissait a ses deux bouts. Un trait
   d'encre commence et s'arrete. */
.module-rule {
  height: 2px; margin: 2px 4px 12px;
  background: #74522f;
}

/* Le bouton : un aplat franc, un cerne sombre, et la meme ombre nette que le
   panneau -- il est POSE dessus, il ne rayonne pas. */
.module-end-turn {
  border: 2px solid #14101c;
  border-radius: 3px;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .5);
}
.module-end-turn:disabled {
  background: #221b30;
  border-color: #14101c;
  color: var(--ink-faint);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .35);
}

/* Les deux filets de l'intertitre : pleins, et de longueur franche. */
.prompt-kicker::before,
.prompt-kicker::after {
  height: 2px;
  background: #74522f;
}


/* ── LA FENETRE D'ACTION ──────────────────────────────────────────────────
   Le jeu ne disait jamais franchement ce qu'il attendait. Le lancer
   d'ouverture, par exemple, tenait dans un bandeau translucide fondu dans le
   haut de l'ecran : un titre gris sur un degrade noir, et un bouton qu'on
   trouvait par hasard. Ce n'etait pas une demande, c'etait un decor.

   Une demande a la forme d'une demande : un cadre pose sur la table, un
   intitule qui nomme la phase (« Choix du premier tour »), une consigne en
   clair, et le geste a faire sous forme de bouton. Rien d'autre. Quand il n'y
   a rien a faire -- c'est le tour d'en face --, le cadre reste et montre
   qu'on attend, plutot que de disparaitre et laisser croire a une table
   morte.

   Elle ne prend PAS les clics : seuls ses boutons en prennent. Elle couvre le
   haut du plateau, et une zone morte de 300 px de large au-dessus des tuiles
   se paierait a chaque tour. */
.action-window {
  /*  AU MILIEU DE LA TABLE, PAS DANS SON BORD.
   *
   *  Elle a d'abord ete posee en haut, centree horizontalement. Fondue dans le
   *  bord superieur de l'ecran, elle s'y lisait comme un bandeau de titre : on
   *  passait dessus sans la lire, ce qui etait exactement le defaut du panneau
   *  qu'elle remplacait. Et le seul moment ou elle parle est un moment ou le
   *  jeu s'arrete -- ce moment-la se joue au centre. */
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 47; pointer-events: none;
  width: min(420px, 76vw);
  animation: aw-entre .3s ease both;
  /* Le couloir des portraits est etroit : le titre s'y regle sur la LARGEUR DU
     CADRE, pas sur celle de l'ecran -- « Choix du premier tour » y tenait sur
     trois lignes. */
  container-type: inline-size;
}
@keyframes aw-entre {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.94); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.aw-cadre {
  position: relative;
  display: grid; justify-items: center; gap: 7px;
  padding: 20px 26px 22px;
  border-radius: 4px;
  border: 1px solid rgba(201, 162, 70, .42);
  /* Le meme parchemin sombre que les autres cartouches du duel : la fenetre
     appartient a l'arene, elle n'est pas une boite de dialogue du navigateur. */
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(201, 162, 70, .10), transparent 62%),
    linear-gradient(180deg, rgba(24, 19, 28, .96), rgba(12, 9, 15, .96));
  box-shadow:
    0 18px 44px rgba(0, 0, 0, .66),
    inset 0 1px 0 rgba(255, 232, 180, .10);
}
/* Les deux filets d'or du haut et du bas, comme sur les tuiles gravees. */
.aw-cadre::before, .aw-cadre::after {
  content: ''; position: absolute; left: 12px; right: 12px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(201, 162, 70, .55), transparent);
}
.aw-cadre::before { top: 4px; }
.aw-cadre::after { bottom: 4px; }
.aw-kicker {
  font-family: var(--font-title);
  font-size: 9.5px; font-weight: 800; letter-spacing: .34em;
  text-transform: uppercase; color: #c9a246;
}
.aw-titre {
  margin: 0; text-align: center;
  font-family: var(--font-title);
  font-size: 21px; font-weight: 800; letter-spacing: .04em;
  color: #f3e6c0;
  text-shadow: 0 0 18px rgba(201, 162, 70, .28);
  text-wrap: balance;
}
.aw-texte {
  margin: 0; text-align: center;
  text-wrap: balance;
  font-size: 12.5px; line-height: 1.5; color: var(--ink-dim);
  max-width: 34ch;
}
.aw-texte b { color: var(--accent); font-weight: 700; }
.aw-texte:empty { display: none; }
.aw-gestes { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 4px; }
.aw-gestes:empty { display: none; }
.aw-gestes button { white-space: nowrap; max-width: 100%; }
.aw-bouton {
  pointer-events: auto; cursor: pointer;
  padding: 9px 22px; border-radius: 999px;
  border: 1px solid rgba(201, 162, 70, .55);
  background: linear-gradient(#3a2c12, #1b1409);
  color: #f3e6c0; font-family: var(--font-title);
  font-size: 12px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .6);
  transition: border-color .18s ease, box-shadow .18s ease, filter .18s ease;
}
.aw-bouton:hover { border-color: var(--accent); box-shadow: 0 0 18px rgba(255, 190, 77, .35); }
/* Le geste PRINCIPAL respire : c'est celui qu'on attend, il doit se voir de
   l'autre bout de la table. */
.aw-bouton.majeur { animation: aw-pulse 2.2s ease-in-out infinite; }
.aw-bouton.majeur:hover { animation: none; }
@keyframes aw-pulse {
  0%, 100% { box-shadow: 0 8px 22px rgba(0, 0, 0, .6), 0 0 0 0 rgba(255, 190, 77, .0); }
  50%      { box-shadow: 0 8px 22px rgba(0, 0, 0, .6), 0 0 20px 3px rgba(255, 190, 77, .30); }
}
.aw-bouton.discret {
  background: linear-gradient(#241d2b, #14101a);
  border-color: rgba(201, 162, 70, .28); color: var(--ink-dim);
  letter-spacing: .12em;
}
/* L'ATTENTE A UNE FORME. Sans elle, « Ziggy joue... » est une phrase figee et
   rien ne distingue un adversaire qui reflechit d'une partie plantee. */
.aw-attente { display: flex; gap: 5px; margin-top: 2px; }
.aw-attente i {
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(201, 162, 70, .75);
  animation: aw-attente 1.15s ease-in-out infinite;
}
.aw-attente i:nth-child(2) { animation-delay: .16s; }
.aw-attente i:nth-child(3) { animation-delay: .32s; }
@keyframes aw-attente {
  0%, 100% { opacity: .22; transform: translateY(0); }
  40%      { opacity: 1; transform: translateY(-3px); }
}
/* Le tour d'en face : la fenetre se retire au second plan au lieu de crier. */
.action-window.veille .aw-cadre { border-color: rgba(140, 150, 170, .30); }
.action-window.veille .aw-kicker { color: #8c96aa; }
.action-window.veille .aw-titre { color: #cdd4e2; text-shadow: none; }

/* En portrait le haut de l'ecran est au pupitre : la fenetre se resserre et
   se pose juste sous lui. */
@media (max-width: 760px) {
  .action-window { width: min(340px, 88vw); }
  .aw-cadre { padding: 14px 16px 16px; }
  .aw-titre { font-size: 17px; }
  .aw-texte { font-size: 11.5px; }
}

/* Les reglages du cadre etroit viennent APRES les regles de base : poses
   avant, a specificite egale, ils etaient ecrases -- le titre gardait ses
   21 px dans un couloir de 280. */
@container (max-width: 300px) {
  .aw-cadre { padding: 13px 11px 15px; }
  .aw-titre { font-size: 15px; letter-spacing: .01em; line-height: 1.2; }
  .aw-texte { font-size: 11px; max-width: none; }
  .aw-kicker { font-size: 8.5px; letter-spacing: .22em; }
  .aw-bouton { padding: 8px 13px; font-size: 10.5px; letter-spacing: .1em; }
}
/* Deux gestes cote a cote ne tiennent pas dans un cadre etroit : « Continuer
   le duel » debordait du cadre et mordait sur le nom d'en face. On les
   empile, a la meme largeur, et le texte peut passer a la ligne plutot que
   sortir. */
@container (max-width: 360px) {
  .aw-gestes { flex-direction: column; align-items: stretch; width: 100%; }
  .aw-gestes button { white-space: normal; }
}

/* ══════════════════════════════════════════════════════════════════════════
   LE CARTABLE -- la collection rangee dans un classeur

   Tout part de deux nombres, `--ct-cols` et `--ct-rangs`, qui DOIVENT rester
   d'accord avec COLONNES/RANGEES dans cartable.js. Le reste -- proportion
   d'une face, d'une double-page, taille d'une pochette -- se calcule a
   partir d'eux : passer de 4x3 a 3x3 ne demande de toucher qu'a ces deux
   endroits.

   La feuille qui tourne est un vrai objet a deux faces (`preserve-3d`), pas
   un fondu : c'est la seule facon d'avoir un DOS.
   ══════════════════════════════════════════════════════════════════════════ */

body.collection-mode { overflow: hidden; }
body.collection-mode main { padding: 0; max-width: none; margin: 0; }
body.collection-mode #view-cartable.is-on { height: calc(100dvh - var(--topbar-h)); }

.cartable {
  --ct-cols: 4;
  --ct-rangs: 3;
  --ct-marge: clamp(10px, 1.1vw, 18px);   /* le blanc autour des pochettes */
  --ct-or: #c9a227;

  /*  LE CLASSEUR SE DETACHE DE LA SALLE, IL NE S'EN ARRACHE PAS.
      Un premier essai en papier ivoire a ete refuse : le meuble criait plus
      fort que les cartes, et les cartes manquantes, qu'il fallait bien
      eclaircir avec lui, devenaient des fantomes blancs illisibles. Le bon
      reglage est UN CRAN de gris au-dessus du fond, pas une inversion --
      juste assez pour qu'on voie ou finit la feuille et ou commence la
      piece. Les cartes, elles, gardent exactement le ton qu'elles avaient. */
  --ct-feuille: #2c2833;    /* le carton de la feuille               */
  --ct-feuille-b: #241f2b;  /* son ombre, vers le pli                */
  --ct-cuir: #3a3444;       /* la reliure, un cran au-dessus encore  */
  --ct-encre: rgba(201, 162, 39, .5);   /* ce qui s'ecrit dessus     */

  /*  LA GEOMETRIE DU MEUBLE, en un seul endroit. La reliure se calcule a
      partir d'elles (voir `.cart-reliure`) : ce qui prend de la place a cote
      ou sous le classeur doit etre declare ici, sinon il deborde. */
  --ct-bord: clamp(10px, 1.25vw, 20px);          /* le cuir autour des pages */
  --ct-fleche: clamp(34px, 3.4vw, 52px);
  --ct-ecart: clamp(6px, 1vw, 16px);
  --ct-ong: clamp(38px, 3.1vw, 54px);            /* largeur d'une languette  */
  --ct-cotes: calc(2 * (var(--ct-fleche) + var(--ct-ecart)) + var(--ct-ong) + 10px);
  --ct-sous: 0px;                                /* ce qui pend sous le cuir */
  /*  Hauteur sur largeur du CONTENU de la reliure : deux faces cote a cote. */
  --ct-ratio: calc(var(--ct-rangs) * 1610 / (2 * var(--ct-cols) * 1024));

  height: 100%;
  display: flex; flex-direction: column;
  min-height: 0;
  /*  Une lampe au-dessus du bureau : le classeur est dans la lumiere, la
      piece tombe dans l'ombre autour de lui. */
  background:
    radial-gradient(60% 55% at 50% 52%, rgba(255, 196, 120, .07), transparent 70%),
    radial-gradient(120% 90% at 50% -10%, rgba(201, 162, 39, .10), transparent 60%),
    linear-gradient(180deg, #0b0910 0%, #07060b 100%);
}
/*  LE CUIR DU CLASSEUR OUVERT, un par classeur -- meme teinte que sa
    couverture sur l'etagere. Texture raccordable cuite par
    card-render/fabriquer_cuir_classeur.py ; la couleur de repli est celle du
    cuir moyen, au cas ou l'image manquerait. */
.cartable-corps { --ct-cuir-img: url("https://medias.kairostcg.com/classeurs/cuir_Creature.webp"); --ct-cuir-fond: #3a1612; }
.cartable-corps[data-classeur="Lieu"]  { --ct-cuir-img: url("https://medias.kairostcg.com/classeurs/cuir_Lieu.webp");  --ct-cuir-fond: #142a1d; }
.cartable-corps[data-classeur="Piege"] { --ct-cuir-img: url("https://medias.kairostcg.com/classeurs/cuir_Piege.webp"); --ct-cuir-fond: #12172b; }
.cartable-corps[data-classeur="Effet"] { --ct-cuir-img: url("https://medias.kairostcg.com/classeurs/cuir_Effet.webp"); --ct-cuir-fond: #2c1430; }

/* ── La tete : les filtres qui MONTENT le classeur ───────────────────── */
.cartable-tete {
  flex: none;
  display: flex; align-items: center; gap: 18px;
  flex-wrap: wrap;
  padding: 9px clamp(12px, 2vw, 28px);
  border-bottom: 1px solid rgba(201, 162, 39, .18);
  background: linear-gradient(180deg, rgba(20, 14, 26, .92), rgba(11, 9, 16, .75));
  backdrop-filter: blur(6px);
}
.cartable-titre { display: flex; align-items: center; gap: 10px; min-width: 180px; }
.cartable-titre .ct-ico { font-size: 24px; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .6)); }
.ct-mots { display: flex; flex-direction: column; line-height: 1.25; }
.ct-mots b {
  font-family: var(--font-title, inherit);
  font-size: 16px; letter-spacing: .06em; color: var(--ink, #ece6f5);
}
.ct-mots small { font-size: 11.5px; color: var(--ink-faint, #8d86a0); }

.cartable-outils {
  flex: 1 1 460px; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
}
.ct-replier { display: none; }
.ct-cherche { flex: 0 1 220px; }
/*  Ces trois listes viennent du panneau lateral de l'atelier, ou elles sont
    EMPILEES parce qu'une colonne est etroite. Ici la tete est une bande :
    elles se couchent. Il faut le dire explicitement -- `flex-wrap` seul
    n'annule pas un `flex-direction: column` herite. */
.cartable-outils .f-els,
.cartable-outils .seg,
.cartable-outils .f-rars {
  display: flex; flex-flow: row wrap; gap: 5px;
  width: auto; max-width: none;
}
.cartable-outils .f-el,
.cartable-outils .f-rar,
.cartable-outils .seg > button {
  width: auto; flex: 0 0 auto;
  padding: 4px 9px; font-size: 11.5px; white-space: nowrap;
}
.cartable-outils .f-rar small { display: none; }
.ct-bascules { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.ct-tri {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--ink-faint, #8d86a0);
}
.ct-tri select {
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(201, 162, 39, .28);
  color: var(--ink, #ece6f5);
  border-radius: 8px; padding: 5px 9px; font: inherit; font-size: 12px;
}

/* ── Le corps : le meuble ────────────────────────────────────────────── */
.cartable-corps {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; align-items: center;
  gap: 10px;
  padding: clamp(10px, 1.8vh, 24px) clamp(8px, 1.6vw, 26px) 14px;
  outline: none;
}
.cartable-scene {
  flex: 1; min-height: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
  gap: var(--ct-ecart);
  perspective: 2600px;
  perspective-origin: 50% 44%;
  /*  La scene est un CONTENEUR : la reliure se mesure a elle dans les deux
      sens (`cqw`, `cqh`), et non plus a sa seule hauteur. */
  container-type: size;
}

/*  LA RELIURE EST LA COUVERTURE DE CUIR.
 *
 *  Le cuir est sa BORDURE : en `content-box`, `aspect-ratio` ne porte que sur
 *  le contenu -- les pages gardent exactement la proportion des cartes -- et
 *  le cuir s'ajoute autour sans rien leur prendre.
 *
 *  SA TAILLE SE CALCULE DANS LES DEUX SENS. Elle etait `height: 100%` avec
 *  `max-width: 100%` : quand la place manquait en largeur, la largeur etait
 *  bornee mais la hauteur restait, et la proportion cassait -- les onglets se
 *  retrouvaient alors loin du bord. On prend maintenant le plus petit des
 *  deux : toute la hauteur, ou toute la largeur qui reste une fois fleches et
 *  onglets places. */
.cart-reliure {
  position: relative;
  flex: none;
  box-sizing: content-box;
  height: min(
    calc(100cqh - 2 * var(--ct-bord) - var(--ct-sous)),
    calc((100cqw - var(--ct-cotes) - 2 * var(--ct-bord)) * var(--ct-ratio)));
  /* Une face fait `cols` cartes de large pour `rangs` de haut, une carte
     mesurant 1024 x 1610 : la double-page vaut donc deux faces cote a cote. */
  aspect-ratio: calc(2 * var(--ct-cols) * 1024) / calc(var(--ct-rangs) * 1610);
  max-width: none;
  /*  La place des onglets, qui pendent hors de la boite. */
  margin-right: var(--ct-ong);
  margin-bottom: var(--ct-sous);
  /*  Le glissement horizontal appartient au classeur (il tourne la page,
      voir cartable.js) : sans cela le navigateur le prend pour un
      defilement et annule le geste. */
  touch-action: pan-y;
  display: grid; grid-template-columns: 1fr 1fr;
  transform-style: preserve-3d;
  border: var(--ct-bord) solid transparent;
  border-radius: 14px;
  background:
    /* le cuir s'assombrit vers les bords, comme un cuir manie */
    radial-gradient(130% 120% at 50% 45%, transparent 55%, rgba(0, 0, 0, .45)) border-box,
    var(--ct-cuir-img) 0 0 / 256px 256px repeat border-box,
    var(--ct-cuir-fond) border-box;
  /*  L'EPAISSEUR DU CARTON. Une couverture a une tranche : la bande sombre
      sous le bord bas (et un peu a droite) est le carton recouvert de cuir,
      vu de biais. C'est elle qui pose le classeur SUR le bureau. */
  box-shadow:
    1px 2px 0 0 color-mix(in srgb, var(--ct-cuir-fond) 70%, #000),
    2px 5px 0 0 color-mix(in srgb, var(--ct-cuir-fond) 45%, #000),
    3px 7px 0 0 rgba(0, 0, 0, .55),
    0 46px 80px -10px rgba(0, 0, 0, .9),
    0 20px 34px -12px rgba(0, 0, 0, .75);
}
/*  LE BOURRELET. Le cuir est tendu sur un carton aux bords arrondis : la
    lumiere de la lampe (en haut a gauche) accroche l'arete du haut, l'arete
    du bas tombe dans l'ombre, et le cuir se creuse la ou les pages
    s'enfoncent. Sans ce relief, ce n'etait qu'une texture posee a plat.
    Ce calque est peint SOUS les pages : seul le cuir le voit. */
.cart-reliure::before {
  content: '';
  position: absolute;
  inset: calc(var(--ct-bord) * -1);
  border-radius: 14px;
  pointer-events: none;
  box-shadow:
    inset 0 2px 1px -1px rgba(255, 230, 200, .38),
    inset 0 calc(var(--ct-bord) * .45) calc(var(--ct-bord) * .5) calc(var(--ct-bord) * -.3) rgba(255, 220, 180, .12),
    inset 2px 0 2px -1px rgba(255, 230, 200, .18),
    inset 0 -3px 3px -1px rgba(0, 0, 0, .7),
    inset 0 calc(var(--ct-bord) * -.5) calc(var(--ct-bord) * .6) calc(var(--ct-bord) * -.3) rgba(0, 0, 0, .5),
    inset -3px 0 4px -2px rgba(0, 0, 0, .6);
  background:
    /* la lampe : un reflet large et doux sur le haut de la couverture */
    radial-gradient(70% 40% at 35% 0%, rgba(255, 220, 170, .10), transparent 70%);
}
/*  LA COUTURE : un point sellier dore, a mi-cuir, tout autour -- avec son
    ombre, parce qu'un fil est POSE sur le cuir. */
.cart-reliure::after {
  content: '';
  position: absolute;
  inset: calc(var(--ct-bord) * -.5 - 1px);
  border: 1.5px dashed rgba(226, 190, 110, .62);
  border-radius: 10px;
  pointer-events: none;
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .8));
}

/* Une page : le plastique de la pochette, pose sur le carton du classeur. */
.cart-page,
.cart-face {
  /*  Le grain du carton : un bruit fin, a peine visible -- assez pour que la
      feuille soit une matiere et plus un aplat. */
  --ct-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 .07 0 0 0 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background:
    /* le plastique de la feuille prend la lampe en une large diagonale */
    linear-gradient(112deg, transparent 28%, rgba(255, 255, 255, .045) 44%, transparent 58%),
    linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012)),
    var(--ct-grain),
    linear-gradient(160deg, var(--ct-feuille) 0%, var(--ct-feuille-b) 100%);
}
.cart-page {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  padding: var(--ct-marge);
  cursor: pointer;
}
/*  LA TRANCHE DES FEUILLES. Sous chaque page, le bord des feuilles empilees
    depasse sur le cuir -- epais du cote qu'il reste a lire, mince du cote
    deja lu. `--ct-lu` (0 a 1) est pose par cartable.js a chaque vue. */
.cart-page--g::before,
.cart-page--d::before {
  content: '';
  position: absolute; top: 3px; bottom: 3px;
  pointer-events: none;
  background: repeating-linear-gradient(90deg, #4a4352 0 1px, #1b1721 1px 2.5px);
  box-shadow: 0 0 4px rgba(0, 0, 0, .6);
}
.cart-page--g::before {
  right: 100%;
  width: calc(1px + var(--ct-lu, 0) * var(--ct-bord) * .55);
  border-radius: 3px 0 0 3px;
}
.cart-page--d::before {
  left: 100%;
  width: calc(1px + (1 - var(--ct-lu, 0)) * var(--ct-bord) * .55);
  border-radius: 0 3px 3px 0;
}
/* Une feuille se creuse vers le pli : c'est cette ombre-la, et elle seule,
   qui donne l'epaisseur du classeur. */
/*  La page est POSEE sur le cuir : son ombre tombe dessus -- mais JAMAIS du
    cote du pli. Une ombre tout autour debordait d'un ou deux pixels sur
    l'autre moitie du dos ; tant que la page de droite etait peinte apres,
    on ne la voyait pas, mais la page levee sous une carte tenue
    (`.a-la-main`) passe devant, et une ligne noire coupait le dos au survol
    (signale le 03/10/2026). Chaque ombre est donc decalee vers l'exterieur,
    avec un etalement negatif egal au decalage : rien n'atteint le pli. */
.cart-page--g {
  border-radius: 8px 2px 2px 8px;
  box-shadow:
    inset -28px 0 40px -25px rgba(0, 0, 0, .92),
    inset 0 1px 0 rgba(255, 255, 255, .06),
    -1px 0 0 0 rgba(0, 0, 0, .5),
    0 -1px 0 0 rgba(0, 0, 0, .5),
    0 1px 0 0 rgba(0, 0, 0, .5),
    -4px 4px 8px -4px rgba(0, 0, 0, .75);
}
.cart-page--d {
  border-radius: 2px 8px 8px 2px;
  box-shadow:
    inset 28px 0 40px -25px rgba(0, 0, 0, .92),
    inset 0 1px 0 rgba(255, 255, 255, .06),
    1px 0 0 0 rgba(0, 0, 0, .5),
    0 -1px 0 0 rgba(0, 0, 0, .5),
    0 1px 0 0 rgba(0, 0, 0, .5),
    4px 4px 8px -4px rgba(0, 0, 0, .75);
}
.cart-page.est-vide {
  background: var(--ct-grain), linear-gradient(160deg, #262230, #1c1826);
  cursor: default;
}

.cart-grille {
  width: 100%; height: 100%;
  display: grid;
  grid-template-columns: repeat(var(--ct-cols), 1fr);
  grid-template-rows: repeat(var(--ct-rangs), 1fr);
  gap: clamp(5px, .55vw, 11px);
}

/* La pochette : un logement de plastique, vide ou garni. */
.cart-poche {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  border-radius: 6px;
  /*  UNE POCHETTE A LA FORME D'UNE CARTE, PAS CELLE DE SA CASE.
   *
   *  La case de grille naissait de la place restante : mesuree a 119 x 193,
   *  soit 3,1 % plus ETROITE qu'une carte. `object-fit: cover` rognait donc
   *  la carte sur ses deux cotes -- le liseré de rarete y passait, et c'est
   *  ce qu'on voyait. Pire, les calques poses par-dessus (vernis, filigrane)
   *  reperent leurs fenetres en pourcentage de cette boite : une boite a la
   *  mauvaise forme les decale tous.
   *
   *  La LARGEUR commande, la hauteur suit : la case est toujours plus haute
   *  que large une fois la proportion retablie, donc rien ne deborde. Le
   *  reste de la hauteur devient du jeu autour de la pochette -- ce qu'une
   *  vraie feuille a aussi. */
  aspect-ratio: 1024 / 1610;
  width: 100%; height: auto;
  align-self: center;
  background: rgba(255, 255, 255, .05);
  /*  Le plastique : un liseré, l'ouverture de la pochette qui accroche la
      lumiere en haut, et le fond qui se creuse en bas. */
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .09),
    inset 0 2px 0 -1px rgba(255, 255, 255, .16),
    inset 0 -6px 10px -8px rgba(0, 0, 0, .8),
    0 1px 0 rgba(0, 0, 0, .35);
  /*  PAS DE `overflow: hidden` ICI.
      C'est ce qui coupait la carte agrandie au survol : elle grandissait a
      l'interieur d'une boite qui la rognait, et on ne voyait qu'un morceau.
      Le rayon des coins est porte par la vitre et par le reflet, qui en ont
      besoin ; la pochette, elle, laisse passer. */
  transform-style: preserve-3d;
}
/* Une carte penchee passe par-dessus ses voisines, jamais dessous. */
.cart-poche:hover { z-index: 8; }

/*  ... ET PAR-DESSUS LE PLI.
    Lever la carte ne suffit pas : les deux pages sont deux cases de grille,
    et une carte de la page gauche qui grandit vers le pli reste enfermee
    dans SA page -- la page de droite, peinte apres, la coupait net au milieu
    du classeur, et la reliure par-dessus. C'est donc la PAGE qu'on leve, et
    la classe est posee par cartable.js sur celle qui porte la carte tenue. */
.cart-page.a-la-main { z-index: 12; }
.cart-anneaux { z-index: 2; }
/* Une pochette vide se voit au CREUX, pas a la couleur : le plastique y est
   simplement plus mat, et l'ombre du fond transparait. */
.cart-poche.est-libre {
  background:
    repeating-linear-gradient(135deg,
      rgba(255, 255, 255, .025) 0 7px, transparent 7px 14px),
    rgba(0, 0, 0, .26);
}
/*  PAS DE CONTOUR AUTOUR D'UNE CARTE RANGEE.
    `cf--print` se donne un fond noir, un rayon de 14px et un halo blanc a
    un pixel -- utiles en galerie, ou une carte flotte sur le vide. Dans une
    pochette, ce fond depasse de l'image aux quatre coins et dessine un
    cerne noir entre la carte et le plastique. Une carte rangee touche sa
    pochette : rien entre les deux. */
/*  LA VITRE : la carte et le verre de sa pochette, d'un seul tenant.
    C'est elle qui porte l'inclinaison -- voir `allumerLesVitres` dans
    cartable.js. Au repos elle est parfaitement plate et ne coute rien. */
.cart-vitre {
  position: absolute; inset: 0;
  display: flex;
  border-radius: 5px;
  transform-style: preserve-3d;
  transition: transform .2s cubic-bezier(0.16, 1, 0.3, 1);
}

/*  ON RECOUPE LA MARGE NOIRE DU RENDU.
 *
 *  Chaque carte rendue porte une bande noire de 1,37 % sur ses quatre cotes
 *  -- mesuree, identique sur toutes les raretes et tous les elements. Elle
 *  vient de `flat_view(margin=1.03)`, qui cadre 3 % plus large que la carte :
 *  le fond est bien transparent au rendu, mais le PNG est ecrit en RGB et la
 *  transparence s'effondre en noir. Sur une feuille claire, ca se lit comme
 *  un cerne autour de la carte.
 *
 *  LA DECOUPE VA SUR LES ENFANTS, PAS SUR LA VITRE. Deux raisons :
 *    . un `clip-path` coupe aussi l'OMBRE PORTEE de l'element -- pose sur la
 *      vitre, il effacait la lueur de rarete de la carte tenue ;
 *    . carte, filigrane et verre se rognent alors du MEME pas, donc sans se
 *      desaligner. Rogner la seule image les decalerait toutes de 1,4 %,
 *      puisque les fenetres mates se reperent en pourcentage de cette boite.
 *
 *  La vraie correction serait au rendu -- ecrire les cartes en RGBA, ou
 *  cadrer sans marge. Elle coute un re-rendu des 1374 cartes ; celle-ci ne
 *  coute rien et donne le meme resultat a l'ecran.
 */
.cart-vitre > * {
  clip-path: inset(var(--carte-marge, 1.4%) round 4px);
  transform: scale(var(--carte-retaille, 1.03));
}

.cart-vitre.est-tenue {
  transform:
    perspective(760px)
    rotateX(var(--tx, 0deg)) rotateY(var(--ty, 0deg))
    scale(1.12) translateZ(22px);
  z-index: 9;
}
/*  AUCUN ANNEAU AUTOUR D'UNE CARTE TENUE.
    La carte imprimee a deja son propre liseré blanc : tout ce qu'on ajoute
    au ras du bord se lit comme un cerne etranger. Le halo noir precedent en
    dessinait un, franc, sur les quatre cotes. L'ombre est donc DECALEE et
    rentree (etalement negatif) pour ne jamais toucher l'arete, et la seule
    couleur qui reste est celle de la rarete, en lueur. */
.cart-vitre.est-tenue {
  box-shadow:
    0 26px 44px -18px rgba(0, 0, 0, .8),
    0 0 26px -4px color-mix(in srgb, var(--rc, #c9a227) 45%, transparent);
}

.cart-poche .cf {
  width: 100%; height: 100%;
  cursor: pointer;
  background: transparent;
  border-radius: 5px;
  box-shadow: none;
  transition: transform .2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow .22s ease;
}
.cart-poche .cf img { width: 100%; height: 100%; object-fit: cover; }
/*  Repli sans JavaScript : si les vitres ne sont pas allumees, le survol
    seul souleve encore la carte. Sans cela, plus rien ne repondrait. */
.cart-poche:hover .cart-vitre:not(.est-tenue) { transform: scale(1.08); }

/*  UNE CARTE MANQUANTE RESTE VISIBLE.
    Un classeur ou les trous sont des cases blanches ne donne envie de rien :
    on voit l'ombre de la carte qu'on n'a pas, et c'est ce creux qui fait
    ouvrir un booster. */
.cart-poche.est-manquante .cf {
  filter: grayscale(1) brightness(.34) contrast(1.15);
  opacity: .62;
}
.cart-poche.est-manquante:hover .cf {
  filter: grayscale(.75) brightness(.5);
  opacity: .85;
}
.cart-poche.est-manquante::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(60% 60% at 50% 45%, transparent, rgba(0, 0, 0, .45));
  pointer-events: none;
}

/* Le reflet du plastique : une seule diagonale, discrete, par-dessus tout. */
/*  LE VERRE DE LA POCHETTE : le plastique, et rien d'autre.
    Une diagonale fixe dans le coin, comme une vitre prend la lumiere de la
    piece. Il ne suit PAS le pointeur : une nappe blanche qui balayait toute
    la carte lavait l'illustration au lieu de la faire briller. */
.cart-reflet {
  position: absolute; inset: 0; pointer-events: none;
  border-radius: 5px;
  background: linear-gradient(118deg,
    rgba(255, 255, 255, .13) 0%,
    rgba(255, 255, 255, .03) 24%,
    transparent 44%);
  mix-blend-mode: screen;
}

/*  LE FILIGRANE QUI ACCROCHE LA LUMIERE
 *
 *  Ce qui brille sur une vraie carte quand on la penche, ce sont les sigles
 *  imprimes -- pas la carte. Une lumiere posee dessus, quelle que soit sa
 *  forme ou son mode de fusion, eclaire le FOND avant les sigles : elle se
 *  lit comme une tache. Il faut donc leur DECOUPE, et elle ne se devine pas
 *  depuis l'image -- la trame est cuite dans le PNG par Blender (card_bg.py,
 *  style « filigrane »). On la lui demande : card-render/filigranes.py la
 *  rend en six images, une par element.
 *
 *  DEUX DECOUPES SUPERPOSEES, PARCE QU'IL EN FAUT DEUX :
 *
 *    . `--decoupe` (calque exterieur) -- le contour de la carte moins tout
 *      ce qui se lit : illustration, pave d'actions, pastille. La trame de
 *      Blender couvre toute la face, y compris SOUS l'illustration qui la
 *      cache a l'impression ; sans cette decoupe on allumerait des sigles
 *      invisibles par-dessus le dessin. C'est la decoupe DU VERNIS, prise a
 *      la meme source (`decoupeDe` dans vernis.js) : la lumiere du filigrane
 *      s'arrete exactement ou celle du vernis s'arrete.
 *
 *    . `--fili` (calque interieur) -- le masque rendu par Blender, etire sur
 *      la carte entiere. Meme camera, meme cadrage, meme geometrie : il se
 *      recale a (0, 0), verifie sur les six elements et quatre raretes.
 *
 *  Et parce qu'on ne peint QUE sur les sigles, `screen` convient : il n'y a
 *  pas de fond plat a laver, seulement des glyphes a allumer.
 */
.cart-filigrane {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease;
  /*  PAS DE `clip-path` SUR CE CALQUE.
   *  Il en portait un (la decoupe), ce qui ECRASAIT le recadrage de la marge
   *  noire herite de son parent : le calque n'etait plus rogne comme la
   *  carte, et la decoupe tombait 1,4 % a cote. Le recadrage reste donc ici,
   *  et la decoupe descend d'un etage -- deux decoupes, deux elements. */
}
.cart-vitre.est-tenue .cart-filigrane { opacity: 1; }

/*  PAS DE TRAME, PAS DE CALQUE.
 *  Les cartes d'Energie n'appartiennent a aucun element : elles n'ont pas de
 *  filigrane imprime, et `--fili` reste vide. Sans ce garde, un `mask-image`
 *  absent laisse TOUT passer -- le calque s'allumerait en entier, ce qui est
 *  exactement la tache qu'on cherche a eviter. */
.cart-filigrane > i { display: none; }

/*  LA LUMIERE VIENT DE L'INCLINAISON, PAS DU CURSEUR.
 *
 *  Une tache ronde posee sous le pointeur, c'est une lampe de poche : elle
 *  DESIGNE un endroit, et elle n'eclairait que le bas de la carte. Une carte
 *  penchee, elle, prend la lumiere de la piece sur toute sa surface, en
 *  bandes paralleles qui la balaient d'un bord a l'autre -- c'est l'angle
 *  qui fait tout.
 *
 *  D'ou la meme construction que `.vernis-iris` : un degrade REPETE oriente
 *  par `--ang`, sur un fond plus grand que la carte, dont la position glisse
 *  avec `--mx` / `--my`. On ne voit donc jamais ou la bande commence ni ou
 *  elle finit. Les deux brillances d'une meme carte lisent la meme formule
 *  d'angle : elles bougent ensemble, comme deux reflets d'une seule lumiere.
 */
.cart-vitre[style*="--fili"] .cart-filigrane > i {
  display: block;
  position: absolute; inset: 0;
  clip-path: var(--decoupe, none);
  /*  LEGER. Le filigrane est imprime a 0,12 de force pour « disparaitre
      presque a plat et ne revivre qu'au reflet » (card_bg.py) : un reflet
      qui le rend franc dit le contraire de la carte. A .85 les sigles
      devenaient un motif a part entiere ; a .32 ils passent, et c'est tout
      ce qu'on leur demande. */
  background: repeating-linear-gradient(
    calc(var(--ang, 90) * 1deg),
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, .07) 9%,
    rgba(255, 255, 255, .32) 16%,
    rgba(255, 255, 255, .07) 23%,
    rgba(255, 255, 255, 0) 34%,
    rgba(255, 255, 255, 0) 62%);
  /*  UNE SEULE TUILE, JAMAIS REPETEE.
   *
   *  `background-repeat` vaut `repeat` par defaut. La tuile fait 220 % de la
   *  carte : au bord, le degrade est tranche la ou il en est et la tuile
   *  suivante repart a zero -- une ligne droite en travers des sigles, que
   *  l'oeil lit tout de suite comme un defaut d'impression.
   *
   *  Avec `no-repeat`, le deplacement doit rester dans 0-100 % : la tuile
   *  etant plus grande que la carte, elle la couvre alors a toute position.
   *  A 170 % elle sortait du cadre et laissait un bord sans lumiere. Meme
   *  reglage que `.vr-carte` plus bas, qui avait deja ete corrige. */
  background-size: 220% 220%;
  background-repeat: no-repeat;
  background-position: calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: screen;
  -webkit-mask-image: var(--fili);
  mask-image: var(--fili);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/*  LE FILIGRANE DE LA CARTE DE BOOSTER.
 *
 *  Meme construction que `.cart-filigrane` du classeur, et pour la meme
 *  raison : c'est le meme objet, decouvert a un autre moment. Un degrade
 *  REPETE oriente par `--ang`, sur un fond plus grand que la carte, dont la
 *  position glisse avec `--mx` / `--my` -- on ne voit donc jamais ou la bande
 *  commence ni ou elle finit. Le masque est la trame rendue par Blender, la
 *  decoupe celle du vernis : la lumiere s'arrete ou le vernis s'arrete.
 *
 *  Elle ne s'allume que sur une carte RETOURNEE : un dos n'a pas de filigrane,
 *  et l'allumer pendant le vol dirait quelque chose de la carte avant qu'on
 *  l'ait vue.
 */
.bc-filigrane {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease;
}
.reveal-card-slot.is-flipped:hover .bc-filigrane { opacity: 1; }
/*  Pas de trame, pas de calque : sans `--fili`, un `mask-image` absent laisse
    TOUT passer et le calque s'allumerait en entier. */
.bc-filigrane > i { display: none; }
.card-face-front[style*="--fili"] .bc-filigrane > i {
  display: block;
  position: absolute; inset: 0;
  clip-path: var(--decoupe, none);
  background: repeating-linear-gradient(
    calc(var(--ang, 90) * 1deg),
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, .07) 9%,
    rgba(255, 255, 255, .32) 16%,
    rgba(255, 255, 255, .07) 23%,
    rgba(255, 255, 255, 0) 34%,
    rgba(255, 255, 255, 0) 62%);
  /*  UNE SEULE TUILE, JAMAIS REPETEE.
   *
   *  `background-repeat` vaut `repeat` par defaut. La tuile fait 220 % de la
   *  carte : au bord, le degrade est tranche la ou il en est et la tuile
   *  suivante repart a zero -- une ligne droite en travers des sigles, que
   *  l'oeil lit tout de suite comme un defaut d'impression.
   *
   *  Avec `no-repeat`, le deplacement doit rester dans 0-100 % : la tuile
   *  etant plus grande que la carte, elle la couvre alors a toute position.
   *  A 170 % elle sortait du cadre et laissait un bord sans lumiere. Meme
   *  reglage que `.vr-carte` plus bas, qui avait deja ete corrige. */
  background-size: 220% 220%;
  background-repeat: no-repeat;
  background-position: calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: screen;
  -webkit-mask-image: var(--fili);
  mask-image: var(--fili);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
/*  ET LE GESTE SE DIT. Une carte retournee s'ouvre en grand au clic
    (`openCard`) -- rien ne l'annoncait, et personne ne clique sur une carte
    qui vient deja de se retourner au clic. */
.reveal-card-slot.is-flipped { cursor: zoom-in; }

.cart-folio {
  position: absolute; bottom: 3px;
  font-size: 10px; letter-spacing: .12em;
  color: var(--ct-encre);
  pointer-events: none;
}
.cart-page--g .cart-folio { left: 12px; }
.cart-page--d .cart-folio { right: 12px; }

/* ── Le pli, au milieu ───────────────────────────────────────────────
   Des anneaux dessines au trait ont ete essayes ici : a la taille reelle
   d'une double-page, six cercles vides flottant sur la gouttiere ne
   ressemblaient pas a de la quincaillerie, juste a des ronds. Ce qui fait
   lire un classeur, c'est le PLI -- une reliure sombre et l'ombre que les
   deux pages y jettent. Le reste etait du decor qui n'expliquait rien. */
.cart-anneaux { display: none; }
/*  PENDANT LE TOUR, LE DOS PASSE DEVANT LA FEUILLE.
 *
 *  La feuille qui tourne pivote exactement sur le pli et se couchait sur la
 *  moitie du dos d'en face : le cuir du centre disparaissait sous le papier
 *  le temps du geste (signale le 03/10/2026). Le temps du geste seulement,
 *  le dos est donc redessine par-dessus, a l'identique des deux moitiees
 *  portees par les pages -- memes boites, memes fonds, aucun saut a
 *  l'apparition.
 *
 *  Il est avance d'un cheveu (`translateZ`) : la reliure est en
 *  `preserve-3d`, ou la profondeur decide avant le z-index. Pres du pli, la
 *  feuille est sous ce plan et passe SOUS le dos ; en se levant elle passe
 *  devant. C'est exactement une page qui sort de sa reliure. Hors du geste
 *  il reste cache : avance en permanence, il couperait une carte tenue
 *  (voir l'ancienne note sur le `translateZ` du pli, plus haut). */
.cartable-corps.tourne .cart-anneaux {
  display: block;
  position: absolute; left: 50%; width: calc(var(--ct-marge) * 1.7);
  top: calc(var(--ct-bord) * -1); bottom: calc(var(--ct-bord) * -1);
  transform: translateX(-50%) translateZ(3px);
  z-index: 7;
  pointer-events: none;
  background: none; box-shadow: none;
}
.cartable-corps.tourne .cart-anneaux::before,
.cartable-corps.tourne .cart-anneaux::after {
  content: '';
  position: absolute; top: 0; bottom: 0; width: 50%;
  --nervures: repeating-linear-gradient(180deg,
      transparent 0 calc(16.66% - 7px),
      rgba(0, 0, 0, .55) calc(16.66% - 7px) calc(16.66% - 5px),
      rgba(255, 225, 190, .16) calc(16.66% - 5px) calc(16.66% - 3px),
      rgba(0, 0, 0, .35) calc(16.66% - 3px) 16.66%);
}
.cartable-corps.tourne .cart-anneaux::before {
  left: 0;
  background:
    var(--nervures),
    linear-gradient(90deg, rgba(0, 0, 0, .85), rgba(0, 0, 0, .25) 60%, rgba(255, 220, 180, .12)),
    var(--ct-cuir-img, none) right top / 256px 256px,
    var(--ct-cuir-fond, #2a2018);
  box-shadow: -6px 0 10px -4px rgba(0, 0, 0, .7);
}
.cartable-corps.tourne .cart-anneaux::after {
  right: 0;
  background:
    var(--nervures),
    linear-gradient(270deg, rgba(0, 0, 0, .85), rgba(0, 0, 0, .25) 60%, rgba(255, 220, 180, .12)),
    var(--ct-cuir-img, none) left top / 256px 256px,
    var(--ct-cuir-fond, #2a2018);
  box-shadow: 6px 0 10px -4px rgba(0, 0, 0, .7);
}
/*  LE DOS, EN CUIR -- EN DEUX MOITIES, UNE PAR PAGE.
 *
 *  Le pli etait un trait sombre : on voyait que les pages s'arretaient, pas
 *  ce qui les tenait. C'est maintenant le cuir de la couverture, bombe
 *  (clair au milieu, sombre la ou les pages plongent) et barre de nervures,
 *  comme le dos d'un livre relie.
 *
 *  CHAQUE PAGE PORTE SA MOITIE. Pose d'un seul tenant par-dessus la
 *  gouttiere, le dos etait recouvert par la page qu'on LEVE sous une carte
 *  tenue (`.a-la-main`, z-index 12) : survoler une carte de gauche mangeait
 *  la moitie du dos et la page semblait grossir (signale le 03/10/2026). En
 *  deux moities, la page levee n'emporte que la sienne, qui reste a sa
 *  place ; et la carte tenue, plus haute dans la page, passe toujours
 *  par-dessus. */
.cart-page--g::after,
.cart-page--d::after {
  content: '';
  position: absolute;
  top: calc(var(--ct-bord) * -1); bottom: calc(var(--ct-bord) * -1);
  width: calc(var(--ct-marge) * .85);
  pointer-events: none;
  z-index: 1;
  --nervures: repeating-linear-gradient(180deg,
      transparent 0 calc(16.66% - 7px),
      rgba(0, 0, 0, .55) calc(16.66% - 7px) calc(16.66% - 5px),
      rgba(255, 225, 190, .16) calc(16.66% - 5px) calc(16.66% - 3px),
      rgba(0, 0, 0, .35) calc(16.66% - 3px) 16.66%);
}
.cart-page--g::after {
  right: 0;
  background:
    var(--nervures),
    linear-gradient(90deg, rgba(0, 0, 0, .85), rgba(0, 0, 0, .25) 60%, rgba(255, 220, 180, .12)),
    var(--ct-cuir-img, none) right top / 256px 256px,
    var(--ct-cuir-fond, #2a2018);
  box-shadow: -6px 0 10px -4px rgba(0, 0, 0, .7);
}
.cart-page--d::after {
  left: 0;
  background:
    var(--nervures),
    linear-gradient(270deg, rgba(0, 0, 0, .85), rgba(0, 0, 0, .25) 60%, rgba(255, 220, 180, .12)),
    var(--ct-cuir-img, none) left top / 256px 256px,
    var(--ct-cuir-fond, #2a2018);
  box-shadow: 6px 0 10px -4px rgba(0, 0, 0, .7);
}


/* ── La feuille qui tourne ───────────────────────────────────────────── */
.cart-feuille {
  position: absolute; top: 0; bottom: 0; width: 50%;
  transform-style: preserve-3d;
  /* 1,1 s : assez lent pour voir la feuille se courber (Alexandre, 03/10/2026). */
  transition: transform 1.1s cubic-bezier(0.42, 0, 0.28, 1);
  will-change: transform;
  z-index: 6;
}
.cart-feuille--d { left: 50%; transform-origin: left center; }
.cart-feuille--g { left: 0; transform-origin: right center; }

/*  LES BANDES DE LA FEUILLE QUI SE COURBE (voir BANDES dans cartable.js).
 *
 *  La premiere bande occupe 1/n de la feuille, collee au pli ; chacune des
 *  suivantes est l'ENFANT de la precedente, posee contre son bord libre et
 *  pivotant sur lui. Elles gardent toutes `preserve-3d` : c'est ce qui laisse
 *  leurs angles s'additionner. */
.cart-bande {
  position: absolute; top: 0; bottom: 0;
  width: calc(100% / var(--n, 6));
  transform-style: preserve-3d;
}
.cart-bande .cart-bande { width: 100%; }
.cart-feuille--d > .cart-bande { left: 0; }
.cart-feuille--d .cart-bande .cart-bande { left: 100%; }
.cart-feuille--d .cart-bande { transform-origin: left center; }
.cart-feuille--g > .cart-bande { right: 0; }
.cart-feuille--g .cart-bande .cart-bande { right: 100%; }
.cart-feuille--g .cart-bande { transform-origin: right center; }

/*  Un morceau : une fenetre plate sur la face entiere. Un demi-pixel de
    recouvrement entre voisins, sinon la jointure se voit en biais. */
.cart-morceau {
  position: absolute; top: 0; bottom: 0; left: -.5px; right: -.5px;
  overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.cart-morceau--dos { transform: rotateY(180deg); }
.cart-morceau > .cart-face {
  position: absolute; top: 0; bottom: 0;
  width: calc(var(--n, 6) * 100%);
  left: calc(var(--k, 0) * -100%);
}
/*  L'ombre de la courbe : la bande qui se detourne de la lampe s'assombrit.
    Son opacite est animee par cartable.js, avec la courbure. */
.cart-pli-ombre {
  position: absolute; inset: 0;
  /*  Du bord cote pli au bord libre : les forces sont posees par
      cartable.js pour que deux bandes voisines se raccordent sans marche. */
  background: linear-gradient(var(--sens, 90deg),
    rgba(0, 0, 0, var(--o-pli, 0)), rgba(0, 0, 0, var(--o-bord, 0)));
  opacity: 0;
  pointer-events: none;
}
.cart-face {
  display: flex; align-items: center; justify-content: center;
  padding: var(--ct-marge);
  box-sizing: border-box;
}

/* Pendant qu'une feuille tourne, on ne clique plus rien : sinon deux gestes
   se chevauchent et le classeur saute une feuille. */
.cartable-corps.tourne .cart-page,
.cartable-corps.tourne .cart-fleche { pointer-events: none; }

/* ── Les fleches ─────────────────────────────────────────────────────── */
.cart-fleche {
  flex: none;
  width: clamp(34px, 3.4vw, 52px); height: clamp(64px, 12vh, 110px);
  display: grid; place-items: center;
  font-size: clamp(26px, 2.6vw, 38px); line-height: 1;
  color: rgba(201, 162, 39, .85);
  background: linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015));
  border: 1px solid rgba(201, 162, 39, .25);
  border-radius: 12px;
  cursor: pointer;
  transition: background .2s ease, transform .2s ease, opacity .2s ease;
}
.cart-fleche:hover:not(:disabled) {
  background: rgba(201, 162, 39, .18);
  transform: scale(1.06);
}
.cart-fleche:disabled { opacity: .22; cursor: default; }

/* ── Le pied : ou on en est dans le classeur ─────────────────────────── */
.cart-pied {
  flex: none;
  display: flex; align-items: center; gap: 16px;
  width: min(720px, 92%);
}
.cart-compteur {
  flex: none; font-size: 12px; letter-spacing: .06em;
  color: var(--ink-faint, #8d86a0);
}
.cart-curseur { flex: 1; accent-color: var(--ct-or); min-width: 0; }
.cart-curseur:disabled { opacity: .3; }

/*  L'ombre de la feuille du dessus sur celle d'en dessous, dans la pile du
    telephone (voir `empiler`). Toujours absolue : enfant de la reliure, qui
    est une grille, elle y prendrait sinon une case. */
.cart-voile {
  position: absolute; inset: 0; z-index: 5;
  border-radius: 8px;
  background: #050308;
  opacity: 0;
  pointer-events: none;
}

/* ── Ecrans etroits : le classeur perd sa double-page ─────────────────
   Un cartable a deux pages parce qu'un bureau est large. Sur un telephone
   il n'y a la place que d'une : on n'ecrase pas les cartes pour garder une
   metaphore, on montre une face a la fois -- et la feuille tourne pareil. */
@media (orientation: portrait) and (max-width: 1100px), (max-width: 900px) and (min-height: 501px) {
  /*  QUATRE DE LARGE, TROIS DE HAUT. Douze pochettes par face dans les deux
   *  cas, donc la pagination ne bouge pas -- mais une face plus large que
   *  haute epouse mieux l'espace disponible, et chaque carte y gagne un tiers
   *  de largeur. C'est aussi la disposition du bureau : une seule facon de
   *  ranger, quel que soit l'ecran. */
  .cartable {
    --ct-cols: 4; --ct-rangs: 3;
    --ct-ratio: calc(var(--ct-rangs) * 1610 / (var(--ct-cols) * 1024));
    /*  LES FLECHES ONT LEUR COULOIR. Posees sur la page, elles cachaient le
        bord des cartes de la premiere et de la derniere colonne (03/10/2026).
        Plus fines, elles prennent chacune un couloir que la reliure leur
        laisse : `--ct-cotes` le retire a sa largeur. */
    --ct-fleche-e: clamp(22px, 3.6vw, 34px);
    --ct-cotes: calc(2 * var(--ct-fleche-e) + 8px);
    /* Les languettes pendent SOUS le cuir, a l'horizontale. */
    --ct-ong-h: 50px;
    --ct-sous: calc(var(--ct-ong-h) + 4px);
  }
  .cart-reliure {
    aspect-ratio: calc(var(--ct-cols) * 1024) / calc(var(--ct-rangs) * 1610);
    grid-template-columns: 1fr;
    margin-right: 0;
  }
  .cart-page--g, .cart-anneaux, .cart-page--d::after,
  .cartable-corps.tourne .cart-anneaux { display: none; }

  /*  TROIS DE LARGE, QUATRE DE HAUT, QUAND LA PLACE EST HAUTE.
   *  Sur un grand telephone debout, la face en 4 x 3 se mesurait a la
   *  LARGEUR et laissait une bande vide dessus et dessous. Quand la scene
   *  est nettement plus haute que large, 3 x 4 donne des cartes plus grandes
   *  (+7 % sur un iPhone 390 x 844, +13 % sur un 430 x 932) ; sur un petit
   *  ecran (iPhone SE), 4 x 3 reste meilleur. Toujours douze pochettes : la
   *  pagination ne bouge pas, seul le CSS choisit. Les variables sont posees
   *  sur la reliure, premiere descendante de la scene (le conteneur). */
  @container (max-aspect-ratio: 2 / 3) {
    .cart-reliure {
      --ct-cols: 3; --ct-rangs: 4;
      --ct-ratio: calc(4 * 1610 / (3 * 1024));
    }
    /* L'anneau devient un hexagone debout, toujours Feu en haut et dans le
       sens des aiguilles. Prefixe `.cart-reliure` : les places de 4 x 3 sont
       ecrites plus loin dans la feuille et gagneraient a egalite. */
    .cart-reliure .cart-grille--anneau .cart-poche:nth-child(1) { grid-area: 1 / 2; }
    .cart-reliure .cart-grille--anneau .cart-poche:nth-child(2) { grid-area: 2 / 3; }
    .cart-reliure .cart-grille--anneau .cart-poche:nth-child(3) { grid-area: 3 / 3; }
    .cart-reliure .cart-grille--anneau .cart-poche:nth-child(4) { grid-area: 4 / 2; }
    .cart-reliure .cart-grille--anneau .cart-poche:nth-child(5) { grid-area: 3 / 1; }
    .cart-reliure .cart-grille--anneau .cart-poche:nth-child(6) { grid-area: 2 / 1; }
    .cart-reliure .cart-grille--anneau::before { left: 14%; right: 14%; }
  }
  .cart-page--d { border-radius: 8px; box-shadow: none; }
  .cart-feuille { width: 100%; }
  .cart-feuille--d { left: 0; transform-origin: left center; }

  /*  LA PILE (voir `empiler` dans cartable.js). Une face seule ne tourne
      pas sur un pli qu'elle n'a pas : la feuille du dessus glisse de cote,
      la suivante sort de son ombre. Le doigt pilote le glissement : le
      navigateur ne doit garder que le defilement vertical. */
  .cart-reliure { touch-action: pan-y; }
  .cart-feuille--pile {
    left: 0; width: 100%;
    transform-style: flat;
    transition: none;
    /* Le pivot sous la feuille : elle part comme poussee du pouce. */
    transform-origin: 50% 115%;
    /* Elle passe SOUS les fleches (z-index 40) : elles restent fixes,
       toujours visibles (Alexandre, 03/10/2026). */
    border-radius: 8px;
    box-shadow: 0 16px 34px -6px rgba(0, 0, 0, .7), 0 0 0 1px rgba(0, 0, 0, .45);
  }
  .cart-feuille--pile > .cart-face {
    position: absolute; inset: 0;
    border-radius: 8px;
  }

  .cartable-tete { gap: 10px; padding: 8px 12px; }
  .cartable-titre { min-width: 0; flex: 1; }
  /*  LES FILTRES SE REPLIENT.
      Deplies, ils mangeaient la moitie de l'ecran et il ne restait plus de
      place pour la feuille -- or on vient ici pour REGARDER des cartes. */
  /*  Le bouton vit dans l'en-tete, jamais dans la bande : place dedans, il
   *  se repliait avec elle et plus rien ne pouvait la rouvrir. */
  .cartable-titre .ct-replier { display: inline-flex; flex: none; }
  body.ct-filtres-ouverts .cartable-titre .ct-replier {
    color: #ffe3a0; box-shadow: inset 0 0 0 1px rgba(255, 210, 140, .5);
  }
  .cartable-outils { display: none; }

  /*  LES FILTRES SE POSENT PAR-DESSUS, ILS NE POUSSENT PLUS.
   *
   *  Deplies, ils prenaient 116 px dans le flux : la scene perdait d'un coup
   *  un quart de sa hauteur, et comme la reliure est contrainte par la
   *  HAUTEUR -- une face fait 3 cartes sur 4, donc plus haute que large --
   *  les cartes retrecissaient d'autant. On venait regarder des cartes et
   *  ouvrir un filtre les rapetissait.
   *
   *  En panneau flottant, la feuille garde sa taille : on choisit sa rarete,
   *  on referme, et rien n'a bouge dessous. */
  /*  LE REPLI ETAIT MORT. `.cartable-outils { display: none }` ne pesait pas
   *  assez : la regle `#view-cartable .ct-bande { display: flex }`, ecrite
   *  plus loin et portant un identifiant, gagnait a tous les coups. La bande
   *  restait donc DEPLIEE en permanence au telephone, le bouton « Filtres »
   *  ne faisait plus rien, et ses 116 px etaient pris sur la feuille. D'ou
   *  le selecteur double ci-dessous, qui passe devant. */
  #view-cartable .cartable-outils.ct-bande { display: none; }
  body.ct-filtres-ouverts #view-cartable .cartable-outils.ct-bande {
    display: flex;
    /*  `bottom: auto` n'est pas decoratif : une autre regle pose
     *  `bottom: 62px`, et un bloc absolu dont le haut ET le bas sont fixes a
     *  sa hauteur IMPOSEE -- le panneau sortait haut de 23 px, ses filtres
     *  debordant dans le vide. */
    position: absolute; left: 0; right: 0; top: 100%; bottom: auto; z-index: 30;
    max-height: 46vh; overflow-y: auto;
    padding: 10px 12px 12px;
    background: linear-gradient(180deg, rgba(18, 16, 26, .98), rgba(12, 10, 18, .98));
    border-bottom: 1px solid rgba(255, 220, 150, .18);
    box-shadow: 0 18px 30px rgba(0, 0, 0, .6);
  }
  .cartable-tete { position: relative; }

  /*  ON REPREND LA HAUTEUR PARTOUT OU ELLE NE SERT A RIEN : chaque pixel
   *  rendu au corps devient de la carte visible. */
  .cartable-corps { padding: 6px 6px 6px; gap: 6px; }
  .cart-pied { padding-top: 2px; }

  /*  LES FLECHES PASSENT SUR LA PAGE. Posees a cote, elles prenaient
   *  quatre-vingt-dix pixels de large pour ne rien montrer. */
  .cartable-scene { position: relative; gap: 0; }
  /*  Les fleches passent PAR-DESSUS la feuille : posees a cote, elles
   *  prenaient quatre-vingt-dix pixels de large ; passees dessous, elles
   *  disparaissaient derriere les cartes. Au-dessus et translucides, elles
   *  ne coutent rien et restent trouvables. */
  .cartable-scene > .cart-fleche,
  .cartable-scene > button:not(.cart-reliure) {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 40;
    width: var(--ct-fleche-e); min-width: 0; margin: 0;
    font-size: clamp(20px, 3.4vw, 30px);
    opacity: .82; backdrop-filter: blur(3px);
    background: rgba(12, 10, 18, .55);
    border: 1px solid rgba(255, 220, 150, .22);
  }
  .cartable-scene > button:not(.cart-reliure):first-child { left: 0; }
  .cartable-scene > button:not(.cart-reliure):last-child { right: 0; }
  /*  LES FLECHES NE BOUGENT PAS (Alexandre, 03/10/2026). Au doigt, `:hover`
   *  reste colle apres un tap, et son `scale(1.06)` remplacait le
   *  `translateY(-50%)` qui les centre : la fleche sautait d'une demi-hauteur
   *  a chaque appui. Et la feuille de la pile glisse DESSOUS. */
  .cartable-scene > .cart-fleche:hover:not(:disabled),
  .cartable-scene > .cart-fleche:active { transform: translateY(-50%); }
  .cartable-scene > .cart-fleche { transition: background .2s ease, opacity .2s ease; }
}

/* ══ LE DECK GRATUIT ═══════════════════════════════════════════════════════
   
   La ceremonie reutilise les classes du booster pour le retournement et les
   lueurs de rarete (.reveal-card-slot, .reveal-card-3d, .card-face, .glow-*).
   Ce bloc ne fait que deux choses : poser l'ecran, et REDIMENSIONNER les
   cartes -- sept a 184 px tiennent sur une rangee, quarante non. */
.dg-fond {
  position: fixed; inset: 0; z-index: 3000;
  background: rgba(4, 6, 11, 0.94);
  backdrop-filter: blur(14px);
  display: flex; align-items: flex-start; justify-content: center;
  overflow-y: auto; padding: 3rem 1.5rem;
  opacity: 0; transition: opacity .26s ease;
}
.dg-fond.is-on { opacity: 1; }
.dg-boite {
  position: relative; width: 100%; max-width: 1080px;
  transform: translateY(14px); transition: transform .32s cubic-bezier(.16,1,.3,1);
}
.dg-fond.is-on .dg-boite { transform: none; }
.dg-fermer {
  position: absolute; top: -.6rem; right: 0;
  background: none; border: 0; color: var(--ink-faint);
  font-size: 1.3rem; cursor: pointer; padding: .4rem .6rem; line-height: 1;
}
.dg-fermer:hover { color: var(--accent-light); }

.dg-tete { text-align: center; margin-bottom: 2rem; }
.dg-kicker {
  font-family: var(--font-title); font-size: .72rem; font-weight: 700;
  letter-spacing: .3em; color: var(--accent-dark); text-transform: uppercase;
}
.dg-titre {
  font-family: var(--font-title); font-weight: 900;
  font-size: clamp(1.8rem, 5vw, 2.6rem); margin: .4rem 0 .6rem;
  background: var(--gold-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.dg-sous { color: var(--ink-dim); max-width: 40rem; margin: 0 auto; font-size: .95rem; }

/* Le choix des elements */
.dg-elements {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: .8rem; max-width: 46rem; margin: 0 auto;
}
.dg-el {
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  padding: 1.3rem .8rem; cursor: pointer;
  background: rgba(16, 21, 34, .8);
  border: 1px solid var(--line); border-radius: 12px;
  color: var(--ink-dim); transition: all .18s ease;
}
.dg-el:hover { border-color: var(--el); transform: translateY(-2px); }
.dg-el.is-on {
  border-color: var(--el); color: var(--ink-bright);
  background: color-mix(in srgb, var(--el) 16%, rgba(16, 21, 34, .9));
  box-shadow: 0 0 0 1px var(--el), 0 10px 26px -12px var(--el);
}
.dg-el-glyphe {
  /* MEME ICONE QUE PARTOUT AILLEURS. Le PNG est pose en masque et teinte par
     la couleur de l'element, comme dans le coffret et sur la Roue : un joueur
     qui a vu le Feu ici le reconnait a la table. */
  display: block; width: 34px; height: 34px; background: var(--el);
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
}
.dg-el-nom {
  font-family: var(--font-title); font-weight: 700; font-size: .82rem;
  letter-spacing: .1em; text-transform: uppercase;
}

/* Les classes, facultatives, et l'avis « ce choix n'est pas definitif » */
.dg-classes { max-width: 46rem; margin: 1.6rem auto 0; text-align: center; }
.dg-sous-titre {
  font-family: var(--font-title); font-size: .72rem; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase; color: var(--ink-faint);
  margin-bottom: .6rem;
}
.dg-classes-rang { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }
.dg-classe {
  min-height: 40px; padding: 0 1.1rem; cursor: pointer;
  background: rgba(16, 21, 34, .8); color: var(--ink-dim);
  border: 1px solid var(--line); border-radius: 999px;
  font-family: var(--font-title); font-weight: 700; font-size: .8rem; letter-spacing: .08em;
  transition: all .18s ease;
}
.dg-classe:hover { border-color: var(--accent); color: var(--ink-bright); }
.dg-classe.is-on {
  border-color: var(--accent); color: var(--ink-bright);
  background: color-mix(in srgb, var(--accent) 18%, rgba(16, 21, 34, .9));
}
.dg-classes-note { color: var(--ink-faint); font-size: .8rem; margin: .6rem auto 0; max-width: 34rem; }
.dg-avis {
  max-width: 40rem; margin: 1.4rem auto 0; padding: .8rem 1rem;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 10px; background: rgba(16, 21, 34, .7);
  color: var(--ink-dim); font-size: .88rem; text-align: center;
}
.dg-avis b { color: var(--accent-light); }
.dg-rendues { color: var(--ink-faint); font-size: .85rem; }
.dg-relancer { min-height: 50px; }

/* Les cartes pretees */
.dg-cartes {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 12px; perspective: 1600px; margin: 0 auto;
}
.dg-slot { width: var(--dg-l); height: var(--dg-h); border-radius: 9px; }
.dg-slot .card-face { border-radius: 9px; }
.dg-slot .card-face-front img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dg-sans-art {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  padding: .5rem; text-align: center; font-size: .68rem; color: var(--ink-dim);
  background: var(--bg-3);
}

.dg-pied {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 1rem; margin-top: 2rem; padding-bottom: 1rem;
}
.dg-note { color: var(--ink-dim); font-size: .9rem; margin: 0; flex-basis: 100%; text-align: center; }
.dg-note b { color: var(--accent-light); }
.dg-go:disabled { opacity: .4; cursor: not-allowed; }
@media (max-width: 640px) {
  .dg-fond { padding: 1.5rem .8rem; }
  .dg-cartes { gap: 8px; }
}
/*  LE BOUTON RESTE SOUS LE POUCE. Pose apres quarante cartes, « Jouer » etait
    a six ecrans de defilement : on ne le trouvait pas. Le pied colle au bas
    de la fenetre, et la partie se lance d'un geste. */
.dg-pied {
  position: sticky; bottom: -3rem; z-index: 5;
  margin: 1.5rem -1.5rem -3rem; padding: 1rem 1.5rem calc(1rem + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(180deg, rgba(4, 6, 11, 0), rgba(4, 6, 11, .96) 26%);
}
.dg-pied .dg-go { min-height: 50px; padding: 0 28px; font-size: 16px; }
.dg-atelier { min-height: 50px; }
.dg-slot { position: relative; }
.dg-qte {
  position: absolute; top: -6px; right: -6px; z-index: 3;
  min-width: 26px; height: 22px; padding: 0 6px; border-radius: 999px;
  background: var(--gold-grad); color: #1a1202;
  font: 800 12px/22px var(--font-num, sans-serif); text-align: center;
  box-shadow: 0 0 0 2px #05070c;
}
@media (max-width: 640px) {
  .dg-tete { margin-bottom: 1rem; }
  .dg-sous { font-size: .85rem; }
  .dg-cartes.dg-lu, .dg-cartes {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 6px;
  }
  .dg-cartes .dg-slot { width: auto; height: auto; aspect-ratio: 1024 / 1610; }
  .dg-pied { margin: 1rem -.8rem -1.5rem; padding: .8rem .8rem calc(.8rem + env(safe-area-inset-bottom, 0px)); bottom: -1.5rem; gap: .6rem; }
  .dg-note { font-size: .8rem; }
  .dg-avis { font-size: .8rem; }
}

/* ── La ceremonie du deck prete, en trois temps (27/09/2026) ────────────────
   Le choix s'anime, le deck prend forme au centre, se dissout comme la pile
   du grimoire, et les cartes paraissent a leur place. Les classes de lumiere
   (.gerbe-paquet, .eclat-paquet, .traits-paquet, .carte-sceau, .parait) sont
   celles du grimoire ; ce bloc ne pose que ce qui est propre au deck prete. */

/* Les ecrans entrent et sortent : le choix s'efface avant que le deck prenne
   forme, la donne entre quand la pile a disparu. */
.dg-scene.dg-entre { animation: dgSceneEntre .45s cubic-bezier(.16, 1, .3, 1) both; }
.dg-scene.dg-sort  { animation: dgSceneSort .42s cubic-bezier(.5, 0, .75, 0) both; pointer-events: none; }
.dg-scene.dg-revele .dg-tete, .dg-scene.dg-revele .dg-bilan, .dg-scene.dg-revele .dg-barre {
  animation: dgSceneEntre .5s cubic-bezier(.16, 1, .3, 1) .15s both;
}
@keyframes dgSceneEntre {
  0%   { opacity: 0; transform: translateY(12px); }
  100% { opacity: 1; transform: none; }
}
@keyframes dgSceneSort {
  0%   { opacity: 1; transform: none; filter: none; }
  100% { opacity: 0; transform: scale(.96); filter: blur(6px); }
}

/* Les tuiles d'element : elles entrent une a une, s'allument au survol,
   et le choix part en anneau. */
.dg-el {
  position: relative; overflow: hidden; isolation: isolate;
  animation: dgElEntre .55s cubic-bezier(.2, .8, .3, 1) calc(var(--i, 0) * 65ms + 120ms) backwards;
}
@keyframes dgElEntre {
  0%   { opacity: 0; transform: translateY(16px) scale(.94); }
  100% { opacity: 1; transform: none; }
}
.dg-el::before {
  /* La lumiere de l'element, qui monte du bas de la tuile. */
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 110%, color-mix(in srgb, var(--el) 55%, transparent), transparent 62%);
  opacity: 0; transition: opacity .3s ease;
}
.dg-el:hover::before { opacity: .55; }
.dg-el.is-on::before { opacity: 1; animation: dgElSouffle 2.6s ease-in-out infinite; }
@keyframes dgElSouffle {
  0%, 100% { opacity: .75; }
  50%      { opacity: 1; }
}
.dg-el::after {
  /* Un reflet qui traverse la tuile choisie, de temps en temps. */
  content: ""; position: absolute; inset: -20% auto -20% -60%; width: 40%; z-index: 1;
  pointer-events: none; opacity: 0;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .28), transparent);
  transform: skewX(-18deg);
}
.dg-el.is-on::after { animation: dgReflet 3.2s ease-in-out 0.4s infinite; }
@keyframes dgReflet {
  0%   { left: -60%; opacity: 0; }
  8%   { opacity: 1; }
  30%  { left: 130%; opacity: 0; }
  100% { left: 130%; opacity: 0; }
}
.dg-el-glyphe, .dg-el-nom { position: relative; z-index: 2; }
.dg-el-glyphe { transition: transform .25s cubic-bezier(.2, .8, .3, 1), filter .25s ease; }
.dg-el:hover .dg-el-glyphe { transform: translateY(-3px) scale(1.08); }
.dg-el.is-on .dg-el-glyphe {
  filter: drop-shadow(0 0 8px var(--el-clair)) drop-shadow(0 0 2px var(--el-clair));
  transform: scale(1.12);
}
.dg-el.vient .dg-el-glyphe { animation: dgGlyphePop .5s cubic-bezier(.2, .9, .3, 1.4); }
@keyframes dgGlyphePop {
  0%   { transform: scale(.8); }
  55%  { transform: scale(1.35); }
  100% { transform: scale(1.12); }
}
.dg-el-anneau {
  position: absolute; left: 50%; top: 42%; width: 70px; height: 70px; margin: -35px;
  border-radius: 50%; border: 2px solid var(--el-clair); z-index: 1;
  box-shadow: 0 0 16px var(--el); opacity: 0; pointer-events: none;
}
.dg-el.vient .dg-el-anneau { animation: dgAnneau .7s cubic-bezier(.15, .85, .3, 1) both; }
@keyframes dgAnneau {
  0%   { opacity: .95; transform: scale(.3); }
  100% { opacity: 0; transform: scale(2.6); }
}
.dg-elements.a-choisi .dg-el:not(.is-on) { opacity: .7; }
.dg-elements.a-choisi .dg-el:not(.is-on):hover { opacity: 1; }

.dg-classe { transition: all .18s ease, transform .25s cubic-bezier(.2, .9, .3, 1.4); }
.dg-classe.vient { animation: dgPop .38s cubic-bezier(.2, .9, .3, 1.4); }
@keyframes dgPop {
  0%   { transform: scale(.92); }
  60%  { transform: scale(1.08); }
  100% { transform: none; }
}

/* Le bouton qui reclame : un reflet court dedans des qu'il est pret, dans la
   couleur du premier element choisi. */
.dg-go { position: relative; overflow: hidden; }
.dg-reclamer:not(:disabled)::after, .dg-barre .dg-go::after {
  content: ""; position: absolute; top: -30%; bottom: -30%; left: -40%; width: 30%;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, var(--reflet, #fff6e2), transparent);
  opacity: .75; transform: skewX(-20deg); mix-blend-mode: soft-light;
  animation: dgBoutonReflet 2.8s ease-in-out infinite;
}
@keyframes dgBoutonReflet {
  0%   { left: -40%; }
  45%  { left: 120%; }
  100% { left: 120%; }
}
.dg-reclamer:not(:disabled) { animation: dgBoutonPret .6s cubic-bezier(.2, .9, .3, 1.4); }
@keyframes dgBoutonPret {
  0%   { transform: scale(.94); }
  60%  { transform: scale(1.05); }
  100% { transform: none; }
}
.dg-reclamer.en-attente { animation: dgAttente 1s ease-in-out infinite; }
@keyframes dgAttente {
  0%, 100% { box-shadow: 0 4px 14px rgba(245, 185, 66, .35); }
  50%      { box-shadow: 0 4px 26px rgba(245, 185, 66, .8); }
}

/* 1. LE DECK PREND FORME. Un calque par-dessus l'ecran : l'anneau des
   elements tourne, les dos volent des tuiles vers la pile. */
.dg-forge {
  position: fixed; inset: 0; z-index: 3500; pointer-events: none;
  opacity: 0; transition: opacity .3s ease;
}
.dg-forge.is-on { opacity: 1; }
.dg-forge.part { opacity: 0; transition-duration: .5s; }
.dg-forge-anneau {
  position: fixed; width: var(--taille, 280px); height: var(--taille, 280px);
  margin: calc(var(--taille, 280px) / -2);
  border-radius: 50%;
  background: conic-gradient(from 0deg, var(--t1), var(--t2), var(--t3), var(--t1));
  -webkit-mask: radial-gradient(circle, transparent 58%, #000 61%, #000 64%, transparent 70%);
  mask: radial-gradient(circle, transparent 58%, #000 61%, #000 64%, transparent 70%);
  filter: blur(1.5px) drop-shadow(0 0 12px var(--t1));
  animation: dgAnneauNait .9s cubic-bezier(.16, 1, .3, 1) both, dgTourne 3.2s linear infinite;
}
.dg-forge-anneau::after {
  /* Le halo au coeur de l'anneau : la lumiere qui va dissoudre le deck. */
  content: ""; position: absolute; inset: 18%; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--t1) 45%, transparent), transparent 70%);
}
.dg-forge-anneau.se-dissout { animation: dgAnneauPart .7s ease-in both, dgTourne 1s linear infinite; }
@keyframes dgAnneauNait {
  0%   { opacity: 0; transform: scale(.4) rotate(-90deg); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes dgAnneauPart {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.6); }
}
@keyframes dgTourne { to { rotate: 360deg; } }

.dg-forge-pile { position: fixed; transform: translate(-50%, -50%); }
.dg-forge-pile img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  /* Le dos prete n'est pas detoure : ses coins noirs sont rognes ici. */
  border-radius: 7% / 4.5%;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .55);
  -webkit-mask-image: linear-gradient(to top, transparent 0 48%, #000 60% 100%);
  mask-image: linear-gradient(to top, transparent 0 48%, #000 60% 100%);
  -webkit-mask-size: 100% 300%; mask-size: 100% 300%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 0 8%; mask-position: 0 8%;
}
.dg-forge-pile.recoit { animation: dgPileRecoit .22s ease-out; }
@keyframes dgPileRecoit {
  0%   { transform: translate(-50%, -50%) scale(1); }
  40%  { transform: translate(-50%, -50%) scale(1.035); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
.dg-forge-pile.se-charge { animation: pileCharge .5s ease-in both; }
.dg-forge-pile.se-dissout img {
  animation: pileSeDissout .66s cubic-bezier(.4, 0, .75, .35) both;
}
.dg-forge-pile.se-dissout .pile-lame {
  animation: lameMonte .66s cubic-bezier(.4, 0, .75, .35) both;
}
.dg-volant {
  position: fixed; aspect-ratio: 1024 / 1610; height: auto;
  border-radius: 7% / 4.5%;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 18px var(--teinte, #f0d9a0);
  animation: dgVole 560ms cubic-bezier(.45, 0, .25, 1) both;
}
@keyframes dgVole {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.35) rotate(0deg); filter: brightness(2.4); }
  18%  { opacity: 1; }
  70%  { filter: brightness(1.3); }
  100% {
    opacity: 1;
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(var(--ech, 1.6)) rotate(var(--rot, 0deg));
    filter: none;
  }
}
.dg-forge-legende {
  position: fixed; left: 0; right: 0; text-align: center;
  font-family: var(--font-title); font-weight: 700; font-size: .8rem;
  letter-spacing: .3em; text-transform: uppercase; color: var(--accent-light);
  text-shadow: 0 0 12px rgba(245, 185, 66, .6);
  animation: dgSceneEntre .5s ease .3s both, dgLegende 1.6s ease-in-out .8s infinite;
}
.dg-forge-legende.part { opacity: 0; transition: opacity .3s ease; animation: none; }
@keyframes dgLegende {
  0%, 100% { opacity: 1; }
  50%      { opacity: .55; }
}

/* 3. LA BARRE DU HAUT. Elle colle au haut de l'ecran pendant qu'on defile :
   la consigne et « Tout retourner » d'abord, les quatre choix ensuite. */
.dg-barre {
  position: sticky; top: -3rem; z-index: 6;
  margin: 0 -1.5rem 1.4rem; padding: 3.1rem 1.5rem .9rem;
  background: linear-gradient(180deg, rgba(4, 6, 11, .97) 72%, rgba(4, 6, 11, 0));
}
.dg-consigne, .dg-actions {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .8rem 1rem;
}
.dg-message { margin: 0; color: var(--ink-dim); font-size: .92rem; text-align: center; }
.dg-message b { color: var(--accent-light); }
.dg-compteur {
  min-width: 4.2rem; padding: 0 .7rem; height: 30px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent);
  font: 700 .82rem/1 var(--font-num, var(--font-title)); color: var(--accent-light);
  font-variant-numeric: tabular-nums;
}
.dg-tout { min-height: 46px; padding: 0 26px; font-size: 15px; position: relative; overflow: hidden; }
.dg-barre.est-prete .dg-tout:not(:disabled) { animation: dgBoutonPret .6s cubic-bezier(.2, .9, .3, 1.4); }
.dg-barre.est-prete .dg-tout:not(:disabled)::after {
  content: ""; position: absolute; top: -30%; bottom: -30%; left: -40%; width: 30%;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, #fff6e2, transparent);
  opacity: .8; transform: skewX(-20deg); mix-blend-mode: soft-light;
  animation: dgBoutonReflet 2.4s ease-in-out infinite;
}
/* Les choix n'existent pas avant la fin : une couche cachee garderait sa
   hauteur, et au telephone la consigne flottait sous un grand vide. */
.dg-actions { display: none; }
.dg-actions > button { min-height: 48px; }
.dg-actions .dg-go { padding: 0 28px; font-size: 16px; }
.dg-barre.est-fini .dg-consigne { display: none; }
.dg-barre.est-fini .dg-actions { display: flex; }
.dg-barre.est-fini .dg-actions > button {
  animation: dgSceneEntre .45s cubic-bezier(.16, 1, .3, 1) backwards;
}
.dg-barre.est-fini .dg-actions > button:nth-child(2) { animation-delay: .06s; }
.dg-barre.est-fini .dg-actions > button:nth-child(3) { animation-delay: .12s; }
.dg-barre.est-fini .dg-actions > button:nth-child(4) { animation-delay: .18s; }
.dg-bilan { margin: -1rem auto 1rem; max-width: 46rem; }

/* Le retournement : un rai qui balaie la carte, des etincelles de son element,
   l'onde qui traverse la grille, et un eclat d'or quand tout est retourne. */
.dg-cartes { position: relative; }
.dg-rai {
  position: absolute; inset: 0; z-index: 4; pointer-events: none;
  border-radius: 9px; overflow: hidden;
}
.dg-rai::before {
  content: ""; position: absolute; top: -20%; bottom: -20%; left: -70%; width: 55%;
  background: linear-gradient(100deg, transparent, rgba(255, 246, 226, .85), transparent);
  transform: skewX(-16deg); opacity: 0;
}
.dg-slot.balaye .dg-rai::before { animation: dgRai .6s ease-out both; }
@keyframes dgRai {
  0%   { left: -70%; opacity: 0; }
  20%  { opacity: 1; }
  100% { left: 130%; opacity: 0; }
}
.dg-etincelle {
  position: absolute; left: 50%; top: 50%; z-index: 5; pointer-events: none;
  width: 5px; height: 5px; margin: -2.5px; border-radius: 50%;
  background: var(--c); box-shadow: 0 0 8px var(--c);
  animation: dgEtincelle .75s cubic-bezier(.2, .7, .3, 1) both;
}
@keyframes dgEtincelle {
  0%   { opacity: 0; transform: translate(0, 0) scale(.4); }
  15%  { opacity: 1; transform: translate(calc(var(--dx) * .2), calc(var(--dy) * .2)) scale(1.3); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.2); }
}
.dg-onde {
  position: absolute; z-index: 5; pointer-events: none;
  width: var(--portee, 1200px); height: var(--portee, 1200px);
  margin: calc(var(--portee, 1200px) / -2);
  border-radius: 50%;
  background: radial-gradient(circle, transparent 60%, rgba(255, 214, 140, .22) 67%, rgba(255, 246, 226, .55) 69.5%, transparent 71%);
  animation: dgOnde 1.25s cubic-bezier(.3, .2, .4, 1) both;
}
@keyframes dgOnde {
  0%   { opacity: 0; transform: scale(.02); }
  10%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1); }
}
.dg-cartes.est-complet .dg-slot.is-flipped {
  animation: dgComplet 1.2s ease-out both;
}
@keyframes dgComplet {
  0%   { filter: none; }
  25%  { filter: brightness(1.35) drop-shadow(0 0 12px rgba(245, 185, 66, .75)); }
  100% { filter: none; }
}

@media (max-width: 640px) {
  .dg-barre { top: -1.5rem; margin: 0 -.8rem 1rem; padding: 1.6rem .8rem .7rem; }
  .dg-message { font-size: .82rem; flex-basis: 100%; }
  .dg-tout { flex: 1 1 auto; }
  .dg-actions { gap: .5rem; }
  .dg-actions > button { flex: 1 1 calc(50% - .5rem); min-height: 44px; padding: 0 10px; font-size: 14px; }
  .dg-actions .dg-go { flex-basis: 100%; order: -1; font-size: 16px; }
  .dg-bilan { margin-top: -.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .dg-el, :where(html:not(.mouvement-plein)) .dg-el.is-on::before, :where(html:not(.mouvement-plein)) .dg-el.is-on::after, :where(html:not(.mouvement-plein)) .dg-reclamer:not(:disabled)::after,
  :where(html:not(.mouvement-plein)) .dg-barre .dg-go::after, :where(html:not(.mouvement-plein)) .dg-barre.est-prete .dg-tout::after, :where(html:not(.mouvement-plein)) .dg-onde,
  :where(html:not(.mouvement-plein)) .dg-scene.dg-entre, :where(html:not(.mouvement-plein)) .dg-scene.dg-sort { animation: none !important; }
}

/* La pastille FREE du Cartable.
   
   Posee sur la CARTE, pas sur la pochette : la pochette ne bouge pas, et une
   pastille qui reste a plat pendant que la carte s'incline se lit comme un
   defaut d'alignement. Meme raison que le reflet (voir .cart-vitre). */
/*  ELLE SUIT LA TAILLE DE LA CARTE. A taille fixe, elle couvrait le haut
    d'une carte de 45 px (telephone couche, 03/10/2026) : la pochette est un
    conteneur, la pastille se mesure en `cqi` et ne depasse jamais sa taille
    d'origine. */
.cart-poche .cf { container-type: inline-size; }
.cart-pastille-free {
  position: absolute; top: clamp(2px, 4.5cqi, 6px); left: clamp(2px, 4.5cqi, 6px); z-index: 4;
  padding: .2em .75em; border-radius: 999px;
  font-family: var(--font-title); font-size: clamp(5px, 6.8cqi, .52rem); font-weight: 700;
  letter-spacing: .16em; line-height: 1.5;
  color: #dfe5f2;
  background: rgba(16, 21, 34, .92);
  border: 1px solid rgba(196, 203, 218, .5);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .6);
  pointer-events: none;
}
/*  LE COMPTE D'EXEMPLAIRES, en bas a droite.
    Il ne partage pas le coin de « FREE » (en haut a gauche) : une carte
    pretee peut tres bien etre en plusieurs exemplaires, et les deux pastilles
    doivent pouvoir coexister sans se recouvrir. Chiffres tabulaires, pour que
    x2 et x11 aient la meme assise. */
.cart-pastille-nb {
  position: absolute; bottom: clamp(2px, 4.5cqi, 6px); right: clamp(2px, 4.5cqi, 6px); z-index: 4;
  min-width: 1.5em; padding: .2em .6em; border-radius: 999px;
  font-family: var(--font-num), Georgia, serif;
  font-size: clamp(6px, 7.5cqi, .58rem); font-weight: 800; letter-spacing: .02em;
  line-height: 1.5; text-align: center;
  font-variant-numeric: tabular-nums;
  color: #1a1202;
  background: linear-gradient(180deg, #f5d67a, #c9a246);
  border: 1px solid rgba(255, 224, 130, .9);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .6);
  pointer-events: none;
}

/* La carte pretee est PRESENTE -- elle n'est jamais grisee comme une
   manquante. On la desature juste assez pour que la difference se voie a
   l'echelle d'une page, sans la rendre moins lisible que les autres. */
.cart-poche.est-pretee .cart-vitre { filter: saturate(.72); }

/*  QUATRE PORTES, PAS TROIS.
    Une feuille de style plus ancienne redeclare `.home-menu` en trois
    colonnes plus bas dans ce fichier ; en cascade, c'est elle qui gagnait,
    et la quatrieme porte tombait seule sur une deuxieme ligne. On reaffirme
    ici, en dernier, ce que l'accueil demande. */
.home-menu { grid-template-columns: repeat(4, 1fr); gap: 18px; }
@media (max-width: 1100px) { .home-menu { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .home-menu { grid-template-columns: 1fr; } }

/*  ══ LE POUVOIR D'ASCENDANT DANS LE PUPITRE ══════════════════════════════
    La Roue a quitte la table pour venir ici : au milieu du plateau, en
    perspective, on voyait « une pastille allumee » sans pouvoir dire
    laquelle -- et une piece de pierre ne porte pas de phrase, alors que le
    cadran en a une a dire a chaque cran depuis les Pouvoirs.
    ═══════════════════════════════════════════════════════════════════════ */
.module-ascendant {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 4px 0 2px;
}

/*  LA ROUE SE POSE DANS SON SIEGE, SUR LA TABLE.
    Elle y a toujours ete -- c'est la piece maitresse du jeu, elle appartient
    au plateau. Ce qui a change, c'est sa matiere : la pierre gravee est
    devenue du DOM, lisible a toute taille. Sa POSITION et sa TAILLE viennent
    de la table (`siegeDeLaRoue`), pas d'ici : elles dependent de la camera,
    et le CSS n'en sait rien. */
.roue-table {
  position: absolute; z-index: 6;
  pointer-events: none;              /* la table dessous reste cliquable */
  /* L'ombre portee qui la fait tenir DANS le creux plutot que flotter
     au-dessus : sans elle, la piece est un autocollant. */
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .75));
}
.roue-table .roue-piece { pointer-events: auto; }
/*  LE SERPENT DU TOUR (js/serpent.js) : sa toile est taillee et posee par
    le script, a la bande des portraits. Juste au-dessus de la Roue, qu'il
    longe sans la toucher. */
/*  `.table3d > canvas` donne a toute toile de la table sa taille, et au
    telephone une marge haute : celle-ci se pose seule, au pixel pres. */
.table3d > .serpent-tour { position: absolute; z-index: 6; pointer-events: none; margin: 0; }
.table3d > .serpent-tour[hidden] { display: none; }
/*  SUR LA TABLE, LA ROUE DOIT SE LIRE DE LOIN. L'extinction de l'accueil
    (saturate .35, brightness .72) la noyait dans la planche : les crans
    eteints restent en couleur, seul l'allume brille en plus. */
.roue-table .roue-piece:not(.is-on) {
  filter: saturate(.85) brightness(.95);
  background: radial-gradient(circle at 40% 32%,
              color-mix(in srgb, var(--el-color) 22%, #3a4460) 0%, #1c2234 100%);
  border-color: color-mix(in srgb, var(--el-color) 60%, transparent);
}
.roue-table .roue-piece:not(.is-on) .el-ico { filter: drop-shadow(0 0 3px var(--el-color)); opacity: .8; }
/*  14/10 : « trop lumineuse, on ne voit plus quel element est actif ».
    L'anneau et le coeur gardent leur clarte du 12/10 ; les crans eteints
    redescendent (en couleur, mais sans eclat) et l'allume se remplit de
    sa teinte, cercle blanc et halo large : l'ecart se lit de loin. */
.roue-table .roue-piece.is-on,
.roue-table .roue-piece.is-on:hover:not(:disabled) {
  filter: brightness(1.15) saturate(1.2);
  border: 2.5px solid #fff;
  background: radial-gradient(circle at 40% 32%,
              color-mix(in srgb, var(--el-color) 75%, #fff) 0%,
              var(--el-color) 45%,
              color-mix(in srgb, var(--el-color) 55%, #0a0d16) 100%);
  box-shadow:
    0 0 34px 6px var(--el-glow),
    0 0 0 4px color-mix(in srgb, var(--el-color) 55%, transparent),
    inset 0 0 12px rgba(255, 255, 255, .35);
}
.roue-table .roue-piece.is-on .el-ico { filter: brightness(0) invert(1) drop-shadow(0 0 6px rgba(0, 0, 0, .6)); }
.roue-table .roue-coeur {
  background: radial-gradient(circle at 45% 38%, #4c5878 0%, #2a3248 100%);
  border-color: rgba(245, 185, 66, .9);
  box-shadow: inset 0 0 14px rgba(0, 0, 0, .45), 0 0 12px rgba(245, 185, 66, .25);
}
.roue-table .roue-coeur-lbl { color: var(--ink-bright); }
.roue-table .roue-anneau {
  /* Le creux de la planche fait deja le fond : la piece n'apporte que sa
     couronne, sinon on empile deux disques et la levre de laiton disparait. */
  background: radial-gradient(circle at 42% 34%, rgba(124, 110, 156, .82) 0%, rgba(62, 68, 98, .88) 62%, rgba(36, 40, 60, .92) 100%);
  border-color: rgba(245, 185, 66, .9);
  box-shadow:
    0 0 30px rgba(245, 185, 66, .3),
    inset 0 2px 10px rgba(255, 255, 255, .2),
    inset 0 -4px 14px rgba(0, 0, 0, .6);
}

/* Sans les noms, les pieces respirent et l'icone porte seule. */
.roue-cadran.roue--compacte .piece-nom { display: none; }
.roue-cadran.roue--compacte .roue-piece { width: 27%; }
.roue-cadran.roue--compacte .roue-piece .el-ico { width: 52%; height: 52%; }
.roue-cadran.roue--compacte .roue-coeur { width: 46%; padding: 4px; }
.roue-cadran.roue--compacte .roue-coeur-lbl { font-size: 6.5px; letter-spacing: .16em; }
.roue-cadran.roue--compacte .roue-coeur-el { font-size: 14px; }

.ma-pouvoir {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  text-align: center; width: 100%;
}
.ma-kicker {
  font-family: var(--font-title); font-size: 7.5px; font-weight: 800;
  letter-spacing: .2em; color: var(--ink-faint);
}
.ma-nom {
  font-family: var(--font-title); font-size: 15px; font-weight: 800;
  letter-spacing: .04em; color: var(--el-actif, var(--accent));
  text-shadow: 0 0 12px var(--el-actif, var(--accent));
  transition: color .4s ease, text-shadow .4s ease;
  line-height: 1.2;
}
.ma-ligne { font-size: 11px; line-height: 1.45; color: var(--ink-dim); }

/*  LE POUVOIR N'EST PAS TOUJOURS LE TIEN. Le cadran est commun aux deux
    camps ; le Pouvoir va a qui ALIGNE l'element. Tant que tu n'as pas la
    couleur sur l'anneau, le panneau reste eteint -- il DIT le Pouvoir, il ne
    te le promet pas. */
.module-ascendant:not(.est-mien) .ma-nom {
  color: var(--ink-faint); text-shadow: none;
}
.module-ascendant:not(.est-mien) .ma-roue { opacity: .72; }
.module-ascendant.est-voile .ma-nom { color: var(--ink-faint); text-shadow: none; }

.ma-geste {
  width: 100%; padding: 9px 12px; border-radius: 10px;
  font-family: var(--font-title); font-size: 12px; font-weight: 800;
  letter-spacing: .06em; color: #140d02;
  background: var(--gold-grad);
  border: 1px solid var(--accent-light);
  box-shadow: 0 4px 16px rgba(245, 185, 66, .35);
  animation: ctaRespire 2.4s ease-in-out infinite alternate;
}
.ma-geste:hover:not(:disabled) {
  filter: brightness(1.08); color: #140d02;
  background: var(--gold-grad); border-color: var(--accent-light);
}
/* LE PUPITRE LAISSE PASSER LES CLICS (`.game-module`, pointer-events: none)
   et chacun de ses boutons doit les reprendre, comme `.module-end-turn` et
   `.prompt`. Oublie ici, le bouton du Pouvoir se voyait mais un vrai clic
   tombait sur la table derriere : il n'a jamais rien declenche. */
.ma-geste { pointer-events: auto; cursor: pointer; }
/* A LA COULEUR DE L'ELEMENT, comme la grande annonce qu'il rouvre : le
   bouton dit de quel Pouvoir il s'agit avant qu'on lise son texte.
   --el et --el2 sont poses par renderPouvoirAscendant. */
.ma-geste.teinte {
  color: #0b0a10;
  background: linear-gradient(180deg, var(--el2), var(--el));
  border-color: var(--el2);
  box-shadow: 0 4px 18px color-mix(in srgb, var(--el) 55%, transparent);
  animation: maAppel 2.2s ease-in-out infinite;
}
.ma-geste.teinte:hover:not(:disabled) {
  color: #0b0a10;
  background: linear-gradient(180deg, var(--el2), var(--el));
  border-color: var(--el2);
}
@keyframes maAppel {
  50% { box-shadow: 0 0 26px color-mix(in srgb, var(--el) 85%, transparent); }
}

/*  ══ LA FENETRE DE CHOIX DES TROIS GESTES ════════════════════════════════
    Une liste de vignettes plutot qu'un clic sur la table : rien n'indique
    quelles creatures un Pouvoir peut viser, et pointer une bete en
    perspective sur un telephone est un mauvais geste. La liste se lit et se
    touche a toute taille, et elle montre ce qu'il faut pour choisir -- les
    PV, et surtout les energies posees, qui sont l'enjeu de deux gestes sur
    trois.
    ═══════════════════════════════════════════════════════════════════════ */
.choix-geste {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center;
  padding: 18px;
  background: rgba(4, 6, 11, .72);
  backdrop-filter: blur(6px);
  animation: tabMenuIn .18s cubic-bezier(.16, 1, .3, 1);
}
.cg-cadre {
  width: min(520px, 100%); max-height: min(82dvh, 680px);
  display: flex; flex-direction: column; gap: 8px;
  padding: 22px 24px 18px; border-radius: 18px;
  background: linear-gradient(170deg, rgba(24, 31, 50, .97), rgba(9, 12, 20, .99));
  border: 1px solid var(--line-gold);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .8), inset 0 1px 0 rgba(255, 240, 180, .2);
}
.cg-kicker {
  font-family: var(--font-title); font-size: 9px; font-weight: 800;
  letter-spacing: .2em; color: var(--accent);
}
.cg-titre {
  margin: 0; font-family: var(--font-title); font-size: 19px; font-weight: 800;
  color: var(--ink-bright); letter-spacing: .03em;
}
.cg-texte { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--ink-dim); }

.cg-liste {
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 7px;
  margin: 6px 0 2px; padding-right: 3px;
}
.cg-item {
  /* `justify-content` explicite : la regle generale des boutons centre son
     contenu, et la vignette se retrouvait au milieu de la ligne. */
  display: flex; align-items: center; justify-content: flex-start; gap: 11px;
  padding: 7px 12px 7px 7px; border-radius: 11px; text-align: left;
  background: rgba(255, 255, 255, .04);
  border: 1px solid color-mix(in srgb, var(--el, #f5b942) 32%, transparent);
  color: var(--ink); box-shadow: none;
}
.cg-item:hover {
  background: color-mix(in srgb, var(--el, #f5b942) 14%, transparent);
  border-color: var(--el, var(--accent));
  transform: none; box-shadow: 0 0 18px color-mix(in srgb, var(--el, #f5b942) 30%, transparent);
}
.cg-vign {
  flex: none; width: 38px; height: 54px; border-radius: 6px;
  object-fit: cover; background: #06080e;
}
.cg-txt { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.cg-txt b {
  font-family: var(--font-title); font-size: 14px; font-weight: 800;
  color: var(--ink-bright);
}
.cg-txt span { font-size: 11.5px; color: var(--ink-dim); }
.cg-vide {
  margin: 10px 0; padding: 14px; border-radius: 10px; text-align: center;
  font-size: 12.5px; line-height: 1.55; color: var(--ink-faint);
  background: rgba(255, 255, 255, .03); border: 1px dashed var(--line);
}

.cg-pied { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
.cg-majeur {
  padding: 9px 18px; border-radius: 10px;
  font-weight: 800; letter-spacing: .04em; color: #140d02;
  background: var(--gold-grad); border: 1px solid var(--accent-light);
}
.cg-annuler {
  padding: 9px 16px; border-radius: 10px;
  background: transparent; border: 1px solid var(--line); color: var(--ink-dim);
  box-shadow: none;
}
.cg-annuler:hover:not(:disabled) {
  background: rgba(255, 255, 255, .05); color: var(--ink-bright); border-color: var(--ink-faint);
}
/* Meme piege que les boutons du Pouvoir : sans son fond redit, le bouton
   d'or virait au bleu nuit sous un texte noir. */
.cg-majeur:hover:not(:disabled) {
  background: var(--gold-grad); color: #140d02; border-color: var(--accent-light);
  filter: brightness(1.08);
}
.cg-majeur:disabled { opacity: .4; cursor: default; }

/*  ── L'AUBE ET LA FAILLE : LA TABLE DE REPARTITION ────────────────────────
    Les cartes en vrai a gauche, la carte choisie en grand a droite avec son
    0 / 1 / 2. Rien ne part avant « Valider » (fenetreRepartition, main.js). */
.choix-geste.cg-large .cg-cadre { width: min(860px, 100%); max-height: min(90dvh, 760px); }
.cg-table {
  display: grid; grid-template-columns: minmax(0, 1fr) 250px; gap: 16px;
  min-height: 0;
}
.cg-cartes {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 10px; align-content: start;
  overflow-y: auto; max-height: min(58dvh, 520px); padding: 4px 4px 4px 2px;
}
.cg-carte {
  position: relative;
  display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start;
  gap: 5px; padding: 6px; border-radius: 12px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid color-mix(in srgb, var(--el, #f5b942) 28%, transparent);
  color: var(--ink); box-shadow: none;
}
.cg-carte:hover:not(:disabled) {
  background: color-mix(in srgb, var(--el, #f5b942) 12%, rgba(255, 255, 255, .03));
  border-color: var(--el, var(--accent));
  box-shadow: 0 0 16px color-mix(in srgb, var(--el, #f5b942) 30%, transparent);
  transform: translateY(-2px);
}
.cg-carte.choisie {
  border-color: var(--accent-light);
  box-shadow: 0 0 0 2px var(--accent), 0 0 22px rgba(245, 185, 66, .35);
}
/* Le format des rendus (320 x 503), pas celui d'une carte imprimee : en
   63/88 avec `cover`, le bas de la carte -- les lignes -- etait rogne. */
.cg-carte-img {
  width: 100%; aspect-ratio: 320 / 503; border-radius: 7px;
  object-fit: contain; background: #06080e;
}
.cg-carte-nom {
  font-family: var(--font-title); font-size: 12px; font-weight: 800;
  color: var(--ink-bright); text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cg-badge {
  position: absolute; top: -7px; right: -7px;
  min-width: 30px; padding: 3px 7px; border-radius: 999px;
  font-family: var(--font-title); font-size: 13px; font-weight: 900; color: #0b0a10;
  background: var(--gold-grad); border: 1px solid var(--accent-light);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .6);
}
.choix-geste.cg-large .cg-carte.servie .cg-carte-img { outline: 2px solid var(--accent); }
/* La Faille prend : son badge est rouge, l'or reste a ce qu'on donne. */
.cg-badge.vol { color: #fff; background: linear-gradient(180deg, #ff6b6b, #c22d2d); border-color: #ffb1b1; }

.cg-nrj { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; min-height: 12px; }
.cg-pt {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--pt); border: 1px solid rgba(255, 255, 255, .55);
  box-shadow: 0 0 6px color-mix(in srgb, var(--pt) 70%, transparent);
}
/* Celle qui arrive (l'Aube) respire ; celle qui part (la Faille) s'eteint et se barre. */
.cg-pt.vient { border: 2px solid #fff; animation: cgVient 1.1s ease-in-out infinite alternate; }
.cg-pt.part {
  background: transparent; border: 2px solid #ff5a5a; box-shadow: none; position: relative;
}
.cg-pt.part::after {
  content: ''; position: absolute; left: -2px; right: -2px; top: 50%; height: 2px;
  background: #ff5a5a; transform: rotate(-45deg);
}
@keyframes cgVient { to { transform: scale(1.25); box-shadow: 0 0 12px var(--pt); } }
.cg-nrj-vide { font-size: 10px; color: var(--ink-faint); }

.cg-fiche {
  display: flex; flex-direction: column; gap: 10px;
  padding: 10px; border-radius: 14px;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--line);
}
.cg-grande {
  position: relative; display: block; padding: 0; border: 0; border-radius: 10px;
  background: none; box-shadow: none; cursor: zoom-in;
}
.cg-grande:hover:not(:disabled) { background: none; box-shadow: none; transform: none; }
.cg-grande img {
  display: block; width: 100%; aspect-ratio: 320 / 503; border-radius: 10px;
  object-fit: contain; background: #06080e;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .6);
}
.cg-loupe {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  padding: 3px 10px; border-radius: 999px; font-size: 10.5px; white-space: nowrap;
  color: var(--ink-bright); background: rgba(6, 8, 14, .78); border: 1px solid var(--line);
}
.cg-fiche-info { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--ink-dim); }
.cg-fiche-nom {
  font-family: var(--font-title); font-size: 15px; font-weight: 800; color: var(--ink-bright);
}
.cg-fiche-nrj { color: var(--ink-bright); font-weight: 700; }
.cg-fiche-q { margin-top: 6px; font-weight: 700; color: var(--accent); }
.cg-seg { display: flex; gap: 6px; }
.cg-seg-b {
  flex: 1; padding: 8px 0; border-radius: 9px;
  font-family: var(--font-title); font-size: 16px; font-weight: 900;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--line); color: var(--ink);
  box-shadow: none;
}
.cg-seg-b:hover:not(:disabled) {
  background: rgba(245, 185, 66, .14); border-color: var(--accent); color: var(--ink-bright);
  transform: none;
}
.cg-seg-b.actif, .cg-seg-b.actif:hover:not(:disabled) {
  background: var(--gold-grad); color: #140d02; border-color: var(--accent-light);
}
.cg-seg-b:disabled { opacity: .3; cursor: default; }
.cg-fiche-vide {
  margin: auto 0; padding: 24px 8px; text-align: center;
  font-size: 12.5px; line-height: 1.5; color: var(--ink-faint);
}
.cg-grande[hidden], .cg-fiche-info[hidden], .cg-fiche-vide[hidden], .cg-badge[hidden] { display: none; }
.cg-reste { margin-right: auto; align-self: center; font-size: 12px; color: var(--ink-dim); }

/*  ── LA FICHE QUI FAIT CHOISIR (01/11/2026) ──────────────────────────────
    « On doit voir l'energie, les effets, en tout, pour prendre le meilleur
    choix. » Chaque carte porte ses PV, son attaque et ses etats ; la choisie
    s'ouvre a droite, peinte comme sur la table, avec ses competences et ce
    que le geste leur fait. Rien ne defile : tout tient dans le cadre. */
.choix-geste.cg-large .cg-cadre { width: min(1140px, 100%); max-height: 96dvh; padding: 20px 22px 16px; }
.choix-geste.cg-large .cg-liste { overflow: visible; }
.choix-geste.cg-large .cg-table { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 18px; }
.choix-geste.cg-large .cg-cartes {
  grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
  overflow: visible; max-height: none; padding: 8px 6px 4px 2px;
}
.cg-carte { cursor: pointer; }
.cg-carte-cadre { position: relative; display: block; }
.cg-carte-cadre .cg-carte-img { display: block; }
.cg-carte-etats {
  position: absolute; left: 4px; top: 22%;
  display: flex; flex-direction: column; gap: 3px;
}
.cg-etat {
  display: inline-block; width: 20px; height: 20px; border-radius: 50%; flex: none;
  background: var(--ico, none) center / 78% no-repeat, rgba(6, 8, 14, .82);
  border: 1.5px solid var(--etat, #fff);
  box-shadow: 0 0 8px color-mix(in srgb, var(--etat, #fff) 55%, transparent);
}
.cg-carte-heros {
  position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%);
  padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; color: #140d02; background: var(--gold-grad);
}
.cg-carte-stats { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 11px; }
.cg-carte-pv { position: relative; flex: 1; display: flex; align-items: baseline; gap: 1px; min-width: 0; padding-bottom: 4px; }
.cg-carte-pv b { font-family: var(--font-num); font-size: 13px; color: var(--ink-bright); }
.cg-carte-pv small { font-size: 10px; color: var(--ink-faint); }
.cg-carte-jauge {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, #5be37a calc(var(--pv) * 100%), rgba(255, 255, 255, .1) 0);
}
.cg-carte-atk { font-family: var(--font-num); font-weight: 800; color: #ffd27a; white-space: nowrap; }
.cg-badge { white-space: nowrap; }
.choix-geste.cg-large .cg-carte.servie {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 18px rgba(245, 185, 66, .3);
}
.choix-geste.cg-large .cg-carte.servie:has(.cg-badge.vol) {
  border-color: #ff6b6b; box-shadow: 0 0 0 1px #ff6b6b, 0 0 18px rgba(255, 70, 70, .35);
}
.choix-geste.cg-large .cg-carte.servie .cg-carte-img { outline: none; }

.choix-geste.cg-large .cg-fiche {
  display: grid; grid-template-columns: minmax(150px, 38%) minmax(0, 1fr);
  align-items: start; gap: 14px; padding: 12px;
}
.choix-geste.cg-large .cg-fiche-vide { grid-column: 1 / -1; }
.cg-grande canvas {
  display: block; width: 100%; aspect-ratio: 320 / 503; border-radius: 10px;
  background: #06080e; box-shadow: 0 10px 30px rgba(0, 0, 0, .6);
}
.choix-geste.cg-large .cg-fiche-info { gap: 9px; font-size: 12.5px; min-width: 0; }
.cg-fiche-tete { display: flex; flex-direction: column; gap: 1px; }
.cg-fiche-nom { font-size: 18px; line-height: 1.1; }
.cg-fiche-sous { font-size: 12px; color: var(--ink-dim); }
.cg-fiche-info .vie-barre { margin: 0; }
.cg-fiche-bloc {
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px 10px; border-radius: 10px;
  background: rgba(0, 0, 0, .22); border: 1px solid rgba(255, 255, 255, .07);
}
.cg-fiche-titre {
  font-family: var(--font-title); font-size: 10px; font-weight: 800;
  letter-spacing: .16em; text-transform: uppercase; color: var(--accent);
}
.cg-fiche-nrj-l { display: flex; align-items: center; gap: 10px; }
.cg-fiche-nrj-l .cg-nrj { justify-content: flex-start; flex: 1; }
.cg-fiche-nrj-l .cg-pt { width: 15px; height: 15px; }
.cg-fiche-compte { font-family: var(--font-num); font-size: 18px; color: var(--ink-bright); white-space: nowrap; }
.cg-fiche-nrj.baisse .cg-fiche-compte { color: #ff7a7a; }
.cg-fiche-nrj.hausse .cg-fiche-compte { color: #ffd27a; }
.cg-fiche-nrj .cg-seg { align-items: center; }
.cg-fiche-nrj .cg-fiche-q { margin: 0 4px 0 0; white-space: nowrap; }
.cg-fiche-nrj .cg-seg-b { padding: 6px 0; }
.cg-comp { display: flex; flex-direction: column; gap: 4px; }
.cg-comp-l {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: 8px; background: rgba(255, 255, 255, .04);
  border: 1px solid transparent;
}
.cg-comp-cout {
  flex: none; width: 22px; height: 22px; display: grid; place-items: center;
  font-family: var(--font-num); font-size: 12px; font-weight: 900; color: #140d02;
  background: var(--gold-grad); clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
.cg-comp-nom {
  flex: 1; min-width: 0; font-weight: 700; color: var(--ink-bright);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cg-comp-dmg { font-family: var(--font-num); font-weight: 800; color: #ffd27a; white-space: nowrap; }
.cg-comp-etat {
  flex: none; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 800;
  letter-spacing: .04em; white-space: nowrap;
}
.cg-comp-l.prete .cg-comp-etat { color: #9ff0b0; background: rgba(60, 200, 100, .14); }
.cg-comp-l.eteinte { opacity: .55; }
.cg-comp-l.eteinte .cg-comp-etat { color: var(--ink-faint); background: rgba(255, 255, 255, .05); }
.cg-comp-l.coupee { border-color: rgba(255, 90, 90, .55); background: rgba(255, 60, 60, .1); }
.cg-comp-l.coupee .cg-comp-nom, .cg-comp-l.coupee .cg-comp-dmg { text-decoration: line-through; text-decoration-color: #ff6b6b; }
.cg-comp-l.coupee .cg-comp-etat { color: #fff; background: linear-gradient(180deg, #ff6b6b, #c22d2d); }
.cg-comp-l.debloquee { border-color: rgba(255, 210, 120, .6); background: rgba(255, 200, 90, .1); }
.cg-comp-l.debloquee .cg-comp-etat { color: #140d02; background: var(--gold-grad); }
.cg-fiche-effets { display: flex; flex-wrap: wrap; gap: 5px; }
.cg-tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px 3px 4px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
  color: var(--ink-bright); background: color-mix(in srgb, var(--etat, #fff) 14%, rgba(0, 0, 0, .3));
  border: 1px solid color-mix(in srgb, var(--etat, #fff) 45%, transparent);
}
.cg-tag small { font-size: 10px; color: var(--ink-dim); font-weight: 700; }
.cg-tag.cg-tag-formation { padding-left: 9px; --etat: #7fb4ff; }
.cg-fiche-rien { font-size: 11.5px; color: var(--ink-faint); }
.cg-fiche-sous span + span::before { content: ' \00b7 '; color: var(--ink-faint); }

/*  ── LA FENETRE DE CHOIX PORTE L'ELEMENT DU POUVOIR (01/11/2026) ─────────
    Comme l'annonce qui l'ouvre : fond a la couleur profonde de l'element,
    sceau en tete, particules autour, bouton a ses couleurs. (--el, --el2,
    --el3 et `.el-*` : main.js, `habillerChoix`.) */
.cg-particules {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  -webkit-mask-image: radial-gradient(ellipse 70% 75% at 50% 50%, #000 0%, transparent 80%);
          mask-image: radial-gradient(ellipse 70% 75% at 50% 50%, #000 0%, transparent 80%);
}
.cg-sceau { display: none; }
.choix-geste.a-element {
  background:
    radial-gradient(ellipse 60% 55% at 50% 45%, color-mix(in srgb, var(--el) 20%, transparent), transparent 72%),
    rgba(4, 6, 11, .74);
}
.choix-geste.a-element .cg-cadre {
  position: relative;
  margin-top: 30px; padding-top: 44px;
  background:
    radial-gradient(ellipse 80% 28% at 50% 0%, color-mix(in srgb, var(--el) 26%, transparent), transparent 78%),
    linear-gradient(175deg, color-mix(in srgb, var(--el3) 72%, #20222c) 0%,
      color-mix(in srgb, var(--el3) 82%, #0b0c12) 60%, #07080c 100%);
  border-color: color-mix(in srgb, var(--el) 50%, var(--line-gold));
  box-shadow: 0 0 60px color-mix(in srgb, var(--el) 30%, transparent), 0 30px 80px rgba(0, 0, 0, .8);
}
.choix-geste.a-element .cg-sceau {
  display: grid; place-items: center;
  position: absolute; left: 50%; top: 0; z-index: 4;
  width: 68px; height: 68px; border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--el) 55%, #120c06) 0%, #0b0a0e 70%);
  box-shadow: 0 0 0 3px #1a1005, 0 0 26px color-mix(in srgb, var(--el) 70%, transparent), 0 8px 18px rgba(0, 0, 0, .7);
}
.choix-geste.a-element .cg-sceau::before {
  content: ''; position: absolute; inset: -4px; border-radius: 50%;
  padding: 4px; background: var(--or-metal);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.cg-sceau i {
  width: 62%; height: 62%;
  background: var(--ico) center / contain no-repeat;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--el2) 80%, transparent));
}
.choix-geste.a-element :is(.cg-kicker, .cg-titre, .cg-texte) { text-align: center; }
.choix-geste.a-element .cg-kicker { color: var(--el2); letter-spacing: .28em; }
.choix-geste.a-element .cg-fiche-titre { color: var(--el2); }
.choix-geste.a-element .cg-carte.choisie {
  border-color: var(--el2);
  box-shadow: 0 0 0 2px var(--el2), 0 0 22px color-mix(in srgb, var(--el) 55%, transparent);
}
.choix-geste.a-element .cg-majeur,
.choix-geste.a-element .cg-majeur:hover:not(:disabled) {
  color: #0b0a10;
  background: linear-gradient(180deg, var(--el2), color-mix(in srgb, var(--el) 70%, var(--el2)));
  border: 2px solid #e6bd62;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), 0 0 20px color-mix(in srgb, var(--el) 55%, transparent);
}
.choix-geste.a-element .cg-seg-b.actif,
.choix-geste.a-element .cg-seg-b.actif:hover:not(:disabled) {
  color: #0b0a10; border-color: var(--el2);
  background: linear-gradient(180deg, var(--el2), color-mix(in srgb, var(--el) 70%, var(--el2)));
}

/*  SUR UN TELEPHONE, la fenetre prend toute la largeur et la liste se limite
    a la moitie basse : le pouce y arrive, et le titre reste visible pendant
    qu'on fait defiler. */
@media (max-width: 620px) {
  .choix-geste { padding: 0; place-items: end stretch; }
  .cg-cadre {
    width: 100%; max-height: 86dvh;
    border-radius: 18px 18px 0 0; padding: 18px 16px 14px;
  }
  .cg-item { padding: 9px 12px 9px 9px; }
  .cg-vign { width: 42px; height: 60px; }
  .cg-pied { justify-content: stretch; }
  .cg-pied button { flex: 1; }
  .cg-reste { flex-basis: 100%; text-align: center; }
  /* Au telephone : les cartes en bande qui defile, la fiche en ligne dessous. */
  .cg-table { grid-template-columns: 1fr; gap: 10px; }
  .cg-cartes {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 96px;
    overflow-x: auto; overflow-y: hidden; max-height: none; padding-top: 8px;
  }
  .cg-fiche { flex-direction: row; align-items: flex-start; }
  .cg-grande { flex: none; width: 112px; }
  .cg-fiche-info { flex: 1; min-width: 0; }
  .cg-fiche-vide { padding: 10px 4px; }
  .module-ascendant { flex-direction: row; align-items: center; gap: 10px; }
  .ma-pouvoir { align-items: flex-start; text-align: left; }
  .ma-ligne { font-size: 10.5px; }
  .ma-geste { width: auto; flex: none; }
}

/* ══ L'ANNONCE DU POUVOIR D'ASCENDANT ══════════════════════════════════════
    Le moment qui revient une fois par tour de cadran. Il ne se glisse pas
    dans le pupitre : il coupe l'ecran, a la couleur de l'element (--el,
    --el2, posees par `annoncerPouvoir`).

    REFAITE LE 01/11/2026 (« pas top »). Les rayons en eventail derriere le
    cadre etaient le soleil manga qu'Alexandre refuse partout ; le cadre,
    une boite sombre a filet fin, ne disait rien du jeu. Maintenant :
     . derriere, une lueur de l'element qui RESPIRE, et des braises qui
       montent -- pas une bande nette ;
     . le cadre est cercle d'or massif, comme les tuiles de la Boutique, et
       porte le fleuron sur son filet du bas ;
     . en tete, le SCEAU de l'element : un medaillon d'or a cheval sur le
       filet, l'icone de l'element dedans, qui s'allume a l'arrivee ;
     . le titre TOMBE, une onde part du sceau. Chez l'adversaire, le meme
       cadre encaisse et le bandeau passe au rouge. */
.annonce-pouvoir {
  --el: #f5b942; --el2: #ffe7a3;
  position: fixed; inset: 0; z-index: 125;
  display: grid; place-items: center;
  padding: 16px;
  background:
    radial-gradient(ellipse 60% 55% at 50% 50%,
      color-mix(in srgb, var(--el) 22%, transparent) 0%, transparent 70%),
    radial-gradient(circle at 50% 50%, rgba(3, 4, 8, .55) 0%, rgba(3, 4, 8, .9) 75%);
  overflow: hidden;
}
/*  PAS DE FONDU NI DE FLOU SUR LE VOILE. Par-dessus la table 3D, le flou
    d'arriere-plan et un fondu parti de zero se sont figes sur une machine
    d'essai : la fenetre restait a l'etat de fantome au milieu du plateau.
    Le voile tombe d'un coup ; c'est le cadre qui fait l'entree. */
/*  La lueur qui respire : deux nappes floues, decalees, jamais de rayons. */
.ap-eclat {
  position: absolute; left: 50%; top: 50%;
  width: min(1100px, 130vw); aspect-ratio: 1.6;
  transform: translate(-50%, -50%);
  background:
    radial-gradient(ellipse 38% 42% at 42% 46%, color-mix(in srgb, var(--el) 46%, transparent), transparent 70%),
    radial-gradient(ellipse 34% 38% at 60% 56%, color-mix(in srgb, var(--el2) 26%, transparent), transparent 72%);
  filter: blur(28px);
  opacity: .8;
  pointer-events: none;
  animation: apRespireFond 4.2s ease-in-out infinite alternate;
}
/*  L'air autour du cadre vit comme l'element : la couche est semee de
    particules par main.js (`semerParticules`), leur forme et leur trajet
    sont plus bas (`.pe`). */
.ap-braises {
  position: absolute; inset: 0; pointer-events: none;
  -webkit-mask-image: radial-gradient(ellipse 60% 65% at 50% 52%, #000 0%, transparent 78%);
          mask-image: radial-gradient(ellipse 60% 65% at 50% 52%, #000 0%, transparent 78%);
}

.ap-cadre {
  --or-ep: 4px;
  position: relative;
  width: min(580px, 100%);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin-top: 40px;
  padding: 58px 34px 34px; border-radius: 18px; text-align: center;
  background:
    radial-gradient(ellipse 85% 46% at 50% 0%, color-mix(in srgb, var(--el) 30%, transparent), transparent 75%),
    radial-gradient(ellipse 70% 30% at 50% 100%, color-mix(in srgb, var(--el) 12%, transparent), transparent 80%),
    linear-gradient(175deg, color-mix(in srgb, var(--el3, #0d0e15) 75%, #23242e) 0%,
      color-mix(in srgb, var(--el3, #0d0e15) 85%, #0b0c12) 55%, #07080c 100%);
  border: 1px solid rgba(26, 16, 5, .92);
  box-shadow:
    inset 0 0 0 calc(var(--or-ep) + 1px) rgba(18, 11, 4, .85),
    inset 0 0 0 calc(var(--or-ep) + 2px) rgba(240, 200, 120, .22),
    0 0 60px color-mix(in srgb, var(--el) 40%, transparent),
    0 24px 60px rgba(0, 0, 0, .7);
}
/* L'anneau d'or massif (meme orfevrerie que les tuiles de la Boutique). */
.ap-cadre::after {
  content: ''; position: absolute; inset: 0; z-index: 2;
  border-radius: inherit; padding: var(--or-ep);
  background: var(--or-metal);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
/* L'onde de choc : elle part du cadre et s'eteint en s'elargissant. */
.ap-cadre::before {
  content: ''; position: absolute; inset: -2px; border-radius: inherit;
  border: 2px solid var(--el2); pointer-events: none; opacity: 0;
}
/* Le fleuron, sur le filet du bas. */
.ap-fleuron {
  position: absolute; left: 50%; bottom: 2px; z-index: 3;
  width: 150px; aspect-ratio: 360 / 76;
  transform: translate(-50%, 50%);
  /*  L'image est posee par da_jeu.css : une url(img/) ici ne suivrait pas
      la feuille sur R2. */
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .55));
  pointer-events: none;
}

/*  LE SCEAU DE L'ELEMENT : a cheval sur le filet du haut. */
.ap-sceau {
  position: absolute; left: 50%; top: 0; z-index: 4;
  width: 92px; height: 92px; border-radius: 50%;
  transform: translate(-50%, -50%);
  display: grid; place-items: center;
  background:
    radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--el) 55%, #120c06) 0%, #0b0a0e 70%);
  box-shadow:
    0 0 0 4px #1a1005,
    0 0 0 8px transparent,
    0 0 34px color-mix(in srgb, var(--el) 75%, transparent),
    0 10px 24px rgba(0, 0, 0, .7);
}
/* Son anneau d'or. */
.ap-sceau::before {
  content: ''; position: absolute; inset: -5px; border-radius: 50%;
  padding: 5px; background: var(--or-metal);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* Son halo, qui respire. */
.ap-sceau::after {
  content: ''; position: absolute; inset: -26px; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, color-mix(in srgb, var(--el) 55%, transparent) 0%, transparent 68%);
  animation: apHalo 2.4s ease-in-out infinite;
}
.ap-sceau i {
  width: 62%; height: 62%;
  background: var(--ico) center / contain no-repeat;
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--el2) 80%, transparent));
}

.annonce-pouvoir.entre .ap-cadre { animation: apArrivee .5s cubic-bezier(.2, 1.4, .4, 1); }
.annonce-pouvoir.entre .ap-cadre::before { animation: apChoc .9s .18s ease-out; }
.annonce-pouvoir.entre .ap-sceau { animation: apSceau .7s .05s cubic-bezier(.2, 1.5, .4, 1) both; }
.annonce-pouvoir.entre .ap-titre { animation: apTombe .55s .14s cubic-bezier(.2, 1.2, .35, 1) both; }
.annonce-pouvoir.entre .ap-cri { animation: apMonte .4s .46s ease-out both; }
.annonce-pouvoir.entre .ap-texte,
.annonce-pouvoir.entre .ap-rappel,
.annonce-pouvoir.entre .ap-gestes { animation: apMonte .4s .58s ease-out both; }

/* Le bandeau : petites capitales entre deux filets d'or, pas une pilule. */
.ap-kicker {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: .3em; color: #f0cf7c;
}
.ap-kicker::before, .ap-kicker::after {
  content: ''; width: 46px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, #d9ae56);
}
.ap-kicker::after { transform: scaleX(-1); }
.ap-qui {
  margin-top: 2px;
  font-size: 12px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-dim);
}
.ap-titre {
  margin: 4px 0 0; line-height: 1;
  /* « L'Embrasement » est le plus long des six : c'est lui qui fixe le haut
     de la fourchette, sinon il touche les bords du cadre. */
  font-family: var(--font-title); font-size: clamp(30px, 6.4vw, 50px); font-weight: 900;
  letter-spacing: .03em; text-transform: uppercase; overflow-wrap: anywhere;
  background: linear-gradient(180deg, #fff 18%, var(--el2) 52%, var(--el) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 16px color-mix(in srgb, var(--el) 65%, transparent))
          drop-shadow(0 3px 0 rgba(0, 0, 0, .75));
}
.ap-cri {
  margin: 4px 0 0;
  font-family: var(--font-title); font-size: 20px; font-weight: 800;
  color: var(--ink-bright); letter-spacing: .02em;
}
/* Ce que fait le Pouvoir : sur une plaque, a lire d'un coup d'oeil. */
.ap-texte {
  margin: 6px 0 0; max-width: 44ch;
  padding: 10px 16px; border-radius: 10px;
  font-size: 14.5px; line-height: 1.5; color: var(--ink);
  background: rgba(0, 0, 0, .28);
  border: 1px solid color-mix(in srgb, var(--el) 28%, rgba(255, 255, 255, .06));
}
.ap-rappel {
  margin: 2px 0 0;
  font-size: 11px; font-weight: 700; letter-spacing: .08em; color: var(--el2);
  opacity: .85;
}
.ap-gestes {
  display: flex; gap: 12px; justify-content: center; align-items: center; flex-wrap: wrap;
  margin-top: 14px; width: 100%;
}
.ap-bouton {
  padding: 11px 20px; border-radius: 12px;
  background: transparent; border: 1px solid rgba(240, 200, 120, .28); color: var(--ink-dim);
  box-shadow: none;
}
/*  `button:hover:not(:disabled)` (0,2,1) repeignait le fond en bleu nuit sous
    le texte noir du bouton majeur : illisible au survol. Les survols d'ici
    redisent donc leur fond, avec de quoi passer devant. */
.ap-bouton:hover:not(:disabled) {
  background: rgba(255, 255, 255, .06);
  color: var(--ink-bright); border-color: rgba(240, 200, 120, .55); transform: none;
}
.ap-bouton.majeur {
  position: relative;
  padding: 14px 30px;
  font-family: var(--font-title); font-size: 15px; font-weight: 900;
  letter-spacing: .08em; text-transform: uppercase; color: #0b0a10;
  background: linear-gradient(180deg, var(--el2), var(--el));
  border: 2px solid #e6bd62;
  box-shadow:
    inset 0 0 0 1px rgba(18, 11, 4, .55),
    inset 0 1px 0 rgba(255, 255, 255, .45),
    0 0 26px color-mix(in srgb, var(--el) 60%, transparent);
  animation: apRespire 1.8s ease-in-out infinite;
}
.ap-bouton.majeur:hover:not(:disabled) {
  color: #0b0a10; filter: brightness(1.12);
  background: linear-gradient(180deg, var(--el2), var(--el));
  border-color: #fff1bd;
  box-shadow:
    inset 0 0 0 1px rgba(18, 11, 4, .55),
    inset 0 1px 0 rgba(255, 255, 255, .45),
    0 0 40px color-mix(in srgb, var(--el) 85%, transparent);
}

/* CHEZ CELUI QUI SUBIT : le bandeau vire au rouge, le cadre encaisse. */
.annonce-pouvoir.est-adverse .ap-kicker { color: #ffb4b4; }
.annonce-pouvoir.est-adverse .ap-kicker::before,
.annonce-pouvoir.est-adverse .ap-kicker::after { background: linear-gradient(90deg, transparent, #ff6b6b); }
.annonce-pouvoir.est-adverse .ap-sceau {
  box-shadow: 0 0 0 4px #1a1005, 0 0 34px rgba(255, 70, 70, .6), 0 10px 24px rgba(0, 0, 0, .7);
}
.annonce-pouvoir.est-adverse.entre .ap-cadre {
  animation: apArrivee .5s cubic-bezier(.2, 1.4, .4, 1), apEncaisse .42s .5s ease-in-out;
}
.annonce-pouvoir.est-adverse .ap-bouton.majeur { animation: none; }

/*  ── LES PARTICULES DE L'ELEMENT (annonce et fenetre de choix) ──────────
    Une particule par <i class="pe"> : place (--x, --y), taille (--s),
    duree (--t), depart (--d), derive (--dx). La forme et le trajet suivent
    l'element du conteneur (`.el-Feu`...). Jamais de rayons. */
.pe {
  position: absolute; left: var(--x); top: var(--y);
  width: calc(5px * var(--s)); height: calc(5px * var(--s)); border-radius: 50%;
  background: radial-gradient(circle, #fff 0 20%, var(--el2) 45%, transparent 72%);
  box-shadow: 0 0 calc(8px * var(--s)) var(--el2);
  opacity: 0;
  animation: peScintille var(--t) var(--d) ease-in-out infinite;
}
/* Feu : des braises qui montent en ondulant. */
.el-Feu .pe {
  top: calc(40% + var(--y) * .6);
  background: radial-gradient(circle, #fff6d0 0 18%, #ffb347 40%, var(--el) 62%, transparent 75%);
  box-shadow: 0 0 calc(9px * var(--s)) #ff7a1a;
  animation: peMonte var(--t) var(--d) ease-out infinite;
}
/* Eau : des bulles, un anneau clair qui remonte en tanguant. */
.el-Eau .pe {
  width: calc(10px * var(--s)); height: calc(10px * var(--s));
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, .85) 0 12%, transparent 22%),
              radial-gradient(circle, transparent 55%, color-mix(in srgb, var(--el2) 70%, transparent) 62%, transparent 72%);
  box-shadow: 0 0 6px color-mix(in srgb, var(--el2) 45%, transparent);
  animation: peBulle calc(var(--t) * 1.4) var(--d) ease-in-out infinite;
}
/* Air : des rafales, traits fins qui filent. */
.el-Air .pe {
  width: calc(70px * var(--s)); height: 1.5px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--el2) 90%, #fff), transparent);
  box-shadow: none;
  animation: peVent calc(var(--t) * .55) var(--d) ease-in-out infinite;
}
/* Terre : des eclats qui tombent en tournant. */
.el-Terre .pe {
  width: calc(6px * var(--s)); height: calc(5px * var(--s)); border-radius: 1px;
  clip-path: polygon(20% 0, 100% 20%, 80% 100%, 0 75%);
  background: linear-gradient(140deg, var(--el2), #6b471f);
  box-shadow: none;
  animation: peTombe var(--t) var(--d) linear infinite;
}
/* Lumiere : des paillettes d'or qui s'allument sur place. */
.el-Lumiere .pe {
  background: radial-gradient(circle, #fff 0 22%, #ffe9a0 42%, transparent 70%);
  box-shadow: 0 0 calc(10px * var(--s)) #ffd75a;
  animation: peScintille calc(var(--t) * .7) var(--d) ease-in-out infinite;
}
/* Ether : des fragments en losange qui derivent et s'eteignent. */
.el-Ether .pe {
  width: calc(7px * var(--s)); height: calc(7px * var(--s)); border-radius: 1px;
  background: linear-gradient(135deg, #f0d6ff, var(--el2) 50%, var(--el));
  box-shadow: 0 0 calc(10px * var(--s)) var(--el2);
  animation: peDerive var(--t) var(--d) ease-in-out infinite;
}
@keyframes peMonte {
  0% { opacity: 0; transform: translate(0, 0); }
  12% { opacity: 1; }
  50% { transform: translate(calc(var(--dx) * 22px), -130px); }
  100% { opacity: 0; transform: translate(calc(var(--dx) * -14px), -280px) scale(.4); }
}
@keyframes peBulle {
  0% { opacity: 0; transform: translate(0, 40px); }
  15% { opacity: .9; }
  35% { transform: translate(calc(var(--dx) * 10px), -40px); }
  65% { transform: translate(calc(var(--dx) * -10px), -130px); }
  100% { opacity: 0; transform: translate(0, -220px) scale(1.15); }
}
@keyframes peVent {
  0% { opacity: 0; transform: translate(-160px, 0); }
  30% { opacity: .85; }
  70% { opacity: .85; }
  100% { opacity: 0; transform: translate(220px, calc(var(--dx) * 18px)); }
}
@keyframes peTombe {
  0% { opacity: 0; transform: translate(0, -60px) rotate(0); }
  15% { opacity: .9; }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 30px), 200px) rotate(320deg); }
}
@keyframes peScintille {
  0%, 100% { opacity: 0; transform: translateY(0) scale(.2); }
  50% { opacity: 1; transform: translateY(-14px) scale(1); }
}
@keyframes peDerive {
  0% { opacity: 0; transform: translate(0, 0) rotate(45deg) scale(.5); }
  25% { opacity: .95; }
  50% { transform: translate(calc(var(--dx) * 40px), -40px) rotate(135deg) scale(1); }
  100% { opacity: 0; transform: translate(calc(var(--dx) * -30px), -90px) rotate(225deg) scale(.3); }
}

@keyframes apRespireFond {
  from { opacity: .6; transform: translate(-50%, -50%) scale(.94); }
  to   { opacity: .95; transform: translate(-50%, -50%) scale(1.06); }
}
@keyframes apHalo { 50% { transform: scale(1.18); opacity: .7; } }
@keyframes apSceau {
  0%   { transform: translate(-50%, -50%) scale(.3) rotate(-40deg); opacity: 0; }
  70%  { transform: translate(-50%, -50%) scale(1.12) rotate(4deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1) rotate(0); }
}
@keyframes apArrivee { from { transform: scale(.82); } }
@keyframes apChoc {
  0%   { opacity: .9; transform: scale(1); }
  100% { opacity: 0;  transform: scale(1.3, 1.5); }
}
@keyframes apTombe {
  0%   { transform: scale(2.4); opacity: 0; filter: blur(10px); }
  60%  { transform: scale(.94); opacity: 1; filter: blur(0); }
  100% { transform: scale(1); }
}
@keyframes apMonte { from { transform: translateY(8px); opacity: 0; } }
@keyframes apRespire {
  50% { box-shadow: inset 0 0 0 1px rgba(18, 11, 4, .55), inset 0 1px 0 rgba(255, 255, 255, .45),
                    0 0 44px color-mix(in srgb, var(--el) 90%, transparent); transform: scale(1.03); }
}
@keyframes apEncaisse {
  20% { transform: translateX(-9px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(3px); }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .ap-eclat, :where(html:not(.mouvement-plein)) .pe, :where(html:not(.mouvement-plein)) .ap-sceau::after, :where(html:not(.mouvement-plein)) .ap-bouton.majeur,
  :where(html:not(.mouvement-plein)) .annonce-pouvoir.entre *,
  :where(html:not(.mouvement-plein)) .annonce-pouvoir.entre .ap-cadre::before { animation: none !important; }
}
@media (max-width: 620px) {
  .ap-cadre { padding: 50px 16px 26px; }
  .ap-sceau { width: 76px; height: 76px; }
  .ap-cri { font-size: 18px; }
  .ap-texte { font-size: 13px; }
  .ap-gestes { flex-direction: column; }
  .ap-gestes .ap-bouton { width: 100%; }
}

/* ══ ACCUEIL EN DEUX TUILES (12/09/2026) ═══════════════════════════════════
   Tuile 1 : le jeu -- presenter, puis inviter au deck gratuit.
   Tuile 2 : les paquets -- le grimoire au-dessus des cartes et des actions.
   Place en fin de feuille pour primer sur les anciennes regles de blocs. */
.hero-cta-note { margin: 10px 0 14px; font-size: 13px; line-height: 1.5; color: var(--ink-dim); max-width: 460px; }
.hero-cta-note b { color: #ffe699; }
/* Les deux portes du haut sur une ligne, au même format. */
@media (min-width: 761px) {
  .hero-cta-group { flex-wrap: wrap; }
  .hero-cta-group .btn-hero-cta { white-space: nowrap; display: inline-flex; align-items: center; gap: 8px; }
}

.home-booster-altar {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 40px 44px; text-align: center;
}
.home-booster-altar .altar-pack-preview { width: 190px; height: 190px; }
.home-booster-altar .altar-appel { align-items: center; max-width: 900px; width: 100%; gap: 16px; }
.home-booster-altar .appel-ligne { max-width: 620px; }
.home-booster-altar .altar-pack-actions { max-width: 520px; margin-top: 8px; }
.home-booster-altar .vitrine-raretes { max-width: 900px; margin-top: 14px; gap: 16px; }

@media (max-width: 760px) {
  .home-booster-altar { padding: 22px 14px; }
  .home-booster-altar .altar-pack-preview { width: 130px; height: 130px; }
}

/* ══ LA FETE D'ACHAT ═══════════════════════════════════════════════════════
   Une choregraphie en deux temps, calee sur --eclat (fixe par main.js) :
   la TENSION monte (voile, lumiere qui converge, aura, descente, charge),
   puis tout se LIBERE (flash, gerbe qui retombe, texte, compteur).
   Legend (.is-epique) ajoute rayons, ondes et une secousse legere. */
.achat-fete {
  --eclat: 2900ms;
  --doux: cubic-bezier(.22, .8, .24, 1);
  position: fixed; inset: 0; z-index: 140; display: grid; place-items: center;
  padding: 16px; overflow: hidden;
}
.achat-fete.is-sortie { animation: af-sortie .6s ease forwards; }
@keyframes af-sortie { to { opacity: 0; filter: blur(6px); } }

.af-voile {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 34%, color-mix(in srgb, var(--aura) 26%, transparent), rgba(3, 4, 10, .95) 60%);
  backdrop-filter: blur(10px);
  animation: af-fondu 1.2s ease both;
}
@keyframes af-fondu { from { opacity: 0; backdrop-filter: blur(0); } }

.af-flash {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at 50% 32%, #fff 0%, color-mix(in srgb, var(--aura) 60%, transparent) 25%, transparent 60%);
  animation: af-flash 1.4s ease-out var(--eclat) both;
}
@keyframes af-flash { 0% { opacity: 0; } 12% { opacity: .9; } 100% { opacity: 0; } }

.af-scene { position: absolute; left: 50%; top: 32%; width: 0; height: 0; pointer-events: none; }

/* Le halo grandit pendant toute la tension, puis respire. */
.af-halo {
  position: absolute; width: 460px; height: 460px; left: -230px; top: -230px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--aura) 85%, transparent) 0%, transparent 64%);
  filter: blur(22px); opacity: 0;
  animation: af-halo-monte var(--eclat) ease-in .3s both, af-halo-respire 3.4s ease-in-out calc(var(--eclat) + .3s) infinite;
}
@keyframes af-halo-monte { from { opacity: 0; transform: scale(.15); } to { opacity: .85; transform: scale(1); } }
@keyframes af-halo-respire { 0%, 100% { opacity: .85; transform: scale(1); } 50% { opacity: .55; transform: scale(1.12); } }

/* La lumiere converge vers le livre. */
.af-convergence i {
  position: absolute; left: -2px; top: -2px; width: 4px; height: 4px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 8px 2px var(--aura); opacity: 0;
  animation: af-converge 1.6s cubic-bezier(.55, 0, .8, .4) var(--d) both;
}
@keyframes af-converge {
  0% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.4); }
  30% { opacity: 1; }
  /* Elle s'eteint en entrant dans le livre, sans s'accumuler au centre. */
  85% { opacity: 0; transform: translate(calc(var(--dx) * .08), calc(var(--dy) * .08)) scale(.8); }
  100% { opacity: 0; transform: translate(0, 0) scale(.5); }
}

/* Le grimoire descend, se charge, puis flotte. */
.af-grimoire {
  position: absolute; width: 230px; height: 230px; left: -115px; top: -115px; object-fit: contain;
  filter: drop-shadow(0 24px 30px rgba(0, 0, 0, .8)) drop-shadow(0 0 30px var(--aura));
  opacity: 0;
  animation:
    af-descente 1.7s var(--doux) .1s both,
    af-charge .7s ease-in-out calc(var(--eclat) - .7s),
    af-flotte 4.5s ease-in-out calc(var(--eclat) + .2s) infinite;
}
@keyframes af-descente {
  0% { opacity: 0; transform: translateY(-46vh) scale(.72) rotate(-6deg); filter: blur(8px) drop-shadow(0 0 0 transparent); }
  45% { opacity: 1; }
  100% { opacity: 1; transform: translateY(0) scale(1) rotate(0); filter: drop-shadow(0 24px 30px rgba(0, 0, 0, .8)) drop-shadow(0 0 30px var(--aura)); }
}
@keyframes af-charge {
  0% { opacity: 1; transform: scale(1); }
  70% { opacity: 1; transform: scale(.94); filter: brightness(1.5) drop-shadow(0 0 50px var(--aura)); }
  100% { opacity: 1; transform: scale(1.08); filter: brightness(1.2) drop-shadow(0 0 70px var(--aura)); }
}
@keyframes af-flotte {
  0%, 100% { opacity: 1; transform: translateY(0) scale(1.04); }
  50% { opacity: 1; transform: translateY(-12px) scale(1.04); }
}

/* La gerbe jaillit a l'eclat, puis retombe lentement. */
.af-gerbe i {
  position: absolute; left: 0; top: 0; width: var(--taille); height: var(--taille); border-radius: 50%;
  background: #fff; box-shadow: 0 0 12px 3px var(--aura); opacity: 0;
  /* `forwards` et non `both` : avec `both`, les 90 etincelles attendaient
     l'eclat deja allumees, empilees au centre -- un rond bleu sur le livre. */
  animation: af-etincelle var(--t) cubic-bezier(.12, .7, .3, 1) calc(var(--eclat) + var(--d)) forwards;
}
@keyframes af-etincelle {
  0% { opacity: 0; transform: translate(0, 0) scale(1.3); }
  4% { opacity: 1; }
  55% { opacity: .95; transform: translate(var(--dx), var(--dy)) scale(1); }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 1.12), calc(var(--dy) + 180px)) scale(.3); }
}

/* Le texte se revele etape par etape. */
.af-panneau {
  position: relative; margin-top: 32vh; width: min(480px, 100%);
  display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center;
}
.af-etape { opacity: 0; animation: af-revele 1s var(--doux) var(--r) both; }
@keyframes af-revele { from { opacity: 0; transform: translateY(18px); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }
.af-titre.af-etape { animation-name: af-titre; animation-duration: 1.4s; }
@keyframes af-titre {
  from { opacity: 0; letter-spacing: .35em; filter: blur(10px); }
  to { opacity: 1; letter-spacing: .02em; filter: none; }
}
.af-kicker { font-family: var(--font-title); font-size: 12px; font-weight: 900; letter-spacing: .3em; color: var(--aura); }
.af-titre {
  margin: 0; font-family: var(--font-title); font-size: 40px; font-weight: 900; line-height: 1.05; letter-spacing: .02em;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.af-compte { display: flex; align-items: baseline; gap: 10px; }
.af-compte b {
  font-size: 66px; font-weight: 900; line-height: 1; color: #fff; font-variant-numeric: tabular-nums;
  text-shadow: 0 0 30px var(--aura); transition: transform .5s var(--doux), text-shadow .5s ease;
}
.af-compte.is-arrive b { animation: af-arrive .7s var(--doux); text-shadow: 0 0 44px var(--aura), 0 0 90px var(--aura); }
@keyframes af-arrive { 40% { transform: scale(1.18); } 100% { transform: scale(1); } }
.af-compte span { font-size: 20px; font-weight: 800; color: var(--ink-dim); }
.af-bonus {
  padding: 5px 12px; border-radius: 8px; font-size: 12px; font-weight: 900; letter-spacing: .06em;
  background: linear-gradient(135deg, #ff5f6d, #ffc371); color: #1a0d05;
}
.af-merci { margin: 2px 0 8px; font-size: 15.5px; line-height: 1.6; color: var(--ink); }
.af-ouvrir {
  width: 100%; padding: 17px 24px; border: 0; border-radius: 14px; cursor: pointer;
  font-size: 18px; font-weight: 900; letter-spacing: .06em; text-transform: uppercase; color: #fff;
  background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 55%, #ffc24a 100%);
  box-shadow: 0 10px 30px rgba(255, 80, 90, .45);
}
.af-ouvrir.af-etape { animation: af-revele 1s var(--doux) var(--r) both, cta-halo 2.4s ease-in-out calc(var(--r) + 1s) infinite; }
.af-ouvrir:hover:not(:disabled) { transform: translateY(-2px) scale(1.02); background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 55%, #ffc24a 100%); }
.af-plus-tard { background: none; border: 0; color: var(--ink-dim); font-size: 13px; cursor: pointer; padding: 4px 10px; }
.af-plus-tard:hover:not(:disabled) { background: none; color: #fff; text-decoration: underline; }
.af-note { font-size: 11px; color: var(--ink-dim); }
.af-note.af-etape { animation-name: af-note; }
@keyframes af-note { from { opacity: 0; } to { opacity: .6; } }

/* Legend : la version epique. */
.achat-fete.is-epique .af-grimoire { width: 290px; height: 290px; left: -145px; top: -145px; }
.achat-fete.is-epique .af-titre { font-size: 48px; }
.achat-fete.is-epique .af-compte b { font-size: 86px; }
.af-rayons {
  position: absolute; width: 1600px; height: 1600px; left: -800px; top: -800px; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--aura) 30%, transparent) 0deg 5deg, transparent 5deg 15deg);
  -webkit-mask: radial-gradient(circle, #000 0%, transparent 58%); mask: radial-gradient(circle, #000 0%, transparent 58%);
  opacity: 0;
  animation: af-rayons-in 2.4s ease var(--eclat) forwards, af-tourne 60s linear infinite;
}
@keyframes af-rayons-in { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
@keyframes af-tourne { to { rotate: 360deg; } }
.af-onde {
  position: absolute; width: 40px; height: 40px; left: -20px; top: -20px; border-radius: 50%;
  border: 3px solid var(--aura); box-shadow: 0 0 20px var(--aura); opacity: 0;
  animation: af-onde 1.8s cubic-bezier(.1, .6, .3, 1) var(--eclat) both;
}
.af-onde-2 { animation-delay: calc(var(--eclat) + .35s); border-width: 2px; }
@keyframes af-onde { 0% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(28); } }
body.secousse-epique { animation: af-secousse .8s ease-out; }
@keyframes af-secousse {
  0%, 100% { transform: none; } 15% { transform: translate(-4px, 2px); } 30% { transform: translate(4px, -3px); }
  50% { transform: translate(-2px, 2px); } 70% { transform: translate(2px, -1px); } 85% { transform: translate(-1px, 0); }
}

@media (max-width: 760px) {
  .af-grimoire, .achat-fete.is-epique .af-grimoire { width: 170px; height: 170px; left: -85px; top: -85px; }
  .af-scene { top: 24%; }
  .af-panneau { margin-top: 38vh; }
  .af-titre, .achat-fete.is-epique .af-titre { font-size: 30px; }
  .af-compte b, .achat-fete.is-epique .af-compte b { font-size: 56px; }
}
/*  ECRAN BAS (22/10/2026, tele 4K a 300 % : 1280 x 595 CSS). Le livre a 32 %
 *  de la hauteur et le texte pousse de 32 vh : le titre passait sous le livre
 *  et le bouton sortait de l'ecran. Ici tout se compte en hauteur d'ecran,
 *  le texte part juste sous le livre, et s'etale en largeur plutot qu'en
 *  hauteur. */
@media (min-width: 761px) and (max-height: 760px) {
  .achat-fete { place-items: start center; }
  .af-scene { top: 21vh; }
  .af-grimoire { width: 30vh; height: 30vh; left: -15vh; top: -15vh; }
  .achat-fete.is-epique .af-grimoire { width: 32vh; height: 32vh; left: -16vh; top: -16vh; }
  .af-halo { width: 60vh; height: 60vh; left: -30vh; top: -30vh; }
  .af-panneau { margin-top: calc(38vh - 16px); width: min(760px, 100%); gap: 6px; }
  .af-titre, .achat-fete.is-epique .af-titre { font-size: min(34px, 5.6vh); }
  .af-compte b, .achat-fete.is-epique .af-compte b { font-size: min(64px, 10vh); }
  .af-compte span { font-size: 17px; }
  .af-merci { margin: 0 0 4px; font-size: 14px; line-height: 1.45; }
  .af-ouvrir { width: min(480px, 100%); padding: 12px 22px; font-size: 16px; }
  .af-plus-tard { padding: 2px 10px; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .achat-fete *, :where(html:not(.mouvement-plein)) body.secousse-epique { animation-duration: .01s !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; }
}

/* La lumiere s'accumule DERRIERE le livre ; la gerbe jaillit devant. */
.af-halo { z-index: 0; }
.af-rayons, .af-onde { z-index: 0; }
.af-convergence { position: absolute; z-index: 1; }
.af-grimoire { z-index: 3; }
.af-gerbe { position: absolute; z-index: 4; }

/* Le ×2 s'abat, puis le compteur double dans un second eclat. */
.af-bonus.af-etape {
  font-size: 20px; padding: 8px 18px; border-radius: 12px;
  box-shadow: 0 0 30px rgba(255, 95, 109, .6);
  animation: af-tampon .7s cubic-bezier(.2, 1.6, .4, 1) var(--r) both;
}
@keyframes af-tampon {
  0% { opacity: 0; transform: scale(3) rotate(-8deg); filter: blur(4px); }
  60% { opacity: 1; transform: scale(.92) rotate(2deg); filter: none; }
  100% { opacity: 1; transform: scale(1) rotate(-2deg); }
}
.af-compte.is-double b {
  background: linear-gradient(135deg, #ffe699, #ff7a3d); -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: none; filter: drop-shadow(0 0 24px rgba(255, 122, 61, .8));
}
.af-detail { font-size: 14px; font-weight: 800; color: #ffe699; letter-spacing: .04em; }

/* L'ECLAT NAIT DERRIERE LE LIVRE.
   Au premier instant, les 90 etincelles etaient empilees au centre, allumees
   et au premier plan : un point blanc devant le grimoire. Elles passent
   derriere lui et ne s'allument qu'une fois sorties de sa silhouette. */
.af-gerbe { z-index: 2; }
@keyframes af-etincelle {
  0% { opacity: 0; transform: translate(calc(var(--dx) * .1), calc(var(--dy) * .1)) scale(1); }
  12% { opacity: 1; transform: translate(calc(var(--dx) * .3), calc(var(--dy) * .3)) scale(1.3); }
  55% { opacity: .95; transform: translate(var(--dx), var(--dy)) scale(1); }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 1.12), calc(var(--dy) + 180px)) scale(.3); }
}

/* ══ OUVRIR SES GRIMOIRES : L'INVITATION ET LE LOT ════════════════════════ */
.altar-invite {
  position: absolute; left: 50%; bottom: -34px; transform: translateX(-50%); z-index: 2;
  white-space: nowrap; font-size: 13px; font-weight: 800; letter-spacing: .03em; color: #ffe699;
  text-shadow: 0 0 12px rgba(245, 185, 66, .6); animation: altar-invite 2.4s ease-in-out infinite;
}
@keyframes altar-invite { 50% { opacity: .6; } }
.home-booster-altar .altar-pack-side { padding-bottom: 30px; }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .altar-invite { animation: none; } }

.rip-choix { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
/*  « OUVRIR 10 D'UN COUP » : LE HALO NE REPEINT PLUS SOUS LE TEXTE.
 *
 *  Le bouton portait `cta-halo`, qui anime un box-shadow -- quarante-quatre
 *  pixels de flou et un anneau de six. A chaque image, le navigateur repeint
 *  cette ombre, et le texte pose dessus est redessine avec elle : c'est lui
 *  qui tremble. Le defaut se voit surtout ici parce que c'est le bouton le
 *  plus long, donc celui dont le texte occupe le plus de surface repeinte.
 *
 *  Le halo passe sur une couche a part dont on ne fait varier que l'opacite.
 *  Meme battement, aucun repeint.
 *
 *  ET LE TEXTE NE SE COUPE PLUS. « OUVRIR 10 D'UN COUP » tenait sur une ligne
 *  ou deux selon la largeur restante, et changeait d'avis pendant que le halo
 *  pulsait -- la ligne sautait. Il reste d'un bloc ; c'est la rangee qui passe
 *  a la ligne, pas le mot. */
.btn-rip-lot {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer; white-space: nowrap; max-width: 100%;
  padding: 12px 22px; border: 0; border-radius: 12px;
  font-weight: 900; letter-spacing: .06em; color: #fff;
  background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 55%, #ffc24a 100%);
  box-shadow: 0 8px 26px rgba(255, 80, 90, .45);
}
.btn-rip-lot::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 10px 44px rgba(255, 80, 90, .8), 0 0 0 6px rgba(255, 122, 61, .18);
  opacity: 0; will-change: opacity;
  animation: halo-respire 2.4s ease-in-out infinite;
}
@keyframes halo-respire { 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .btn-rip-lot::after { animation: none; } }
/*  Au telephone, le mot passe avant l'ampleur du bouton. */
@media (max-width: 700px) {
  .btn-rip-lot { padding: 11px 14px; letter-spacing: .03em; font-size: 13px; }
  .rip-choix { gap: 8px; }
}
.btn-rip-lot:hover:not(:disabled) { transform: translateY(-2px); background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 55%, #ffc24a 100%); }
.rip-en-main { font-size: 12.5px; font-weight: 700; color: #ffe699; opacity: .85; }

/* La liasse : ses couches montent en escalier, la derniere porte le halo. */

/* La revelation d'un lot : une grille serree de petites cartes, qui defile. */
.cards-reveal-area.is-lot { padding: 16px 12px 24px; }
.reveal-cards-row.is-lot {
  display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 8px;
  width: min(1180px, 100%); max-width: none;
}
.reveal-cards-row.is-lot .reveal-card-slot { width: auto; height: auto; aspect-ratio: 184 / 280; }
@media (max-width: 900px) { .reveal-cards-row.is-lot { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
/*  ECRAN BAS (22/10/2026, tele 4K a 300 % : 1280 x 595 CSS). La grille
 *  prenait toute la largeur : dix cartes de 160 px, chacune plus haute que
 *  le quart de l'ecran. Sa largeur suit aussi la hauteur, et l'en-tete se
 *  resserre : deux rangees et demie se voient sans defiler. */
@media (min-width: 901px) and (max-height: 760px) {
  .reveal-cards-row.is-lot { width: min(1180px, 100%, 150vh); gap: 6px; }
  .cards-reveal-area.is-lot { padding-top: 6px; }
  .cards-reveal-area.is-lot .reveal-header { margin-bottom: 6px; }
  .cards-reveal-area.is-lot .reveal-title { font-size: 26px; margin: 2px 0; }
  .cards-reveal-area.is-lot .reveal-hint { margin: 0; font-size: 13px; }
  .cards-reveal-area.is-lot .reveal-header::after { display: none; }
}

/* ══ CARTES REVELEES : NETTES, ET LES RARES QUI RESSORTENT ════════════════
   Le contour jaune etait une bordure posee sur TOUTE face. Le liseré noir,
   le fond sombre de la face : son format (184 x 280) ne suivait pas celui
   des cartes (320 x 503), et ce fond passait sur les bords et dans les coins
   arrondis -- transparents -- de l'image. La face prend donc le format exact
   de la carte, sans fond, sans bordure, sans ombre propre. */
.reveal-card-slot { height: auto; aspect-ratio: 320 / 503; }
.card-face-front {
  border: 0; background: transparent; box-shadow: none; border-radius: 0; overflow: visible;
}
.card-face-front img { object-fit: contain; }
.reveal-cards-row.is-lot .reveal-card-slot { aspect-ratio: 320 / 503; }

/* Dans un lot, l'oeil doit trouver les Rares et au-dessus parmi soixante-dix
   cartes : les Communes et Peu communes retournees s'effacent, les autres
   s'avancent. Un paquet seul garde son devoilement habituel. */
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-commune,
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-peu-commune {
  filter: brightness(.55) saturate(.7); box-shadow: none;
}
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-rare,
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-epique,
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-legendaire,
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-mythique {
  transform: scale(1.08); z-index: 5;
}
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-commune:hover,
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-peu-commune:hover { filter: none; }

/* LA PASTILLE « NEW ».
   Le bandeau « NOUVELLE ! » barrait le haut de la carte, et dans un lot de
   soixante-dix il couvrait le nom d'une carte sur deux. Une pastille jaune
   dans le coin haut droit suffit a la signaler sans rien cacher. */
.badge-new-card {
  top: 6px; right: 6px; left: auto; transform: none;
  font-family: var(--font-body, inherit); font-size: 9px; font-weight: 900; letter-spacing: .08em;
  line-height: 1; padding: 3px 6px; border-radius: 999px; white-space: nowrap;
  background: #ffd23f; color: #1a1300; border: 0;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .6), 0 0 10px rgba(255, 210, 63, .7);
  animation: newPastille .45s cubic-bezier(.2, 1.5, .4, 1) both;
}
@keyframes newPastille { from { transform: scale(0); } to { transform: scale(1); } }
.reveal-cards-row.is-lot .badge-new-card { top: 4px; right: 4px; font-size: 7.5px; padding: 2px 5px; }
@media (max-width: 760px) { .badge-new-card { top: 3px; right: 3px; font-size: 6.5px; padding: 2px 4px; } }

/* ══ LA RECOMPENSE REELLE : COLLECTION, RARETE, EXEMPLAIRES ══════════════ */
.pull-score-banner { flex-wrap: wrap; }
.pull-gain {
  flex: 1 1 100%; display: flex; flex-direction: column; gap: 6px;
  padding-bottom: 12px; margin-bottom: 4px; border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.pull-gain-ligne { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.pull-gain-ligne b {
  font-size: 40px; font-weight: 900; line-height: 1; color: #ffd23f;
  text-shadow: 0 0 20px rgba(255, 210, 63, .55);
}
.pull-gain-ligne span { font-size: 17px; font-weight: 800; color: #fff; }
.pull-gain-barre { height: 8px; border-radius: 99px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.pull-gain-barre i {
  display: block; height: 100%; border-radius: inherit;
  background: linear-gradient(90deg, #ffd23f, #ff7a3d);
  animation: gain-barre 1.4s cubic-bezier(.22, .8, .24, 1) both;
}
@keyframes gain-barre { from { width: 0; } }
.pull-gain-total { font-size: 12px; color: var(--ink-dim); }

/*  LE BILAN, AU TELEPHONE : UN BANDEAU, PAS UN PANNEAU.
 *
 *  Il etait dessine pour 840 px de large et gardait ses mesures de bureau sur
 *  355 : un « +8 » de quarante pixels, un titre d'incantation, une pastille de
 *  score et cinq etoiles, le tout empile sur pres de 250 px -- soit un tiers
 *  de l'ecran mange par le resume, juste au-dessus des cartes qu'on veut
 *  voir. Il se resserre a une centaine de pixels : le chiffre reste le plus
 *  gros element, le reste passe en seconde ligne.
 *
 *  Ces regles sont ICI, apres `.pull-score-banner { flex-wrap: wrap }`, et
 *  non dans le bloc telephone plus haut : a specificite egale c'est la
 *  derniere ecrite qui gagne, media query ou pas -- le `nowrap` d'en haut
 *  etait deja annule par ce `wrap`. */
@media (max-width: 700px) {
  .pull-score-banner {
    width: 100%; padding: 9px 12px 10px; gap: 6px 10px; border-radius: 10px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .7), 0 0 10px rgba(201, 162, 70, .16);
  }
  .pull-gain { gap: 4px; padding-bottom: 8px; margin-bottom: 0; }
  .pull-gain-ligne { gap: 7px; }
  .pull-gain-ligne b { font-size: 26px; text-shadow: 0 0 12px rgba(255, 210, 63, .45); }
  .pull-gain-ligne span { font-size: 12.5px; font-weight: 700; }
  .pull-gain-barre { height: 5px; }
  .pull-gain-total { font-size: 10px; }
  .pull-score-kicker { font-size: 7.5px; letter-spacing: .14em; }
  .pull-rating-title { font-size: 12.5px; }
  .pull-score-right { gap: 8px; }
  .pull-score-badge { padding: 2px 7px; border-radius: 6px; border-width: 1px; box-shadow: 0 0 8px rgba(245, 185, 66, .3); }
  .score-val { font-size: 14px; }
  .score-lbl { font-size: 6px; letter-spacing: .08em; }
  .pull-score-stars { font-size: 11px; letter-spacing: .5px; }
}

/* Rare et au-dessus : l'etiquette de ses exemplaires, et un halo qui reste. */
.tag-exemplaires {
  position: absolute; left: 50%; bottom: 5px; transform: translateX(-50%); z-index: 6;
  white-space: nowrap; font-size: 9px; font-weight: 900; letter-spacing: .03em;
  padding: 2px 7px; border-radius: 999px; color: #0b0d12; background: var(--rc);
  box-shadow: 0 0 10px var(--rc);
}
.reveal-cards-row.is-lot .tag-exemplaires { font-size: 7px; padding: 1px 5px; bottom: 3px; }

/* Epique et au-dessus : la carte vient seule au centre. */
.moment-rarete {
  position: fixed; inset: 0; z-index: 150; display: grid; place-items: center; cursor: pointer;
  animation: mr-entree .35s ease both;
}
.moment-rarete.is-sortie { animation: mr-sortie .45s ease forwards; }
@keyframes mr-entree { from { opacity: 0; } }
@keyframes mr-sortie { to { opacity: 0; } }
.mr-voile {
  position: absolute; inset: 0;
  background: radial-gradient(circle, color-mix(in srgb, var(--rc) 22%, transparent) 0%, rgba(3, 4, 10, .78) 60%);
  backdrop-filter: blur(4px);
}
.moment-rarete.is-supreme .mr-voile {
  background: radial-gradient(circle, color-mix(in srgb, var(--rc) 30%, transparent) 0%, rgba(0, 0, 0, .95) 55%);
}
.mr-rayons { display: none; }
/*  Plus de soleil a rayons derriere les cartes d'exception (« l'effet soleil
 *  manga que je ne veux pas », 29/10/2026) : une lueur douce de la couleur
 *  de la rarete, qui respire. */
.moment-rarete.is-supreme .mr-rayons {
  display: block; position: absolute; left: 50%; top: 42%; width: 1100px; height: 1100px; margin: -550px 0 0 -550px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--rc) 34%, transparent) 0%,
    color-mix(in srgb, var(--rc) 10%, transparent) 38%, transparent 62%);
  animation: mr-respire 3.2s ease-in-out infinite;
}
@keyframes mr-respire { 50% { opacity: .65; scale: 1.06; } }
.mr-carte {
  position: relative; width: min(300px, 62vw); height: auto; margin-bottom: 120px;
  filter: drop-shadow(0 20px 40px rgba(0, 0, 0, .8)) drop-shadow(0 0 40px var(--rc));
  animation: mr-carte .8s cubic-bezier(.2, 1.3, .4, 1) both;
}
.moment-rarete.is-supreme .mr-carte { width: min(340px, 70vw); animation-duration: 1.1s; }
@keyframes mr-carte {
  0% { opacity: 0; transform: scale(.3) rotateY(90deg); }
  100% { opacity: 1; transform: scale(1) rotateY(0); }
}
.mr-texte {
  position: absolute; left: 0; right: 0; bottom: 8vh; display: flex; flex-direction: column; align-items: center; gap: 4px;
  text-align: center; animation: af-revele .7s cubic-bezier(.22, .8, .24, 1) .45s both;
}
.mr-rarete { font-family: var(--font-title); font-size: 14px; font-weight: 900; letter-spacing: .3em; text-transform: uppercase; color: var(--rc); }
.mr-nom { font-family: var(--font-title); font-size: 34px; font-weight: 900; color: #fff; text-shadow: 0 0 24px var(--rc); }
.mr-ex { font-size: 14px; font-weight: 800; color: #ffe699; }
@media (max-width: 760px) { .mr-carte { margin-bottom: 140px; } .mr-nom { font-size: 24px; } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .mr-carte, :where(html:not(.mouvement-plein)) .mr-rayons { animation: none; } }

/* La scene attend le joueur : compteur de serie, et invitation a continuer. */
.mr-compteur {
  position: absolute; top: 24px; left: 50%; transform: translateX(-50%); z-index: 2;
  font-size: 14px; font-weight: 900; letter-spacing: .12em; color: #fff;
  padding: 4px 12px; border-radius: 999px; background: rgba(255, 255, 255, .1);
}
.mr-compteur:empty { display: none; }
.mr-suite {
  margin-top: 10px; font-size: 13px; font-weight: 700; color: var(--ink-dim); opacity: 0;
  transition: opacity .4s ease;
}
.moment-rarete.is-prete .mr-suite { opacity: 1; animation: altar-invite 2s ease-in-out infinite; }
.moment-rarete:not(.is-prete) { cursor: default; }
/* La Rare : la meme scene, en plus sobre. */
.moment-rarete.is-rare .mr-voile {
  background: radial-gradient(circle, color-mix(in srgb, var(--rc) 16%, transparent) 0%, rgba(3, 4, 10, .7) 60%);
}
.moment-rarete.is-rare .mr-carte { width: min(260px, 56vw); }

/* LE SURVOL GAGNE, MEME DANS UN LOT.
   La mise en avant des Rares (`scale(1.08)`) etait plus specifique que le
   zoom de survol et l'ecrasait : ces cartes restaient figees. Meme chose
   pour le filtre des Communes, qui effacait l'ombre du zoom. On reprend le
   zoom normal, a specificite egale, pour toutes les raretes. */
.reveal-cards-row.is-lot .reveal-card-slot.is-flipped[class*="glow-"]:hover {
  /*  Le meme leger zoom sur place qu'hors lot : a 1,55 la carte montait
      recouvrir ses voisines et le titre (Alexandre, 10/10/2026). */
  transform: scale(1.06);
  transform-origin: 50% 50%;
  z-index: 60;
  filter: drop-shadow(0 10px 16px rgba(0, 0, 0, .85))
          drop-shadow(0 0 22px var(--card-glow, #f5b942));
}

/* ══ LE REFLET NE SE COUPE PLUS NET ═══════════════════════════════════════
   Les calques de lumiere sont des degrades STRIES, plus grands que la carte
   (220 %), qu'on faisait glisser jusqu'a 170 % -- au-dela de la carte. Le
   fond sortait donc du cadre et le navigateur le REPETAIT en mosaique : les
   stries penchees ne se raccordent pas d'une tuile a l'autre, et le
   raccord se lisait comme une ligne droite qui coupe la lumiere.
   On garde la meme lumiere, mais elle ne glisse plus que dans l'intervalle
   ou le fond couvre toute la carte (position de 0 a 100 %) : plus aucune
   tuile, plus aucun raccord. */
.card-face-front[style*="--fili"] .bc-filigrane > i,
.cart-vitre[style*="--fili"] .cart-filigrane > i,
.zoom-filigrane > i {
  background-repeat: no-repeat;
  background-position: calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
}
.vernis-iris {
  background-repeat: no-repeat, no-repeat;
  background-position:
    calc(var(--mx) * 100%) calc(var(--my) * 100%),
    calc((1 - var(--mx)) * 100%) calc((1 - var(--my)) * 100%);
}

/* ══ LA MARGE NOIRE DU RENDU, RECOUPEE PARTOUT ════════════════════════════
   Chaque rendu de carte porte ~1,4 % de marge noire autour du liseré. Le
   cartable et la loupe la recoupent deja (`--carte-marge`) ; la revelation
   des paquets, la scene de rarete et la vitrine de l'accueil ne le faisaient
   pas -- d'ou le contour noir autour de la carte, surtout visible au zoom.
   Meme coupe, meme source. */
.card-face-front { clip-path: inset(var(--carte-marge, 1.4%) round 7px); }
.mr-carte { clip-path: inset(var(--carte-marge, 1.4%) round 12px); }
.vr-carte img { clip-path: inset(var(--carte-marge, 1.4%) round 5px); }
/* La pastille NEW et l'etiquette d'exemplaires restent a l'interieur de la
   coupe : on les rentre d'autant. */
.card-face-front .badge-new-card { top: calc(var(--carte-marge, 1.4%) + 5px); right: calc(var(--carte-marge, 1.4%) + 5px); }
.card-face-front .tag-exemplaires { bottom: calc(var(--carte-marge, 1.4%) + 4px); }

/* La scene de rarete : la lueur et l'entree passent au cadre, l'image seule
   est rognee de sa marge noire. */
.mr-cadre {
  position: relative; width: min(300px, 62vw); margin-bottom: 120px;
  filter: drop-shadow(0 20px 40px rgba(0, 0, 0, .8)) drop-shadow(0 0 40px var(--rc));
  animation: mr-carte .8s cubic-bezier(.2, 1.3, .4, 1) both;
}
.moment-rarete.is-supreme .mr-cadre { width: min(340px, 70vw); animation-duration: 1.1s; }
.moment-rarete.is-rare .mr-cadre { width: min(260px, 56vw); }
.mr-cadre .mr-carte { display: block; width: 100%; margin: 0; filter: none; animation: none; }
@media (max-width: 760px) { .mr-cadre { margin-bottom: 140px; } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .mr-cadre { animation: none; } }
/* La vitrine : plus de fond sombre derriere la marge recoupee. */
.vr-carte { background: transparent; }

/* ══ LA VITRINE DU TIRAGE ═════════════════════════════════════════════════
   Apres le devoilement complet : les Rares et plus, ensemble, puis on ferme
   pour voir la pioche entiere. */
.vitrine-tirage {
  position: fixed; inset: 0; z-index: 150; display: grid; place-items: center;
  padding: 20px; overflow-y: auto; animation: mr-entree .4s ease both;
}
.vitrine-tirage.is-sortie { animation: mr-sortie .4s ease forwards; }
.vitrine-tirage .mr-voile { position: fixed; }
/* Avec les cartes 3D, la pioche retournee ne doit plus se voir derriere :
   le voile devient sombre partout, la lueur de rarete par-dessus. */
.vitrine-tirage.est-3d .mr-voile {
  background:
    radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--rc) 18%, transparent) 0%, transparent 60%),
    rgba(3, 4, 10, .94);
  /* Pas de flou : sous un voile a 94 % il ne se voit pas, et un flou plein
     ecran coute plus cher au telephone que les cartes 3D elles-memes. */
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.vitrine-tirage.is-supreme .mr-rayons {
  display: block; position: fixed; left: 50%; top: 45%; width: 1100px; height: 1100px; margin: -550px 0 0 -550px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--rc) 30%, transparent) 0%,
    color-mix(in srgb, var(--rc) 9%, transparent) 38%, transparent 62%);
  animation: mr-respire 3.2s ease-in-out infinite;
}
.vt-panneau {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 14px;
  width: min(1100px, 100%); text-align: center;
}
.vt-kicker { font-family: var(--font-title); font-size: 13px; font-weight: 900; letter-spacing: .3em; color: var(--rc); }
.vt-titre {
  margin: 0; font-family: var(--font-title); font-size: 38px; font-weight: 900;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.vt-grille { display: flex; flex-wrap: wrap; justify-content: center; gap: 22px; margin: 10px 0 8px; }
.vt-item {
  position: relative; width: 200px; display: flex; flex-direction: column; align-items: center; gap: 4px;
  cursor: zoom-in; animation: mr-carte .8s cubic-bezier(.2, 1.3, .4, 1) calc(var(--i) * 180ms + 200ms) both;
}
.vt-item img {
  width: 100%; height: auto; display: block; clip-path: inset(var(--carte-marge, 1.4%) round 10px);
  filter: drop-shadow(0 0 22px var(--rc)); transition: transform .3s ease;
}
.vt-item:hover img { transform: translateY(-6px) scale(1.04); }
/* La carte 3D (js/carte3d.js) prend la place de l'image (`?sans3d` la coupe).
   La toile deborde un peu de la colonne pour que la carte, qui tourne, ait
   la meme taille a l'ecran que l'image plate qu'elle remplace. */
.vt-item .vt-3d {
  display: block; width: 122%; margin: -6% -11% -2%; aspect-ratio: .70;
  filter: drop-shadow(0 0 22px var(--rc)); cursor: grab; touch-action: pan-y;
}
.vt-rarete { margin-top: 6px; font-size: 12px; font-weight: 900; letter-spacing: .2em; text-transform: uppercase; color: var(--rc); }
.vt-nom { font-family: var(--font-title); font-size: 18px; color: #fff; }
.vt-ex { font-size: 12px; font-weight: 800; color: #ffe699; }
.vt-new {
  position: absolute; top: 8px; right: 8px; font-size: 10px; font-weight: 900; padding: 3px 7px;
  border-radius: 999px; background: #ffd23f; color: #1a1300;
}
.vt-fermer { width: auto; padding: 15px 36px; }

/*  LA VITRINE AU TELEPHONE : UNE PAGE A ELLE, PAS UNE NAPPE TRANSPARENTE.
 *
 *  Trois defauts se cumulaient, et ils se voyaient tous les trois d'un coup.
 *  Le voile laissait passer la grille du devoilement -- des cartes derriere
 *  des cartes, on ne savait plus laquelle etait mise en avant. Le panneau
 *  etait centre (`place-items: center`) alors qu'il depasse la hauteur de
 *  l'ecran : le titre sortait par le haut et se melangeait a l'en-tete du
 *  rituel. Et `width: 42vw` sur un flux libre laissait la largeur decider du
 *  nombre par rangee, donc des rangees depareillees.
 *
 *  On accroche donc en haut, on ferme le voile, et la grille devient DEUX
 *  colonnes franches -- ou UNE seule quand il n'y a qu'une carte, qui a alors
 *  droit a toute la largeur. */
@media (max-width: 760px) {
  .vitrine-tirage {
    place-items: start center;
    padding: 18px 14px calc(18px + env(safe-area-inset-bottom));
  }
  .vitrine-tirage .mr-voile {
    background:
      radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--rc) 20%, transparent) 0%, transparent 62%),
      rgba(4, 5, 12, .96);
    backdrop-filter: blur(10px);
  }
  .vt-panneau { gap: 10px; }
  .vt-kicker { font-size: 10px; letter-spacing: .24em; }
  .vt-titre { font-size: 24px; line-height: 1.1; }
  .vt-grille {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 12px; margin: 4px 0 2px; width: 100%;
  }
  /* Une seule piece maitresse : elle occupe le milieu, pas une demi-largeur
     posee a gauche d'un vide. */
  .vt-grille:has(.vt-item:only-child) { grid-template-columns: min(62%, 240px); justify-content: center; }
  /* Un nombre impair de cartes : la derniere, seule sur sa rangee, se centre
     au lieu de rester a gauche d'un vide. Meme largeur qu'une colonne. */
  .vt-grille > .vt-item:last-child:nth-child(odd):not(:only-child) {
    grid-column: 1 / -1; justify-self: center; width: calc((100% - 12px) / 2);
  }
  .vt-item { width: auto; gap: 2px; }
  .vt-item img { filter: drop-shadow(0 0 14px var(--rc)); }
  /* Deux colonnes : la toile 3D reste dans la sienne, sans deborder sur la voisine. */
  .vt-item .vt-3d { width: 100%; margin: -4% 0 0; filter: drop-shadow(0 0 14px var(--rc)); }
  .vt-rarete { margin-top: 4px; font-size: 10px; letter-spacing: .16em; }
  .vt-nom { font-size: 15px; line-height: 1.15; }
  .vt-ex { font-size: 10px; }
  .vt-new { top: 5px; right: 5px; font-size: 8px; padding: 2px 5px; }
  /* « Voir toute ma pioche » reste sous le pouce meme quand six cartes
     d'exception font defiler la vitrine. */
  .vt-fermer {
    position: sticky; bottom: 0; z-index: 2;
    width: 100%; padding: 13px 18px; font-size: 14px;
  }
}
/* Au-dela de deux rangees (six cartes et plus), les vignettes retrecissent
   plutot que de pousser le bouton hors de l'ecran. */
@media (max-width: 760px) and (max-height: 720px) {
  .vt-titre { font-size: 21px; }
  .vt-grille { gap: 10px 10px; }
}

/* ══ LE FILIGRANE DES ENERGIES ════════════════════════════════════════════
   Sur toute la carte, sans decoupe, et tres leger : une trame a peine
   visible au repos, un reflet discret quand on penche la carte. */
[style*="--fili-energie"] .bc-filigrane > i,
[style*="--fili-energie"] .cart-filigrane > i,
[style*="--fili-energie"] .zoom-filigrane > i {
  clip-path: none;
  background:
    repeating-linear-gradient(calc(var(--ang, 90) * 1deg),
      rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .10) 14%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 60%),
    rgba(255, 255, 255, .05);
  background-size: 220% 220%, 100% 100%;
  background-repeat: no-repeat;
  background-position: calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%), 0 0;
}

/* Les actions du devoilement passent EN HAUT, sous le titre : avec soixante-dix
   cartes, on cherchait « Revelation totale » tout en bas de la grille. */
.cards-reveal-area .reveal-header { order: -2; }
.cards-reveal-area .reveal-actions { order: -1; margin-top: 0; }

/* ══ La Forge ═══════════════════════════════════════════════════════════
   Un autel : le creuset au centre, les consommables en couronne, relies par
   des traits de lumiere a la couleur de la rarete visee. Les vignettes sont
   des cardFace reduites : la meme carte qu'au Cartable. */
/*  LA FORGE TIENT L'ECRAN, SANS DEFILER : l'autel a gauche prend toute la
    hauteur, le registre du burn se range en colonne a droite. */
body:has(#view-forge.is-on) main { padding-top: 0; padding-bottom: 0; }
body:has(#view-forge.is-on) { overflow: hidden; }
#view-forge.is-on {
  height: calc(100dvh - var(--forge-haut, 74px)); overflow: hidden;
}
.forge { display: flex; flex-direction: column; height: 100%; min-height: 0; }
/* La Forge des cristaux (forge_cristaux.js) se dessine dans forge.css. */
/* Les cristaux dessines (img/cristaux/). Un halo de leur couleur : ils
   rayonnent, comme dans Cult.io. */
/* Ceux qui tournent sur eux-memes (fonds/cristaux/, envol_cristaux.js) ont un
   cadre plus large que l'icone fixe : une boite taillee pour l'ancien
   (largeur ET hauteur donnees) les contient sans les ecraser. */
:where(img[src*="cristaux/"][src*="_tour.webp"]) { object-fit: contain; }
/* Depuis le 04/11/2026, en vraie 3D (js/cristaux3d.js) : une toile a la place
   de l'<img>, meme rapport 110 x 192 ; les regles qui les visent par `img`
   ont leur double `:is(img, canvas)`. */
:where(canvas.cristal-3d) { object-fit: contain; -webkit-user-drag: none; user-select: none; }
/* Les cristaux dans le profil (modele web2) : un bloc comme le niveau et la
   saison, deux tuiles egales, le cristal en grand -- on doit les voir d'un coup
   d'oeil (Alexandre, 23/10/2026). */
.pf-cristaux-bloc {
  display: grid; gap: 8px; padding: 12px 14px; border-radius: 12px;
  background: rgba(0, 0, 0, .28); border: 1px solid rgba(255, 255, 255, .07);
}
.pf-cristaux { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pf-cristal {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 10px;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--pfc, rgba(255, 255, 255, .15));
  color: var(--ink); font: inherit; cursor: pointer; min-width: 0;
}
.pf-cristal :is(img, canvas) { height: 52px !important; width: auto !important; max-width: none; flex: none; display: block; }
.pf-cristal span { display: grid; text-align: left; line-height: 1.1; min-width: 0; }
.pf-cristal b { font-size: 24px; font-family: var(--font-titre, inherit); }
.pf-cristal small { font-size: 11.5px; color: var(--ink-dim); }
.pf-cristal-ame { --pfc: rgba(232, 96, 96, .55); background: rgba(232, 70, 90, .08); }
.pf-cristal-ame :is(img, canvas) { filter: drop-shadow(0 0 8px rgba(232, 70, 90, .7)); }
.pf-cristal-arcane { --pfc: rgba(120, 150, 255, .55); background: rgba(90, 150, 255, .08); }
.pf-cristal-arcane :is(img, canvas) { filter: drop-shadow(0 0 8px rgba(90, 150, 255, .7)); }
.pf-cristal:hover { transform: translateY(-1px); }

/* Le passe de saison, sous les forfaits de la Boutique (modele web2). */
.boutique-passe {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  max-width: 760px; margin: 14px auto 0; padding: 14px 18px; border-radius: 14px;
  background: linear-gradient(120deg, rgba(190, 110, 255, .14), rgba(226, 178, 74, .1));
  border: 1px solid rgba(190, 110, 255, .45);
}
.bp-texte { display: grid; gap: 2px; }
.bp-kicker { font-size: 11px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: #c99bff; }
.bp-nom { font-size: 20px; color: var(--ink); font-family: var(--font-titre, inherit); }
.bp-note { font-size: 12.5px; color: var(--ink-dim); }
.bp-droite { display: flex; align-items: center; gap: 14px; }
.bp-bonus { font-size: 12.5px; color: #e9d7ff; font-weight: 600; }
.bp-ico { height: 1.3em; width: auto; vertical-align: -0.3em; }
.bp-prix { font-size: 20px; color: var(--ink); white-space: nowrap; }
.bp-acheter:disabled { opacity: .8; cursor: default; }
/* Le Prisme, la monnaie (cristal mauve) : a cote des montants de la Boutique
   et du menu du compte. */
.ic-prisme { height: 1.15em; width: auto; vertical-align: -0.22em; margin-right: 4px;
  filter: drop-shadow(0 0 4px rgba(190, 110, 255, .6)); }
/* Les soldes de cristaux dans la barre du haut, a la place du libelle du
   compte (modele web2). */
.wallet-btn.wallet-cristaux { display: inline-flex; align-items: center; gap: 7px; padding-left: 10px; padding-right: 14px; }
.wb-ico { height: 26px !important; width: auto !important; flex: none; }
.wb-ico-ame { filter: drop-shadow(0 0 4px rgba(232, 70, 90, .6)); }
.wb-ico-arcane { filter: drop-shadow(0 0 4px rgba(90, 150, 255, .6)); margin-left: 6px; }
.wb-n { font-variant-numeric: tabular-nums; font-size: 15px; font-weight: 800; color: var(--ink); }
/* Le Prisme dans la barre, et le grimoire range a cote des soldes, meme forme :
   l'image a cote du nombre (modele web2). */
.wb-ico-prisme { filter: drop-shadow(0 0 4px rgba(190, 110, 255, .65)); margin-left: 6px; }
/* La tuile : un seul cadre pour les soldes et le grimoire ; les deux boutons
   dedans perdent leur propre cadre, un trait fin les separe. */
.tuile-soldes {
  display: inline-flex; align-items: stretch; height: 42px; margin-right: 10px; border-radius: 999px;
  background: linear-gradient(180deg, #243047, #171e2c);
  border: 1px solid rgba(201, 162, 70, .55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 4px 14px rgba(0, 0, 0, .35);
}
.tuile-soldes .wallet { margin-right: 0; display: flex; }
.tuile-soldes .wallet-btn { height: 100%; border: 0; background: none; box-shadow: none; border-radius: 999px 0 0 999px; }
.topbar .tuile-soldes .cta-booster.cta-solde {
  gap: 6px; padding: 0 14px 0 10px; margin: 0; border: 0; border-left: 1px solid rgba(201, 162, 70, .35);
  border-radius: 0 999px 999px 0; background: none; box-shadow: none;
}
.topbar .tuile-soldes .cta-booster.cta-solde:hover { transform: none; background: rgba(245, 185, 66, .1); }
.tuile-soldes .wallet-btn:hover { background: rgba(255, 255, 255, .05); }
.cta-booster.cta-solde .cta-booster-lustre, .cta-booster.cta-solde .cta-booster-txt { display: none; }
.cta-booster.cta-solde .cta-booster-livre { display: inline-flex; align-items: center; gap: 6px; }
.cta-booster.cta-solde .cta-booster-img { width: 24px; height: 24px; animation: none; }
.cta-booster.cta-solde .cta-booster-pastille,
.cta-booster.cta-solde .cta-booster-pastille[hidden] {
  position: static; display: inline; min-width: 0; height: auto; padding: 0;
  background: none; box-shadow: none; color: var(--ink); font-size: 15px; font-weight: 800;
}

.forge-corps {
  position: relative; flex: 1; min-height: 0; overflow: hidden;
  padding: 10px clamp(10px, 2vw, 28px) 14px;
  display: grid; gap: 16px;
  grid-template-columns: minmax(0, 1fr) clamp(320px, 24vw, 420px);
}

/* ── L'autel ── */
.fg-scene { display: flex; flex-direction: column; align-items: center; gap: 10px; min-height: 0; }
.fg-autel {
  --fente-w: 96px;
  position: relative; width: 100%;
  flex: 1; min-height: 0;
  border-radius: 24px; overflow: hidden;
  background:
    radial-gradient(circle at var(--cx, 50%) var(--cy, 25%), color-mix(in srgb, var(--rc) 18%, transparent) 0, transparent 34%),
    radial-gradient(ellipse at 50% 60%, rgba(40, 26, 50, .55), rgba(8, 6, 12, .85) 70%);
  border: 1px solid rgba(201, 162, 39, .16);
}
.fg-traits {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;
  filter: drop-shadow(0 0 3px var(--rc)) drop-shadow(0 0 8px var(--rc));
}
.fg-trait {
  fill: none; stroke: var(--rc); stroke-width: 3;
  stroke-dasharray: calc(var(--len) * 1px); stroke-dashoffset: 0; opacity: .55; stroke-linecap: round;
}
.fg-brin {
  fill: none; stroke: var(--rc); stroke-width: 1.4; stroke-linecap: round;
  stroke-dasharray: calc(var(--len) * 1px); opacity: .35;
}
.fg-brin.plein { opacity: .7; }
.fg-apparait .fg-brin { animation: fg-trace 1s cubic-bezier(.3, .7, .2, 1) both; animation-delay: calc(var(--i) * 80ms + 260ms); }
.fg-trait.plein { opacity: .95; }
.fg-apparait .fg-trait { animation: fg-trace .75s cubic-bezier(.3, .7, .2, 1) both; animation-delay: calc(var(--i) * 80ms + 120ms); }
@keyframes fg-trace { from { stroke-dashoffset: calc(var(--len) * 1px); opacity: 1; } }
.fg-flux {
  fill: none; stroke: #fff; stroke-width: 2.5; stroke-linecap: round;
  stroke-dasharray: 5 23; opacity: .9; stroke-width: 2;
  animation: fg-flux 1.6s linear infinite; animation-delay: calc(var(--i) * -170ms);
}
@keyframes fg-flux { to { stroke-dashoffset: -28px; } }
.forge-feu .fg-flux { animation-duration: .25s; stroke-width: 3.5; }
.forge-feu .fg-trait { opacity: 1; stroke-width: 3; }

/*  LES FILS SE RETIRENT AVEC LES CARTES QU'ILS TIENNENT.
 *
 *  Les consommables disparaissaient d'un coup et les filaments restaient
 *  tendus vers des emplacements vides -- accroches a rien. Ils se retractent
 *  desormais vers le creuset, dans le meme mouvement que les etincelles qui
 *  y remontent (450 ms), et arrivent avant l'implosion (1150 ms).
 *
 *  SENS DE L'ANIMATION. Le chemin est trace DU creuset VERS l'emplacement.
 *  Avec `dasharray: len`, aller de 0 a +len fait reculer l'extremite libre
 *  vers le depart -- le fil rentre dans le creuset. L'inverse (-len) le
 *  ferait fuir vers la carte brulee, c'est-a-dire nulle part. */
.forge-feu .fg-trait.plein,
.forge-feu .fg-brin.plein {
  /*  MEME HORLOGE QUE LA CARTE. `fg-consume` consume l'emplacement i entre
      i x 90 ms et i x 90 ms + 800 : le fil part avec elle, un peu plus vite,
      pour etre rentre quand la carte a fini de se dissoudre. */
  animation: fg-rappel .62s cubic-bezier(.45, 0, .2, 1) forwards;
  animation-delay: calc(var(--i) * 90ms + 120ms);
}
@keyframes fg-rappel {
  to { stroke-dashoffset: calc(var(--len) * 1px); opacity: 0; }
}
/* Le flux blanc s'eteint avec son fil, sans quoi il coule dans le vide. */
.forge-feu .fg-flux {
  animation: fg-flux .25s linear infinite, fg-flux-fin .3s linear forwards;
  animation-delay: calc(var(--i) * -170ms), calc(var(--i) * 90ms + 420ms);
}
@keyframes fg-flux-fin { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .forge-feu .fg-trait.plein, :where(html:not(.mouvement-plein)) .forge-feu .fg-brin.plein { animation-duration: .01s; }
}

/*  LA CARTE A CREER N'EXISTE PAS ENCORE : elle attend en gris, et prend ses
 *  couleurs au moment ou la forge la fait. Le delai la cale sur l'eclat
 *  (1550 ms), pas sur le debut du geste. */
.fg-creuset-case > .cf {
  filter: grayscale(.95) brightness(.82) contrast(.95);
  transition: filter .5s ease;
}
/*  ELLE PREND SES COULEURS, PUIS SA LUMIERE. Les filaments entrent dans la
    carte pendant deux secondes : elle passe du gris (elle n'existe pas
    encore) a ses couleurs, puis disparait dans son propre eclat -- d'ou la
    revelation la fera ressortir. */
.forge-blanchit .fg-creuset-case > .cf {
  animation: fg-naissance 2s cubic-bezier(.4, 0, .5, 1) forwards;
}
@keyframes fg-naissance {
  0%   { filter: grayscale(.95) brightness(.82) contrast(.95); }
  45%  { filter: none; }
  75%  { filter: brightness(2.6) saturate(.4); }
  100% { filter: brightness(9) saturate(0) contrast(.2); }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .forge-blanchit .fg-creuset-case > .cf { animation-duration: .4s; }
}

/* ══════════════════════════════════════════════════════════════════════════
 *  LA REVELATION
 *
 *  On vient de detruire dix cartes pour en faire une : elle se montre, en
 *  grand, et attend qu'on la referme. Le moment ne se termine pas tout seul.
 * ══════════════════════════════════════════════════════════════════════════ */
.fg-revele {
  position: absolute; inset: 0; z-index: 30;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 18px; text-align: center;
  background:
    radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--rc) 22%, transparent), transparent 58%),
    rgba(6, 5, 10, .86);
  backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px);
  animation: fg-revele-fond .8s ease both;
}
@keyframes fg-revele-fond { from { opacity: 0; } }
/*  La carte avance vers nous depuis la lumiere : elle arrive blanche et
    surdimensionnee, et se pose a sa taille en reprenant ses couleurs. */
/*  LA CARTE SE MESURE EN HAUTEUR, PAS EN LARGEUR. Calee sur la largeur, elle
    depassait par le haut de l'autel des que celui-ci etait etroit et court --
    on ne voyait plus ni son nom ni son cadre. */
.fg-revele-carte {
  height: min(56%, 430px); width: auto; aspect-ratio: 1024 / 1610;
  flex: 0 1 auto; min-height: 0; cursor: zoom-in;
  filter: drop-shadow(0 0 30px color-mix(in srgb, var(--rc) 55%, transparent))
          drop-shadow(0 18px 40px rgba(0, 0, 0, .65));
  animation: fg-revele-avance 1.1s cubic-bezier(.16, 1, .3, 1) both;
}
.fg-revele-carte > * { width: 100%; height: 100%; display: block; }
/* Les commandes de la forge se taisent pendant la revelation. */
.revele-en-cours .fg-bas { display: none; }
@keyframes fg-revele-avance {
  0%   { transform: scale(.28); opacity: 0; filter: brightness(14) saturate(0); }
  35%  { opacity: 1; }
  100% { transform: scale(1); opacity: 1; filter: none; }
}
.fg-revele-dit { display: flex; flex-direction: column; gap: 2px; animation: fg-revele-fond .6s .5s ease both; }
.fg-revele-kicker {
  font-size: 11px; letter-spacing: .22em; text-transform: uppercase;
  color: rgba(201, 162, 39, .95);
}
.fg-revele-nom { font-family: var(--font-title); font-size: 26px; color: #fff3d6; }
.fg-revele-sous { font-size: 12.5px; color: var(--ink-dim, #b8b0c8); }
.fg-revele-actions { display: flex; gap: 10px; animation: fg-revele-fond .6s .7s ease both; }
.fg-revele-actions button { min-height: 42px; padding: 0 18px; border-radius: 10px; }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .fg-revele, :where(html:not(.mouvement-plein)) .fg-revele-carte, :where(html:not(.mouvement-plein)) .fg-revele-dit, :where(html:not(.mouvement-plein)) .fg-revele-actions { animation-duration: .01s; }
}
@media (max-width: 700px) {
  .fg-revele { gap: 10px; padding: 12px; }
  .fg-revele-carte { height: min(54%, 360px); }
  .fg-revele-nom { font-size: 21px; }
}

.fg-creuset {
  position: absolute; left: 50%; top: 4%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px; z-index: 3;
}
.fg-creuset-titre {
  font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: rgba(201, 162, 39, .9);
}
.fg-creuset-case {
  position: relative; width: clamp(120px, 11vw, 150px); aspect-ratio: 1024 / 1610;
  padding: 0; border: 0; border-radius: 12px; overflow: hidden; cursor: pointer; background: none;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--rc) 60%, transparent),
              0 0 36px color-mix(in srgb, var(--rc) 35%, transparent), 0 14px 40px rgba(0, 0, 0, .6);
  transition: transform .2s;
}

.fg-creuset-case > :first-child { width: 100%; height: 100%; pointer-events: none; }
.fg-creuset-case.est-vide {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  background: radial-gradient(circle, rgba(201, 162, 39, .12), rgba(0, 0, 0, .35));
  border: 2px dashed rgba(201, 162, 39, .55); box-shadow: 0 0 40px rgba(201, 162, 39, .15);
  animation: fg-respire 2.8s ease-in-out infinite;
}
.fg-glyphe { font-size: 40px; color: #c9a227; text-shadow: 0 0 18px rgba(201, 162, 39, .8); }
.fg-invite { font-size: 13px; color: var(--ink, #ece6f5); padding: 0 14px; text-align: center; }
@keyframes fg-respire { 50% { box-shadow: 0 0 60px rgba(201, 162, 39, .35); } }
.fg-apparait .fg-creuset-case { animation: fg-pose .5s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes fg-pose { from { transform: scale(.7); opacity: 0; } }
/*  Le nom se range A COTE de la carte : dessous, les traits le traverseraient. */
.fg-creuset-dit {
  position: absolute; left: calc(100% + 18px); top: 55%; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  font-size: 12px; color: var(--ink-dim, #b8b0c8); white-space: nowrap;
}
.fg-creuset-dit b { font-size: 15px; color: var(--ink, #ece6f5); }
.fg-voir { background: none; border: 0; padding: 2px; color: var(--rc); font: inherit; font-size: 11.5px; cursor: pointer; text-decoration: underline; }

.fg-fente {
  /*  CENTRE PAR LES MARGES, PAS PAR UN TRANSFORM. La regle globale
      `button:hover` pose son propre transform et ecrasait le translate :
      la carte sautait d'une demi-largeur au survol. */
  position: absolute; z-index: 2; width: var(--fente-w); height: calc(var(--fente-w) * 1610 / 1024);
  margin: calc(var(--fente-w) * -805 / 1024) 0 0 calc(var(--fente-w) / -2);
  padding: 0; cursor: pointer;
  border-radius: 9px; display: grid; place-items: center;
  font-size: 26px; color: color-mix(in srgb, var(--rc) 70%, transparent);
  background: rgba(0, 0, 0, .45);
  border: 1.5px dashed color-mix(in srgb, var(--rc) 55%, transparent);
  transition: transform .18s;
}
/*  LE ZOOM AGRANDIT LA CARTE, PAS L'EMPLACEMENT : il reste a sa place et
    ses traits aussi. La carte grandit vers le haut, par-dessus ses voisines. */
.fg-fente:hover, .fg-creuset-case:hover { transform: none !important; }
.fg-fente:hover { z-index: 10; }
.fg-fente > .cf, .fg-creuset-case > .cf {
  border-radius: 9px; overflow: hidden;
  transition: transform .22s cubic-bezier(.2, .9, .3, 1), box-shadow .22s;
}
.fg-fente > .cf { transform-origin: 50% 85%; }
.fg-fente.est-pleine:hover > .cf {
  transform: scale(2.1);
  box-shadow: 0 0 0 1px var(--rc), 0 18px 50px rgba(0, 0, 0, .75), 0 0 30px color-mix(in srgb, var(--rc) 45%, transparent);
}
.fg-creuset-case { overflow: visible !important; }
.fg-creuset-case > .cf { transform-origin: 50% 0; }
.fg-creuset-case:hover > .cf { transform: scale(1.6); position: relative; z-index: 10; box-shadow: 0 20px 60px rgba(0, 0, 0, .8); }
.fg-fente.est-pleine { border: 0; box-shadow: 0 0 0 1px color-mix(in srgb, var(--rc) 70%, transparent), 0 0 18px color-mix(in srgb, var(--rc) 35%, transparent); }
.fg-fente > .cf, .fg-fente > :first-child:not(span) { width: 100%; height: 100%; pointer-events: none; }
.fg-apparait .fg-fente { animation: fg-surgit .55s cubic-bezier(.2, 1.5, .4, 1) both; animation-delay: calc(var(--i) * 80ms + 500ms); }
@keyframes fg-surgit { from { transform: scale(0); opacity: 0; } }

.fg-bas { width: 100%; flex: none; display: flex; flex-direction: column; gap: 6px; }
.fg-commandes { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fg-solde { font-weight: 700; color: #f0a15e; margin-right: 8px; }
.fg-go { margin-left: auto; padding-inline: 22px; }
.fg-pourquoi { font-size: 12.5px; color: var(--ink-faint, #8d86a0); margin: 0; }
.fg-avert {
  padding: 10px 12px; border-radius: 10px;
  background: rgba(226, 112, 58, .12); border: 1px solid rgba(226, 112, 58, .5);
  font-size: 13px; color: var(--ink, #ece6f5);
}
.fg-avert ul { margin: 6px 0 10px 18px; padding: 0; }
.fg-avert button { margin-right: 8px; }

/* ── Le choix ── */
.fg-choix {
  position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
  background: rgba(4, 3, 8, .72); backdrop-filter: blur(4px);
}
.fg-choix-panneau {
  width: min(94vw, 980px); max-height: 86vh; overflow: auto;
  display: flex; flex-direction: column; gap: 12px; padding: 16px 18px;
  border-radius: 16px; background: linear-gradient(180deg, #1a1322, #0d0a13);
  border: 1px solid rgba(201, 162, 39, .3); box-shadow: 0 30px 80px rgba(0, 0, 0, .7);
}
.fg-choix-tete { display: flex; align-items: center; justify-content: space-between; }
.fg-choix-tete h4 { margin: 0; font-size: 15px; letter-spacing: .06em; color: var(--ink, #ece6f5); }
.fg-outils { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }
.fg-rars { display: flex; flex-wrap: wrap; gap: 5px; }
.fg-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; font-size: 12px; border-radius: 999px;
  background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .12);
  color: var(--ink-dim, #b8b0c8); cursor: pointer;
}
.fg-chip i { width: 8px; height: 8px; border-radius: 50%; background: var(--rc); }
.fg-chip-ratio { font-style: normal; opacity: .6; }
.fg-chip-ratio::before { content: " · "; }
/*  La regle en clair, juste au-dessus de la grille : c'est la derniere chose
    qu'on lit avant de choisir, donc elle se place la et pas dans l'en-tete. */
.fg-regle {
  margin: 0; font-size: 12.5px; line-height: 1.45;
  color: var(--ink-dim, #b8b0c8);
}
.fg-chip.is-on { border-color: var(--rc); color: var(--ink, #ece6f5); background: rgba(255, 255, 255, .09); }
/*  `.seg` est empile dans le panneau de l'atelier : ici il se couche. */
.fg-choix .fg-types { display: flex; flex-direction: row; flex-wrap: wrap; gap: 4px; width: auto; }
.fg-choix .fg-types button { width: auto; flex: 0 0 auto; padding: 5px 12px; font-size: 12px; }
.fg-cherche { flex: 0 1 220px; }
.fg-vide { color: var(--ink-faint, #8d86a0); font-size: 13px; line-height: 1.5; margin: 0; }
.fg-grille { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); padding: 2px; }
.fg-vignette {
  position: relative; padding: 0; border: 0; background: none; cursor: pointer;
  border-radius: 8px; aspect-ratio: 1024 / 1610; overflow: hidden;
  outline: 2px solid transparent; transition: transform .15s, outline-color .15s;
}
.fg-vignette > :first-child { width: 100%; height: 100%; pointer-events: none; }
.fg-vignette:hover:not(:disabled) { transform: translateY(-2px); }
.fg-vignette.is-on { outline-color: rgba(201, 162, 39, .95); }
.fg-vignette.est-manquante > :first-child { filter: saturate(.25) brightness(.65); }
.fg-vignette:disabled { opacity: .35; cursor: default; }
.fg-nb, .fg-deck {
  position: absolute; right: 4px; top: 4px; padding: 1px 6px; border-radius: 999px;
  font-size: 11px; font-weight: 700; color: #fff; background: rgba(0, 0, 0, .75);
}
.fg-deck { top: auto; bottom: 4px; left: 4px; right: auto; background: rgba(201, 162, 39, .85); color: #1a1206; }

/* ── L'embrasement ── */
.forge-feu .fg-fente.est-pleine {
  animation: fg-consume .8s cubic-bezier(.5, 0, .9, .4) forwards;
  animation-delay: calc(var(--i) * 90ms);
}
@keyframes fg-consume {
  0%   { filter: none; opacity: 1; }
  40%  { filter: brightness(1.8) sepia(1) saturate(4) hue-rotate(-20deg); }
  100% { filter: brightness(3) sepia(1) saturate(6) blur(3px); transform: scale(.6); opacity: 0; }
}
.fg-etincelle {
  position: absolute; left: 0; top: 0; z-index: 4; width: 7px; height: 7px;
  offset-rotate: 0deg; offset-distance: 0%;
  border-radius: 50%; background: #fff; pointer-events: none; opacity: 0;
  box-shadow: 0 0 8px 3px var(--rc), 0 0 18px 6px var(--rc);
  animation: fg-remonte .65s cubic-bezier(.6, 0, .9, .5) forwards;
}
/*  L'etincelle suit la courbe elle-meme (offset-path), de la fente au creuset. */
@keyframes fg-remonte {
  0%   { opacity: 0; offset-distance: 0%; transform: scale(.4); }
  20%  { opacity: 1; }
  100% { opacity: .9; offset-distance: 100%; transform: scale(1.4); }
}
.forge-implose .fg-creuset-case { animation: fg-contracte .4s cubic-bezier(.6, 0, 1, .6) forwards; }
@keyframes fg-contracte { to { transform: scale(.82); filter: brightness(2.4) saturate(1.4); } }
.forge-eclat .fg-creuset-case { animation: fg-renait 1s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes fg-renait {
  0%   { transform: scale(.82); filter: brightness(3); }
  100% { transform: scale(1); filter: none; }
}
.forge-eclat .fg-traits { opacity: 0; transition: opacity .5s; }
.fg-flash {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: radial-gradient(circle at var(--cx) var(--cy), #fff 0, var(--rc) 14%, transparent 55%);
  animation: fg-flash .9s ease-out forwards;
}
@keyframes fg-flash { 0% { opacity: 0; } 12% { opacity: .95; } 100% { opacity: 0; } }
.fg-onde {
  position: absolute; left: var(--cx); top: var(--cy); z-index: 4; width: 160px; height: 160px; margin: -80px;
  border-radius: 50%; border: 3px solid var(--rc); pointer-events: none; opacity: 0;
  box-shadow: 0 0 24px var(--rc), inset 0 0 24px var(--rc);
  animation: fg-onde 1.1s cubic-bezier(.1, .6, .3, 1) forwards;
}
@keyframes fg-onde { 0% { transform: scale(.3); opacity: 1; } 100% { transform: scale(6); opacity: 0; } }
.fg-rayons {
  position: absolute; left: var(--cx); top: var(--cy); z-index: 1; width: 1400px; height: 1400px; margin: -700px;
  pointer-events: none; opacity: 0; mix-blend-mode: screen;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--rc) 55%, transparent) 0 4deg, transparent 4deg 18deg);
  -webkit-mask: radial-gradient(circle, #000 0, transparent 45%);
          mask: radial-gradient(circle, #000 0, transparent 45%);
  animation: fg-rayons 2.6s ease-out forwards;
}
@keyframes fg-rayons {
  0% { opacity: 0; transform: rotate(0) scale(.4); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: rotate(70deg) scale(1); }
}
.fg-particule {
  position: absolute; left: var(--cx); top: var(--cy); z-index: 4; width: 5px; height: 5px; margin: -2.5px;
  border-radius: 50%; background: #fff; pointer-events: none;
  box-shadow: 0 0 6px 2px var(--rc);
  animation: fg-gerbe 1.4s cubic-bezier(.1, .7, .3, 1) forwards;
}
@keyframes fg-gerbe {
  0% { transform: translate(0, 0) scale(1.4); opacity: 1; }
  100% { transform: translate(var(--px), var(--py)) scale(.2); opacity: 0; }
}
.secousse { animation: fg-secousse .5s linear; }
.palier-5.secousse { animation-duration: .8s; }
@keyframes fg-secousse {
  10%, 50%, 90% { transform: translate(-5px, 2px); }
  30%, 70% { transform: translate(5px, -3px); }
}
.fg-banniere {
  position: absolute; left: 50%; top: calc(var(--oy) + 60px); z-index: 6; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; pointer-events: none;
  text-shadow: 0 0 18px var(--rc), 0 2px 8px #000;
  animation: fg-banniere 2.4s cubic-bezier(.2, 1, .3, 1) both;
}
.fg-banniere small {
  font-family: var(--font-title, inherit); font-size: clamp(22px, 3vw, 38px);
  letter-spacing: .3em; text-transform: uppercase; color: var(--rc);
}
.fg-banniere b { font-size: 18px; color: #fff; letter-spacing: .04em; }
@keyframes fg-banniere {
  0% { opacity: 0; transform: translate(-50%, 20px) scale(.9); letter-spacing: .6em; }
  25% { opacity: 1; transform: translate(-50%, 0) scale(1); }
  80% { opacity: 1; }
  100% { opacity: 0; }
}
/*  La Mythique illumine la salle entiere, pas seulement l'autel. */
body.fg-salle-illuminee::after {
  content: ''; position: fixed; inset: 0; z-index: 50; pointer-events: none;
  background: radial-gradient(circle at 50% 55%, rgba(129, 254, 151, .35), transparent 65%);
  animation: fg-salle 2.2s ease-out forwards;
}
@keyframes fg-salle { 0% { opacity: 0; } 15% { opacity: 1; } 100% { opacity: 0; } }
/*  Trop etroit pour deux colonnes : on empile, et la seulement on defile. */
@media (max-width: 1000px) {
  #view-forge.is-on { overflow: visible; height: auto; }
  body:has(#view-forge.is-on) { overflow: auto; }
  .forge-corps { overflow: auto; grid-template-columns: 1fr; }
  .fg-autel { flex: none; height: 640px; }
}
/*  ECRAN BAS (22/10/2026, tele 4K a 300 % : 1280 x 595 CSS). Les rangs se
 *  posent en POURCENTAGE de la hauteur de l'autel (`positionDe`, 66 et 87 %),
 *  mais les cartes avaient une taille en pixels : sur un autel de 400 px, le
 *  second rang sortait par le bas et le creuset mordait sur le premier. La
 *  taille suit donc aussi la hauteur de l'autel (cqh) ; sur un autel haut,
 *  le plafond en pixels reste celui qui decide. */
@media (min-width: 701px) {
  .fg-autel { container-type: size; }
  .fg-fente {
    --fw: min(var(--fente-w), 13cqh);   /* 13 : les rangs de 66 et 87 % ne se touchent pas */
    width: var(--fw); height: calc(var(--fw) * 1610 / 1024);
    margin: calc(var(--fw) * -805 / 1024) 0 0 calc(var(--fw) / -2);
  }
  .fg-creuset-case { width: min(clamp(120px, 11vw, 150px), 27cqh); }
}
@media (max-width: 700px) {
  /* Les 58 px etaient poses en `!important` pour battre le style en ligne
     que la Forge ecrit sur l'autel : ils figeaient la fente a la meme taille
     quel qu'en soit le nombre, et le `!important` empechait toute reprise
     ailleurs. Le plafond du telephone se pose maintenant sur la fente
     elle-meme (mobile.css), en pourcentage de l'ecran. */
  .fg-autel { height: min(38vh, 280px); }
  .fg-creuset-case { width: 88px; }
  .fg-creuset-dit { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .fg-autel *, :where(html:not(.mouvement-plein)) .fg-autel { animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
}

/*  LE REGISTRE DU BURN. Barres fines, extremites arrondies, un seul axe par
    figure ; le texte reste dans l'encre, la couleur n'est que sur la marque. */
.fg-burn {
  display: flex; flex-direction: column; gap: 14px; min-height: 0; overflow: hidden;
  align-self: stretch; padding: 14px; border-radius: 14px;
  background: rgba(12, 10, 18, .72); border: 1px solid rgba(201, 162, 39, .16);
}
.fg-burn-tete { grid-column: 1 / -1; }
.fg-burn-tete h3 { margin: 0; font-size: 16px; color: var(--ink, #ece6f5); }
.fg-burn-tete p { margin: 4px 0 0; font-size: 12.5px; color: var(--ink-faint, #8d86a0); }
/* L'avertissement se distingue du compteur : il dit une chose qu'on ne peut
   pas apprendre apres coup. */
.fg-burn-tete .fg-burn-avert { color: #e8b27a; }
.fg-fig { margin: 0; }
.fg-fig figcaption { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim, #b8b0c8); margin-bottom: 8px; }
.fg-row {
  display: grid; align-items: center; gap: 10px; padding: 5px 0;
  grid-template-columns: 96px 1fr 64px; font-size: 12.5px; color: var(--ink-dim, #b8b0c8);
}
.fg-row:hover { background: rgba(255, 255, 255, .03); }
.fg-row-div { grid-template-columns: 110px 36px 1fr 1fr 36px; gap: 0 6px; }
.fg-lab { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fg-lien {
  text-align: left; background: none; border: 0; padding: 0 0 0 10px; cursor: pointer;
  color: var(--ink, #ece6f5); font: inherit; position: relative;
}
.fg-lien::before {
  content: ''; position: absolute; left: 0; top: 50%; width: 6px; height: 6px;
  margin-top: -3px; border-radius: 50%; background: var(--rc);
}
.fg-piste { position: relative; height: 10px; border-radius: 4px; background: rgba(255, 255, 255, .05); }
.fg-bar { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 0 4px 4px 0; min-width: 0; }
.fg-g .fg-bar { left: auto; right: 0; border-radius: 4px 0 0 4px; }
.fg-g { border-radius: 4px 0 0 4px; margin-right: 1px; }
.fg-d { border-radius: 0 4px 4px 0; }
.fg-val { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink, #ece6f5); }
.fg-val-g { text-align: right; }
.fg-legende { display: flex; gap: 14px; font-size: 12px; color: var(--ink-dim, #b8b0c8); margin-bottom: 6px; }
.fg-legende i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
.fg-bulle {
  position: absolute; z-index: 20; pointer-events: none; min-width: 180px; max-width: 240px;
  padding: 8px 10px; border-radius: 8px; font-size: 12px; line-height: 1.5;
  background: rgba(10, 8, 14, .96); border: 1px solid rgba(201, 162, 39, .35);
  color: var(--ink, #ece6f5); box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}
.fg-bulle div:first-child { font-weight: 700; }

/* ══ STATISTIQUES ═══════════════════════════════════════════════════════════
   Des panneaux sur une grille de 12. Les marques portent la couleur (rarete,
   element, or du mint, feu, forge) ; le texte reste dans l'encre. */
#view-stats.is-on { display: flex; flex-direction: column; }
.st-corps { position: relative; padding: 10px 0 24px; }
.st-grille { display: grid; gap: 14px; grid-template-columns: repeat(12, minmax(0, 1fr)); }
.st-tuiles { grid-column: 1 / -1; display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.st-tuile {
  display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border-radius: 12px;
  background: rgba(12, 10, 18, .72); border: 1px solid rgba(201, 162, 39, .16);
  border-top: 3px solid var(--t, rgba(255, 255, 255, .12));
}
.st-lab { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-dim, #b8b0c8); }
.st-val { font-size: 26px; font-variant-numeric: tabular-nums; color: var(--ink, #ece6f5); }
.st-tuile small { font-size: 12px; color: var(--ink-faint, #8d86a0); }
.st-panneau {
  grid-column: 1 / -1; min-width: 0; padding: 14px; border-radius: 14px;
  background: rgba(12, 10, 18, .72); border: 1px solid rgba(201, 162, 39, .16);
  display: flex; flex-direction: column; gap: 10px;
}
.st-demi { grid-column: span 6; }
.st-large { grid-column: span 8; }
.st-etroit { grid-column: span 4; }
.st-tete h3 { margin: 0; font-size: 16px; color: var(--ink, #ece6f5); }
.st-tete p { margin: 3px 0 0; font-size: 12.5px; color: var(--ink-faint, #8d86a0); }
.st-vide, .st-note { margin: 0; font-size: 12.5px; color: var(--ink-faint, #8d86a0); }
.st-mut { color: var(--ink-faint, #8d86a0); }

.st-courbe { margin: 0; }
.st-legende { display: flex; gap: 14px; font-size: 12px; color: var(--ink-dim, #b8b0c8); margin-bottom: 6px; }
.st-legende i { display: inline-block; width: 12px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: 3px; }
.st-svg { width: 100%; height: 200px; display: block; overflow: visible; }
.st-grid { stroke: rgba(255, 255, 255, .07); stroke-width: 1; vector-effect: non-scaling-stroke; }
.st-axe { fill: var(--ink-faint, #8d86a0); font-size: 10px; }
.st-ligne { fill: none; stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.st-croix { stroke: rgba(255, 255, 255, .35); stroke-width: 1; vector-effect: non-scaling-stroke; }

.st-row { display: grid; grid-template-columns: 110px 1fr 70px; align-items: center; gap: 10px; padding: 4px 0; font-size: 12.5px; color: var(--ink-dim, #b8b0c8); }
.st-row:hover { background: rgba(255, 255, 255, .03); }
.st-nom { position: relative; padding-left: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink, #ece6f5); text-align: left; }
.st-nom::before { content: ''; position: absolute; left: 0; top: 50%; width: 6px; height: 6px; margin-top: -3px; border-radius: 50%; background: var(--rc); }
.st-piste { position: relative; height: 10px; border-radius: 4px; background: rgba(255, 255, 255, .05); overflow: hidden; }
.st-piste i { position: absolute; inset: 0 auto 0 0; border-radius: 0 4px 4px 0; }
.st-num { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink, #ece6f5); }

.st-table-wrap { overflow-x: auto; }
.st-table { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.st-table th { text-align: right; font-weight: 500; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-dim, #b8b0c8); padding: 6px 8px; border-bottom: 1px solid rgba(255, 255, 255, .08); }
.st-table th:first-child, .st-table td:first-child { text-align: left; }
.st-table td { text-align: right; padding: 7px 8px; color: var(--ink, #ece6f5); border-bottom: 1px solid rgba(255, 255, 255, .04); }
.st-table tr:hover td { background: rgba(255, 255, 255, .03); }
.st-sortie { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.st-jauge { position: relative; width: 70px; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .06); overflow: hidden; }
.st-jauge i { position: absolute; inset: 0 auto 0 0; }

.st-journal { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--ink, #ece6f5); }
.st-journal li { display: grid; grid-template-columns: 8px 86px 1fr; gap: 8px; align-items: center; }
.st-journal li i { width: 8px; height: 8px; border-radius: 50%; }
.st-journal time { color: var(--ink-faint, #8d86a0); font-variant-numeric: tabular-nums; }

.st-outils { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
.st-cherche { flex: 0 1 240px; }
.st-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.st-chip { padding: 4px 10px; font-size: 12px; border-radius: 999px; background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .12); color: var(--ink-dim, #b8b0c8); cursor: pointer; }
.st-chip.is-on { border-color: var(--rc, #c9a227); color: var(--ink, #ece6f5); background: rgba(255, 255, 255, .09); }
.st-explo-zone { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); gap: 16px; align-items: start; }
.st-liste { max-height: min(78vh, 760px); overflow: auto; display: flex; flex-direction: column; }
.st-carte {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center;
  padding: 6px 8px; border: 0; border-radius: 6px; background: none; font: inherit; font-size: 12.5px; cursor: pointer;
  color: var(--ink-dim, #b8b0c8); transform: none !important;
}
.st-carte:hover { background: rgba(255, 255, 255, .04); }
.st-carte.is-on { background: rgba(201, 162, 39, .12); }
.st-fiche {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  border-radius: 16px;
  background: rgba(10, 8, 14, .6); border: 1px solid rgba(201, 162, 39, .16);
}
/*  LA VITRINE : la carte en grand, eclairee par sa rarete (--rc) et teintee
    de son element (--ea), sur un socle de lumiere. */
.st-hero {
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); gap: 36px; align-items: center;
  padding: 34px 34px 38px;
  background:
    radial-gradient(42% 70% at 20% 50%, color-mix(in srgb, var(--rc) 30%, transparent), transparent 72%),
    radial-gradient(55% 80% at 100% 0%, color-mix(in srgb, var(--ea) 14%, transparent), transparent 70%),
    linear-gradient(180deg, rgba(18, 14, 24, .95), rgba(9, 8, 13, .95));
  border-bottom: 1px solid rgba(201, 162, 39, .14);
}
.st-hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .5;
  background: repeating-linear-gradient(115deg, transparent 0 22px, rgba(255, 255, 255, .018) 22px 23px);
}
.st-scene { position: relative; perspective: 1100px; animation: st-arrivee .45s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes st-arrivee { from { opacity: 0; transform: translateY(12px) scale(.96); } }
.st-face {
  position: relative; z-index: 1; display: block; width: 100%;
  padding: 0; border: 0; background: none; cursor: zoom-in; border-radius: 14px;
  transform: none !important;
}
.st-incline {
  border-radius: 14px;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .35s cubic-bezier(.2, .8, .2, 1), box-shadow .35s;
  box-shadow:
    0 34px 60px -24px rgba(0, 0, 0, .9),
    0 0 46px -8px color-mix(in srgb, var(--rc) 55%, transparent);
}
.st-face:hover .st-incline { transition-duration: .08s, .35s; box-shadow: 0 40px 70px -24px rgba(0, 0, 0, .9), 0 0 64px -6px color-mix(in srgb, var(--rc) 70%, transparent); }
.st-incline > .cf { width: 100%; display: block; pointer-events: none; }
.st-socle {
  position: absolute; left: 6%; right: 6%; bottom: -22px; height: 34px; z-index: 0; pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--rc) 60%, transparent), transparent);
  filter: blur(8px);
}
.st-hero-info { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.st-hero-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.st-pill {
  padding: 4px 12px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--rc); border: 1px solid color-mix(in srgb, var(--rc) 55%, transparent);
  background: color-mix(in srgb, var(--rc) 12%, transparent);
}
.st-hero-num { font-family: var(--font-num); font-size: 13px; letter-spacing: .08em; color: var(--ink-faint, #8d86a0); }
.st-hero-nom {
  margin: 0; font-family: var(--font-title); font-weight: 700; line-height: 1.05;
  font-size: clamp(28px, 3.4vw, 46px); color: #f5ecd6; overflow-wrap: anywhere;
  text-shadow: 0 2px 22px color-mix(in srgb, var(--rc) 45%, transparent);
}
.st-hero-sous { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; font-size: 14px; color: var(--ink-dim, #b8b0c8); }
.st-hero-el { display: inline-flex; align-items: center; gap: 6px; color: var(--ea); }
.st-hero-el i { font-style: normal; }
.st-hero .st-taux {
  margin-top: 6px; padding: 14px 18px; border-radius: 14px; gap: 4px;
  background: rgba(8, 6, 12, .55); border: 1px solid rgba(255, 255, 255, .07);
  border-left: 3px solid var(--rc);
}
.st-hero .st-taux-val { font-family: var(--font-num); font-size: clamp(40px, 4.6vw, 60px); color: #fff8e6; }
.st-taux { display: flex; flex-direction: column; gap: 4px; }
.st-taux-val { font-size: 34px; line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink, #ece6f5); }
.st-taux-sens { font-size: 13px; color: var(--ink-dim, #b8b0c8); }
.st-leviers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
/*  En dessous, l'historique : la courbe large, la chaine dans la colonne. */
.st-fiche-bas {
  display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 16px;
  padding: 20px 22px 8px; align-items: start;
}
.st-fiche-cote { display: grid; gap: 16px; min-width: 0; }
.st-bloc { padding: 14px 16px; border-radius: 12px; background: rgba(255, 255, 255, .025); border: 1px solid rgba(255, 255, 255, .06); gap: 8px; }
.st-bloc:empty { display: none; }
.st-fiche-bas .st-chaine { margin-top: 0; }
.st-fiche > .st-lu { padding: 0 22px 16px; }
.st-levier {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 10px;
  background: rgba(12, 10, 18, .55); border-top: 3px solid var(--t, rgba(255, 255, 255, .12));
}
.st-levier b { font-size: 22px; font-family: var(--font-num); font-variant-numeric: tabular-nums; color: var(--ink, #ece6f5); }
.st-levier small { font-size: 11px; color: var(--ink-faint, #8d86a0); }
.st-dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 6px 0; font-size: 12.5px; }
.st-dl dt { color: var(--ink-dim, #b8b0c8); }
.st-dl dd { margin: 0; text-align: right; color: var(--ink, #ece6f5); font-variant-numeric: tabular-nums; }
.st-fiche-offre { display: flex; gap: 2px; height: 10px; }
.st-fiche-offre i { flex-basis: 0; min-width: 2px; border-radius: 3px; }
.st-chaine { display: grid; gap: 8px; margin-top: 12px; }
.st-chaine-rang { display: grid; gap: 4px; }
.st-chaine-liens { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.st-chaine-lien {
  font-size: 12px; padding: 2px 8px; border-radius: 999px; text-decoration: none;
  color: #c9a227; border: 1px solid rgba(201, 162, 39, .45);
}
.st-chaine-lien:hover { background: rgba(201, 162, 39, .14); }
.st-miens-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; font-size: 12px; }
.st-miens-liste li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.st-origine { color: var(--ink, #ece6f5); font-weight: 600; }
.st-chaine-tx { color: var(--ink-dim, #b8b0c8); text-decoration: underline dotted; }
.st-chaine-tx:hover { color: #c9a227; }
.st-lu { font-size: 11px; margin-top: 4px; }
.st-seg-mintees { background: #c9a227; }
.st-seg-reste { background: rgba(255, 255, 255, .1); }
.st-bulle {
  position: absolute; z-index: 20; pointer-events: none; min-width: 170px; max-width: 230px;
  padding: 8px 10px; border-radius: 8px; font-size: 12px; line-height: 1.5;
  background: rgba(10, 8, 14, .96); border: 1px solid rgba(201, 162, 39, .35);
  color: var(--ink, #ece6f5); box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}
.st-bulle-t { font-weight: 700; }
@media (max-width: 1100px) {
  .st-demi, .st-large, .st-etroit { grid-column: 1 / -1; }
  .st-explo-zone { grid-template-columns: 1fr; }
  .st-fiche { order: -1; }
  .st-liste { max-height: 280px; }
  .st-fiche-bas { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .st-hero { grid-template-columns: 1fr; gap: 30px; padding: 26px 16px 24px; justify-items: center; }
  .st-scene { width: min(260px, 72vw); }
  .st-hero-info { width: 100%; }
  .st-fiche-bas { padding: 14px 12px 6px; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .st-scene { animation: none; }
  :where(html:not(.mouvement-plein)) .st-incline { transition: none; }
}
@media (max-width: 640px) {
  .st-leviers { grid-template-columns: 1fr; }
  .st-taux-val { font-size: 28px; }
}
.st-journal li.st-vide { display: block; }
.st-svg { overflow: hidden; }
.st-zero { stroke: rgba(255, 255, 255, .25); }

/* ══ ATELIER : DEUX ONGLETS, DECK ET TABLE ═══════════════════════════════
   L'ancienne barre melangeait le deck, les des et le plateau sur une seule
   ligne de pastilles. Chaque question a maintenant sa page. */
.atelier { grid-template-rows: auto auto minmax(0, 1fr); }
.atelier-onglets {
  display: flex; gap: 10px; padding: 12px 24px 0;
  background: rgba(10, 14, 23, 0.98);
}
.ao-btn {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 22px 12px; min-width: 220px;
  border: 1px solid var(--line); border-bottom: none;
  border-radius: 12px 12px 0 0;
  background: rgba(255, 255, 255, .03); color: var(--ink-dim);
  box-shadow: none; cursor: pointer; text-align: left;
}
.ao-btn:hover { color: var(--ink-bright); border-color: rgba(201, 162, 70, .5); }
.ao-btn.is-on {
  color: var(--ink-bright); border-color: var(--line-gold);
  background: linear-gradient(180deg, rgba(245, 185, 66, .14), rgba(18, 24, 38, .95));
}
.ao-ico { font-size: 26px; line-height: 1; }
.ao-txt { display: flex; flex-direction: column; }
.ao-txt b { font-family: var(--font-title); font-size: 18px; letter-spacing: .04em; }
.ao-btn.is-on .ao-txt b { color: var(--accent); }
.ao-txt small { font-size: 12px; color: var(--ink-faint); font-weight: 600; }

#view-atelier.mode-table .deck-rail,
#view-atelier.mode-table .atelier-body { display: none !important; }

/* La barre du deck, allegee */
.deck-meta { gap: 10px; }
.deck-meta .saved { flex: 1 1 auto; }
.deck-rail .deck-actions button { padding: 9px 16px; font-size: 13px; }
.deck-rail .play-btn { padding: 9px 22px !important; font-size: 14px !important; }
.deck-etat { display: flex; align-items: center; gap: 14px; margin-top: 10px; flex-wrap: wrap; }
.deck-etat .req { font-size: 12px; padding: 5px 12px; }
.deck-etat .play-why { width: auto; margin-left: auto; font-size: 13px; color: #fca5a5; font-weight: 600; }
.deck-etat .play-why.is-ok { color: #6ee7b7; }

.auto-group { position: relative; display: flex; }
.auto-group #deck-auto { border-radius: 8px 0 0 8px; }
.auto-caret { border-radius: 0 8px 8px 0 !important; padding: 9px 10px !important; border-left: 1px solid rgba(0, 0, 0, .35) !important; }
.auto-pop {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 80;
  width: 300px; padding: 12px;
  background: #121826; border: 1px solid var(--line-gold); border-radius: 10px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, .7);
}
.auto-pop-titre { margin: 0 0 8px; font-size: 12px; font-weight: 700; color: var(--ink-dim); }
.auto-pop .deck-els { flex-wrap: wrap; gap: 6px; }
.auto-pop .el-note { flex: 1 1 100%; margin: 6px 0 0; }

/* ── La page Table ── */
.atelier-table {
  grid-row: 3; overflow-y: auto; min-height: 0;
  padding: 22px 24px 40px;
  background: linear-gradient(180deg, rgba(18, 24, 38, 0.95), rgba(8, 10, 16, 1));
  border-top: 1px solid var(--line-gold);
}
.at-bloc { max-width: 1400px; margin: 0 auto 30px; }
.at-tete h2 {
  margin: 0; font-family: var(--font-title); font-size: 20px;
  color: var(--accent); letter-spacing: .04em;
}
.at-tete p { margin: 4px 0 14px; color: var(--ink-dim); font-size: 13px; }
.at-grille { display: grid; gap: 14px; }
.at-des { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
.at-fonds { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }

.at-tuile {
  display: flex; flex-direction: column; padding: 0; overflow: hidden;
  border: 2px solid var(--line); border-radius: 12px;
  background: rgba(14, 18, 28, .9); color: var(--ink);
  box-shadow: 0 8px 20px rgba(0, 0, 0, .45);
  cursor: pointer; text-align: left;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.at-tuile:hover { transform: translateY(-3px); border-color: rgba(201, 162, 70, .6); }
.at-tuile.is-on {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 24px rgba(245, 185, 66, .35);
}
.at-tuile.is-on::after {
  /* La coche seule : un `content` CSS ne se traduit pas (« Choisi » restait
     en francais en anglais et en espagnol). */
  content: '✓'; position: absolute; top: 8px; right: 8px;
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); color: #1a1202; font-size: 15px; font-weight: 800;
}
.at-tuile { position: relative; }
.at-tuile-txt { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px 12px; }
.at-tuile-txt b { font-size: 15px; color: var(--ink-bright); }
.at-tuile-txt small { font-size: 12px; color: var(--ink-faint); line-height: 1.35; }

/* LA SAISON, en tete du kit : nom, niveau, jauge. Une ligne qui n'a encore
   rien de gagne (les boites Classique au depart) se cache. */
.at-bloc[hidden] { display: none !important; }
.at-saison {
  display: grid; grid-template-columns: auto auto 1fr auto; align-items: center;
  gap: 6px 12px; margin: 0 0 14px; padding: 12px 14px;
  border: 1px solid rgba(201, 162, 70, .45); border-radius: 12px;
  background: linear-gradient(180deg, rgba(201, 162, 70, .12), rgba(201, 162, 70, .04));
}
.at-saison[hidden] { display: none; }
.ats-nom { color: var(--accent); font-size: 15px; letter-spacing: .04em; }
.ats-niveau { color: var(--ink-bright); font-weight: 700; }
.ats-jauge { height: 8px; border-radius: 4px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.ats-jauge i { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 4px; transition: width .4s ease; }
.ats-reste { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.ats-dit { grid-column: 1 / -1; margin: 0; font-size: 12px; color: var(--ink-faint); }
@media (max-width: 520px) {
  .at-saison { grid-template-columns: auto 1fr auto; }
  .ats-jauge { grid-column: 1 / -1; order: 5; }
}

.at-fond-vue {
  display: block; flex: 0 0 150px; width: 100%; height: 150px;
  background-size: cover; background-position: center;
}
.at-de-vue {
  display: grid; place-items: center; height: 130px;
  background: radial-gradient(circle at 50% 40%, rgba(255, 255, 255, .08), transparent 65%);
}
/* Un d20 vu de face : un hexagone, une facette claire en haut. */
.at-de {
  width: 84px; height: 94px; display: grid; place-items: center;
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  background:
    linear-gradient(160deg, rgba(255, 255, 255, .35), transparent 45%),
    linear-gradient(20deg, rgba(0, 0, 0, .45), transparent 55%),
    var(--de-c);
  font-family: var(--font-num); font-size: 28px; font-weight: 900;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .6));
}

@media (max-width: 700px) {
  .atelier-onglets { padding: 8px 8px 0; gap: 6px; }
  .ao-btn { min-width: 0; flex: 1; padding: 8px 10px 10px; gap: 8px; }
  .ao-ico { font-size: 20px; }
  .ao-txt b { font-size: 14px; }
  .ao-txt small { font-size: 10px; }
  .atelier-table { padding: 14px 10px 30px; }
  .at-des { grid-template-columns: repeat(2, 1fr); }
  .at-fonds { grid-template-columns: repeat(2, 1fr); }
  .deck-etat .play-why { margin-left: 0; width: 100%; }
}
/*  L'ATELIER EN FEUILLES : telephone, et tablette debout (27/09/2026). */
@media (max-width: 700px), (max-width: 1100px) and (orientation: portrait) {
  #view-atelier.en-feuilles .atelier { grid-template-rows: auto auto minmax(0, 1fr); }
  #view-atelier.en-feuilles .atelier-onglets { grid-row: 1; }
  #view-atelier.en-feuilles .barre-atelier { grid-row: 2; }
  #view-atelier.en-feuilles .atelier-body,
  #view-atelier.en-feuilles .atelier-table { grid-row: 3; }
  #view-atelier.mode-table .ba-deck,
  #view-atelier.mode-table .ba-filtres { visibility: hidden; }
}

/*  LE MUR DE LA FORGE. La salle du forgeron derriere l'autel : pierre, racines,
    pinces et braises. L'autel devient une vitre sombre pour qu'on voie le mur. */
body:has(#view-forge.is-on) .fantasy-bg-fx {
  background: #1a1210 url('https://medias.kairostcg.com/fonds/mur_forge.jpg') center / cover no-repeat;
}
body:has(#view-forge.is-on) .fantasy-bg-fx::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 80% 75% at 50% 45%, rgba(0, 0, 0, .25), rgba(0, 0, 0, .6) 100%);
}
body:has(#view-forge.is-on) .fx-orb,
body:has(#view-forge.is-on) .mur-glyphe { display: none; }
body:has(#view-forge.is-on) .fg-autel {
  background:
    radial-gradient(circle at var(--cx, 50%) var(--cy, 25%), color-mix(in srgb, var(--rc) 18%, transparent) 0, transparent 34%),
    radial-gradient(ellipse at 50% 60%, rgba(20, 12, 10, .35), rgba(8, 6, 6, .6) 75%);
  backdrop-filter: blur(1.5px);
}
body:has(#view-forge.is-on) .fg-burn { background: rgba(12, 9, 8, .78); backdrop-filter: blur(4px); }

/*  LES BRAISES DE LA FORGE. Au-dessus du mur, sous l'autel et le burn. */
.braises-forge { display: none; }
body:has(#view-forge.is-on) .braises-forge {
  display: block; position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
}
body:has(#view-forge.is-on) main { position: relative; z-index: 1; }

/* ══ ATELIER, SECONDE PASSE ══════════════════════════════════════════════
   La barre du deck en trois colonnes -- quel deck, ou j en suis, que faire --
   et un panneau de filtres qui se lit d un coup d oeil. */
.deck-rail { padding: 16px 24px 6px; }
.dk-haut {
  display: grid; gap: 22px; align-items: stretch;
  grid-template-columns: minmax(230px, 300px) minmax(0, 1fr) auto;
}
.dk-ident { display: flex; flex-direction: column; justify-content: center; gap: 8px; min-width: 0; }
.dk-mes { position: relative; }
.dk-liste-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .04);
  color: var(--ink-dim); font-size: 11px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; box-shadow: none;
}
.dk-liste-btn b {
  min-width: 20px; padding: 1px 6px; border-radius: 999px; text-align: center;
  background: rgba(245, 185, 66, .18); color: var(--accent); font-family: var(--font-num);
}
.dk-liste-btn:hover { color: var(--ink-bright); border-color: rgba(201, 162, 70, .5); }
.dk-liste {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 90;
  width: 340px; max-height: 420px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 6px; padding: 8px;
  background: #121826; border: 1px solid var(--line-gold); border-radius: 12px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .75);
}
.dk-liste[hidden] { display: none; }
.dk-nouveau {
  width: 100%; padding: 10px; border-radius: 8px; box-shadow: none;
  border: 1px dashed rgba(201, 162, 70, .5); background: transparent;
  color: var(--accent); font-weight: 700;
}
.dk-nouveau:hover { background: rgba(245, 185, 66, .08); }
.dk-liste .saved { flex-direction: column; flex-wrap: nowrap; gap: 4px; }
.dk-liste .saved-deck { border-radius: 8px; padding: 8px 6px 8px 10px; gap: 10px; }
.dk-vide { margin: 6px 4px; font-size: 12px; color: var(--ink-faint); }
.sd-els { display: flex; gap: 3px; flex: none; min-width: 18px; }
.sd-els i, .jauge-els i {
  display: block; width: 18px; height: 18px;
  background: var(--el, #8a9cb5);
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
}
.sd-info { flex: 1; min-width: 0; }
.saved-deck .sd-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dk-nom { position: relative; display: block; }
.dk-nom .deck-name {
  width: 100%; font-size: 24px; padding: 4px 28px 4px 0;
  border-bottom: 1px solid transparent; border-radius: 0;
}
.dk-nom .deck-name:hover, .dk-nom .deck-name:focus { border-bottom-color: rgba(201, 162, 70, .55); }
.dk-nom-crayon {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  color: var(--ink-faint); pointer-events: none;
}

.dk-jauges { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.jauge {
  display: flex; flex-direction: column; justify-content: space-between; gap: 7px;
  padding: 10px 12px; border-radius: 10px;
  background: rgba(8, 11, 18, .55); border: 1px solid rgba(248, 113, 113, .22);
}
.jauge.is-ok { border-color: rgba(52, 211, 153, .22); }
.jauge-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; }
.jauge-titre {
  font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint);
}
.jauge-val { font-family: var(--font-num); font-size: 21px; color: var(--ink-bright); line-height: 1; }
.jauge-barre { height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .07); overflow: hidden; }
.jauge-barre i { display: block; height: 100%; border-radius: 3px; background: #f87171; transition: width .3s ease; }
.jauge.is-ok .jauge-barre i { background: #34d399; }
.jauge-els { display: flex; align-items: center; gap: 6px; height: 18px; }
.jauge-rien { color: var(--ink-faint); }
.jauge-detail { font-size: 11.5px; line-height: 1.3; color: #fca5a5; }
.jauge.is-ok .jauge-detail { color: var(--ink-dim); }

.dk-actions { display: flex; align-items: stretch; gap: 12px; margin-left: 0; }
.dk-outils { display: flex; flex-direction: column; justify-content: center; gap: 6px; min-width: 160px; }
.dk-outil, .dk-outils .auto-group button {
  padding: 7px 12px !important; font-size: 12.5px !important; font-weight: 600;
  border-radius: 8px; border: 1px solid var(--line);
  background: rgba(255, 255, 255, .04); color: var(--ink); box-shadow: none; text-align: left;
}
.dk-outil:hover, .dk-outils .auto-group button:hover { border-color: rgba(201, 162, 70, .55); color: var(--ink-bright); }
.dk-outils .auto-group #deck-auto { flex: 1; border-radius: 8px 0 0 8px; }
.dk-outils .auto-group .auto-caret {
  border-radius: 0 8px 8px 0 !important; border-left: none !important; text-align: center;
}
.auto-pop { left: 0; right: auto; }
.dk-jouer { display: flex; flex-direction: column; justify-content: center; gap: 6px; min-width: 170px; }
.dk-jouer .play-btn { padding: 18px 28px !important; font-size: 19px !important; }
.dk-jouer .play-why { width: auto; margin: 0; text-align: center; font-size: 12px; font-weight: 600; color: #fca5a5; }
.dk-jouer .play-why.is-ok { color: #6ee7b7; }
.deck-rail .fan-container { margin-top: 14px; }

@media (max-width: 1500px) {
  .dk-jauges { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .jauge { padding: 7px 10px; gap: 4px; }
  .jauge-val { font-size: 17px; }
}
@media (max-width: 1000px) {
  .dk-haut { grid-template-columns: 1fr; gap: 12px; }
}

/* Le panneau des filtres */
.filters { gap: 22px; padding: 20px 16px 28px; }
.filters .filter-lbl {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: 11px; letter-spacing: .14em; color: var(--accent-light);
}
.filters .filter-lbl small { letter-spacing: 0; text-transform: none; font-weight: 600; color: var(--ink-faint); font-size: 11px; }
.filters .search-box input { padding: 10px 12px 10px 34px; font-size: 14px; border-radius: 10px; }
.filters .f-els { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.filters .f-el {
  flex-direction: column; justify-content: center; gap: 5px;
  padding: 11px 4px 8px; border-radius: 10px; text-align: center;
  font-size: 11.5px; font-weight: 700;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--line);
}
.filters .f-el i { width: 28px; height: 28px; background: color-mix(in srgb, var(--el) 55%, #9aa5b8); }
.filters .f-el:hover i { background: var(--el); }
.filters .f-el.is-on {
  color: var(--ink-bright);
  background: color-mix(in srgb, var(--el) 20%, transparent); border-color: var(--el);
  box-shadow: 0 0 14px color-mix(in srgb, var(--el) 35%, transparent);
}
.filters .f-el.is-on i { background: var(--el); }
.f-types { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.f-type {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px;
  border-radius: 9px; border: 1px solid var(--line);
  background: rgba(255, 255, 255, .03); color: var(--ink-dim);
  font-size: 13px; box-shadow: none; text-align: left;
}
.f-type-ico { width: 18px; text-align: center; color: var(--accent); }
.f-type:hover { color: var(--ink-bright); border-color: rgba(201, 162, 70, .45); }
.f-type.is-on { background: rgba(245, 185, 66, .14); border-color: rgba(245, 185, 66, .6); color: var(--ink-bright); font-weight: 700; }
.filters .f-rar { padding: 8px 10px; border: 1px solid transparent; }
.filters .f-rar span { flex: 1; }
.filters .f-rar.is-on { border-color: var(--rc); background: color-mix(in srgb, var(--rc) 14%, transparent); }
.f-switch { position: relative; display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 13px; color: var(--ink); }
.f-switch input { position: absolute; opacity: 0; pointer-events: none; }
.f-switch-rail { position: relative; flex: none; width: 36px; height: 20px; border-radius: 10px; background: rgba(255, 255, 255, .12); transition: background .2s; }
.f-switch-rail::after {
  content: ""; position: absolute; left: 3px; top: 3px;
  width: 14px; height: 14px; border-radius: 50%; background: #cfd6e4; transition: transform .2s;
}
.f-switch input:checked + .f-switch-rail { background: var(--accent); }
.f-switch input:checked + .f-switch-rail::after { transform: translateX(16px); background: #1a1202; }
.f-reset {
  padding: 9px; border-radius: 9px; box-shadow: none;
  border: 1px solid rgba(248, 113, 113, .4); background: transparent; color: #fca5a5; font-weight: 700;
}
.f-reset:hover { background: rgba(248, 113, 113, .1); }
.gal-barre { display: flex; align-items: baseline; gap: 6px; padding: 14px 28px 0; color: var(--ink-faint); font-size: 13px; }
.gal-barre b { font-family: var(--font-num); color: var(--ink-bright); font-size: 16px; }
.gal .gallery { padding-top: 12px; }

/* L onglet Table : le vrai de, la vraie table */
.at-de-vue { height: 150px; }
.at-de-toile { width: 136px; height: 136px; }
.at-fonds { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.at-fond-vue {
  flex: none !important; height: 0 !important; padding-top: 62.5%;
  background-color: #0a0708;
}

@media (max-width: 700px) {
  .dk-jauges { grid-template-columns: 1fr 1fr; }
  .dk-actions { flex-direction: column; }
  .dk-outils { flex-direction: row; flex-wrap: wrap; min-width: 0; }
  .dk-jouer { display: none; }
  .dk-liste { width: calc(100vw - 40px); }
  .at-fonds { grid-template-columns: 1fr; }
}

/*  LE MUR DE L ATELIER. La forge du fabricant de decks : pierre, foyer,
    enclume. Les panneaux deviennent des vitres sombres pour qu on le voie. */
body:has(#view-atelier.is-on) .fantasy-bg-fx {
  background: #16110d url("https://medias.kairostcg.com/fonds/mur_atelier.jpg") center / cover no-repeat;
}
body:has(#view-atelier.is-on) .fantasy-bg-fx::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 85% 80% at 50% 45%, rgba(0, 0, 0, .35), rgba(0, 0, 0, .7) 100%);
}
body:has(#view-atelier.is-on) .fantasy-bg-fx > * { display: none; }
#view-atelier .atelier-onglets { background: rgba(8, 6, 5, .55); backdrop-filter: blur(3px); }
#view-atelier .deck-rail { background: rgba(10, 8, 7, .72); backdrop-filter: blur(6px); }
#view-atelier .filters { background: rgba(10, 8, 7, .66); backdrop-filter: blur(6px); }
#view-atelier .atelier-table { background: rgba(10, 8, 7, .55); }
#view-atelier .at-tuile { background: rgba(14, 11, 9, .82); }

/*  ATELIER : PAS DE MUR PEINT, UN FOND CLAIR. Pierre claire et chaude, sans
    image : les panneaux sombres s y detachent comme des plateaux poses. */
body:has(#view-atelier.is-on) .fantasy-bg-fx {
  background:
    radial-gradient(ellipse 90% 70% at 50% 35%, #e9e1d2 0%, #d6cab5 60%, #b9ab93 100%);
}
body:has(#view-atelier.is-on) .fantasy-bg-fx::after { background: none; }
#view-atelier .gal-barre { color: #5a4c38; }
#view-atelier .gal-barre b { color: #2a2016; }
#view-atelier .gal-more { color: #5a4c38; }

/*  LE MENU DE GAUCHE TIENT SANS DEFILER. Elements sur une rangee de trois
    plus basse, types sur trois colonnes, raretes sur deux. */
#view-atelier .filters { gap: 12px; padding: 14px 12px 14px; overflow: hidden; }
#view-atelier .filters .filter-group { gap: 5px; }
#view-atelier .filters .search-box input { padding: 7px 10px 7px 30px; font-size: 13px; }
#view-atelier .filters .f-els { gap: 4px; }
#view-atelier .filters .f-el { padding: 6px 2px 5px; gap: 3px; font-size: 11px; }
#view-atelier .filters .f-el i { width: 20px; height: 20px; }
#view-atelier .f-types { grid-template-columns: repeat(3, 1fr); gap: 4px; }
#view-atelier .f-type { flex-direction: column; gap: 2px; padding: 5px 2px; font-size: 11px; text-align: center; justify-content: center; }
#view-atelier .filters .f-rars { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
#view-atelier .filters .f-rar { padding: 5px 7px; gap: 6px; font-size: 11.5px; }
#view-atelier .filters .f-rar small { font-size: 10px; }
#view-atelier .f-reset { padding: 6px; }

/*  LE MENU DE GAUCHE MONTE JUSQU AUX ONGLETS. Glisse sous la barre du deck,
    il n avait que ce qu elle lui laissait -- 320 px sur un ecran de 800. En
    colonne pleine hauteur, il tient sans defiler. `display: contents` fait des
    filtres et de la galerie des cases directes de la grille, sans toucher au
    HTML ni a la disposition telephone. */
@media (min-width: 501px) {
  #view-atelier .atelier {
    grid-template-columns: 236px minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr);
  }
  #view-atelier .atelier-onglets { grid-column: 1 / -1; grid-row: 1; }
  #view-atelier .atelier-body { display: contents; }
  #view-atelier .filters { grid-column: 1; grid-row: 2 / 4; min-height: 0; }
  #view-atelier .deck-rail { grid-column: 2; grid-row: 2; min-width: 0; }
  #view-atelier .gal { grid-column: 2; grid-row: 3; }
  #view-atelier .atelier-table { grid-column: 1 / -1; grid-row: 2 / 4; }
}

/*  LE MENU DE GAUCHE, REMIS D APLOMB. Sur le fond clair, le voile translucide
    le rendait boueux : il redevient un panneau plein. Les raretes s empilent,
    une par ligne, nom a gauche et cout a droite. */
#view-atelier .filters { background: #15110e; backdrop-filter: none; border-right: 1px solid rgba(201, 162, 70, .25); }
#view-atelier .deck-rail { background: #15110e; backdrop-filter: none; }
#view-atelier .atelier-onglets { background: #0f0c0a; backdrop-filter: none; }
#view-atelier .filters .f-rars { display: flex; flex-direction: column; gap: 3px; }
#view-atelier .filters .f-rar { padding: 6px 10px; font-size: 12.5px; white-space: nowrap; }
#view-atelier .filters .f-rar small { font-size: 11px; }
#view-atelier .f-type { gap: 4px; padding: 7px 2px 6px; }
#view-atelier .f-type-ico { width: 22px; height: 22px; color: var(--accent); }
#view-atelier .f-type-ico svg { display: block; width: 100%; height: 100%; }
#view-atelier .f-type.is-on .f-type-ico { color: #ffd27a; }

/*  LE MENU REDESCEND SOUS LA BARRE DU DECK, a cote de la galerie. Pour qu il
    tienne sans defiler, c est la bande du deck qui maigrit : l eventail passe
    de 168 a 112 px de haut. */
@media (min-width: 501px) {
  #view-atelier .atelier {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr);
  }
  #view-atelier .atelier-onglets { grid-column: 1; grid-row: 1; }
  #view-atelier .atelier-body { display: grid; grid-template-columns: 236px minmax(0, 1fr); grid-column: 1; grid-row: 3; }
  #view-atelier .filters { grid-column: 1; grid-row: 1; }
  #view-atelier .deck-rail { grid-column: 1; grid-row: 2; }
  #view-atelier .gal { grid-column: 2; grid-row: 1; }
  #view-atelier .atelier-table { grid-column: 1; grid-row: 2 / 4; }
  #view-atelier .deck-rail { padding: 10px 20px 4px; }
  #view-atelier .deck-rail .fan { --fan-card-w: 72px; height: 112px; padding-top: 6px; }
  #view-atelier .deck-rail .fan-card { height: 112px; }
  #view-atelier .deck-rail .fan-container { margin-top: 8px; }
  #view-atelier .dk-nom .deck-name { font-size: 20px; }
  #view-atelier .jauge { padding: 7px 10px; gap: 4px; }
}

/*  LE MENU SOUS LA BARRE, EN PLUS SERRE : icone et nom cote a cote plutot
    qu empiles, raretes plus basses. Il gagne ce qui lui manquait. */
@media (min-width: 501px) {
  #view-atelier .filters { gap: 9px; padding: 10px 10px 10px; }
  #view-atelier .filters .filter-group { gap: 4px; }
  #view-atelier .filters .f-el { flex-direction: row; justify-content: flex-start; gap: 5px; padding: 5px 6px; font-size: 11px; }
  #view-atelier .filters .f-el i { width: 16px; height: 16px; }
  #view-atelier .f-types { grid-template-columns: 1fr 1fr; gap: 4px; }
  #view-atelier .f-type { flex-direction: row; justify-content: flex-start; gap: 6px; padding: 5px 7px; font-size: 11.5px; text-align: left; }
  #view-atelier .f-type-ico { width: 16px; height: 16px; }
  #view-atelier .filters .f-rars { gap: 1px; }
  #view-atelier .filters .f-rar { padding: 3px 8px; font-size: 12px; }
}

/* Les icones de type fabriquees : un masque, comme les elements. */
.f-type-ico.est-masque {
  display: block; background: currentColor;
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
}

/*  « Seulement mon deck » passe tout en haut du menu, et les boutons Element
    et Type grandissent : il y a la place sous les raretes. */
@media (min-width: 501px) {
  #view-atelier .filters .f-switch { order: -1; padding: 4px 2px 6px; font-weight: 600; }
  #view-atelier .filters .f-el { padding: 9px 8px; gap: 7px; font-size: 13px; }
  #view-atelier .filters .f-el i { width: 20px; height: 20px; }
  #view-atelier .f-type { padding: 9px 10px; gap: 8px; font-size: 13px; }
  #view-atelier .f-type-ico { width: 20px; height: 20px; }
  #view-atelier .filters .f-els, #view-atelier .f-types { gap: 6px; }
}

/*  Les boutons agrandis ne tenaient plus a trois dans 236 px (« Lumiere »,
    « Ether » coupes) : la colonne s elargit plutot que d ajouter une rangee. */
@media (min-width: 501px) {
  #view-atelier .atelier-body { grid-template-columns: 290px minmax(0, 1fr); }
  #view-atelier .filters .f-el { padding: 9px 6px; gap: 6px; font-size: 12.5px; min-width: 0; }
  #view-atelier .filters .f-el span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #view-atelier .f-type { font-size: 13px; min-width: 0; }
  #view-atelier .filters { gap: 8px; }
  #view-atelier .filters .f-rar { padding: 2px 8px; }
}

/*  « Lumiere » est dans la colonne du milieu : c est elle qui s elargit. */
@media (min-width: 501px) {
  #view-atelier .filters .f-els { grid-template-columns: 0.9fr 1.25fr 0.9fr; }
}

/*  L EVENTAIL DU DECK EST RETIRE (au large) : le deck se regarde dans la
    galerie, par l interrupteur « Toutes les cartes / Mon deck ». */
@media (min-width: 501px) {
  #view-atelier .deck-rail .fan-container { display: none; }
  #view-atelier .deck-rail { padding-bottom: 12px; }
}
#view-atelier .gal-barre {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 28px 4px;
}
.gal-vue {
  display: inline-flex; padding: 4px; gap: 4px; border-radius: 12px;
  background: #15110e; border: 1px solid rgba(201, 162, 70, .35);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
}
.gv-btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 20px; border-radius: 9px; border: none;
  background: transparent; color: var(--ink-dim);
  font-size: 15px; font-weight: 700; box-shadow: none; cursor: pointer;
}
.gv-btn b {
  font-family: var(--font-num); font-size: 13px; padding: 2px 8px; border-radius: 999px;
  background: rgba(255, 255, 255, .08); color: var(--ink);
}
.gv-btn:hover { color: var(--ink-bright); }
.gv-btn.is-on { background: var(--gold-grad); color: #1a1202; }
.gv-btn.is-on b { background: rgba(0, 0, 0, .18); color: #1a1202; }
#view-atelier .gal-compte { font-size: 13px; color: #5a4c38; }
#view-atelier .gal-compte b { font-family: var(--font-num); color: #2a2016; }

/*  Le survol generique des boutons (fond bleu) ecrasait l interrupteur :
    on le neutralise ici, dans les deux etats. */
#view-atelier .gal-vue .gv-btn,
#view-atelier .gal-vue .gv-btn:hover,
#view-atelier .gal-vue .gv-btn:focus-visible {
  background: transparent !important; color: var(--ink-dim) !important;
  border: none !important; box-shadow: none !important; transform: none !important;
  filter: none !important;
}
#view-atelier .gal-vue .gv-btn:hover { background: rgba(255, 255, 255, .07) !important; color: var(--ink-bright) !important; }
#view-atelier .gal-vue .gv-btn b,
#view-atelier .gal-vue .gv-btn:hover b { background: rgba(255, 255, 255, .12) !important; color: var(--ink-bright) !important; }
#view-atelier .gal-vue .gv-btn.is-on,
#view-atelier .gal-vue .gv-btn.is-on:hover {
  background: var(--gold-grad) !important; color: #1a1202 !important;
}
#view-atelier .gal-vue .gv-btn.is-on b,
#view-atelier .gal-vue .gv-btn.is-on:hover b { background: rgba(0, 0, 0, .2) !important; color: #1a1202 !important; }

/* ══ LE COFFRET DU DECK ═══════════════════════════════════════════════════
   Une boite : couvercle (le compte), casier (40 tranches qui se remplissent),
   etiquette (ce que le deck doit contenir). */
#view-atelier .dk-jauges { display: block; }
.coffret {
  display: grid; grid-template-columns: 112px minmax(0, 1fr) 230px; align-items: stretch;
  border-radius: 14px; overflow: hidden;
  background: linear-gradient(180deg, #2a1f16, #1a130d);
  border: 1px solid rgba(201, 162, 70, .55);
  box-shadow: inset 0 1px 0 rgba(255, 220, 150, .18), inset 0 -3px 0 rgba(0, 0, 0, .35),
              0 10px 26px rgba(0, 0, 0, .45);
  position: relative;
}
/* Les coins en laiton */
.coffret::before, .coffret::after {
  content: ""; position: absolute; width: 14px; height: 14px; pointer-events: none;
  border: 2px solid #c9a246; opacity: .8;
}
.coffret::before { top: 4px; left: 4px; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0; }
.coffret::after { bottom: 4px; right: 4px; border-left: 0; border-top: 0; border-radius: 0 0 6px 0; }
.coffret.est-plein { border-color: #e8c25a; box-shadow: inset 0 1px 0 rgba(255, 220, 150, .25), 0 0 22px rgba(232, 194, 90, .28), 0 10px 26px rgba(0, 0, 0, .45); }

.cof-couvercle {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 8px 6px; border-right: 1px solid rgba(201, 162, 70, .3);
  background: radial-gradient(ellipse at 50% 30%, rgba(245, 185, 66, .16), transparent 70%);
}
.cof-titre { font-family: var(--font-title); font-size: 10px; letter-spacing: .22em; text-transform: uppercase; color: #c9a246; }
.cof-total { font-family: var(--font-num); font-size: 34px; line-height: 1; color: #ffe3a0; text-shadow: 0 2px 10px rgba(245, 185, 66, .35); }
.cof-total small { font-size: 15px; color: #a88a52; margin-left: 1px; }
.cof-etat { font-size: 11px; font-weight: 700; color: #fca5a5; }
.coffret.est-plein .cof-etat { color: #6ee7b7; }

.cof-force {
  display: grid; grid-template-columns: auto auto 1fr; align-items: baseline;
  column-gap: 8px; row-gap: 3px;
  padding-bottom: 6px; margin-bottom: 2px;
  border-bottom: 1px solid rgba(201, 162, 70, .28);
}
.cof-force-k {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: #c9a246;
}
.cof-force-n {
  font-family: var(--font-num); font-size: 28px; line-height: 1; color: currentColor;
  text-shadow: 0 2px 10px color-mix(in srgb, currentColor 35%, transparent);
}
.cof-force.monte .cof-force-n { animation: force-monte .48s ease; }
@keyframes force-monte {
  0% { transform: translateY(6px); opacity: .4; }
  100% { transform: none; opacity: 1; }
}
.cof-force-palier {
  justify-self: end; padding: 2px 8px; border-radius: 999px;
  font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  border: 1px solid currentColor;
}
.cof-force-barre {
  grid-column: 1 / -1; display: block; height: 5px; border-radius: 3px;
  background: rgba(255, 255, 255, .08); overflow: hidden;
}
.cof-force-barre > i {
  display: block; height: 100%; width: 0; border-radius: 3px;
  background: currentColor; transition: width .45s ease;
}
.cof-force-suite { grid-column: 1 / -1; font-size: 11px; color: var(--ink-faint); }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .cof-force.monte .cof-force-n { animation: none; }
}

/* Le casier : un fond creuse, quarante logements. */
.cof-casier {
  display: grid; grid-template-columns: repeat(20, minmax(0, 1fr)); grid-template-rows: repeat(2, 1fr);
  gap: 3px; padding: 8px 10px;
  background: linear-gradient(180deg, #0d0906, #17110c);
  box-shadow: inset 0 4px 10px rgba(0, 0, 0, .7);
}
.tranche {
  position: relative; border-radius: 3px; min-height: 36px;
  border: 1px dashed rgba(201, 162, 70, .18);
  background: rgba(255, 255, 255, .02);
}
.tranche.est-pleine {
  border: 1px solid rgba(0, 0, 0, .6);
  background:
    linear-gradient(90deg, var(--el, #888) 0 3px, transparent 3px),
    linear-gradient(180deg, rgba(255, 255, 255, .25), transparent 35%, rgba(0, 0, 0, .45)),
    var(--art, none) center 30% / cover no-repeat,
    color-mix(in srgb, var(--el, #888) 45%, #1a130d);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .5);
}
.tranche.type-energie {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .3), transparent 40%, rgba(0, 0, 0, .35)),
    color-mix(in srgb, var(--el, #888) 75%, #1a130d);
}
.tranche.est-pleine:hover { outline: 1px solid #ffe3a0; z-index: 2; transform: translateY(-2px); }
.tranche.arrive { animation: tranche-arrive .42s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes tranche-arrive {
  0% { transform: translateY(-26px) scale(.8); opacity: 0; box-shadow: 0 0 0 rgba(255, 227, 160, 0); }
  60% { opacity: 1; box-shadow: 0 0 14px rgba(255, 227, 160, .9); }
  100% { transform: none; box-shadow: 0 2px 4px rgba(0, 0, 0, .5); }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .tranche.arrive { animation: none; } }

/* L'etiquette */
.cof-etiquette {
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
  padding: 8px 14px; border-left: 1px solid rgba(201, 162, 70, .3);
}
.cof-ligne {
  display: grid; grid-template-columns: 16px 1fr auto; align-items: center; column-gap: 7px; row-gap: 3px;
  font-size: 12px; color: var(--ink);
}
.cof-l-ico { color: #f87171; text-align: center; }
.cof-ligne.is-ok .cof-l-ico { color: #6ee7b7; }
.cof-l-val { font-family: var(--font-num); font-size: 14px; color: var(--ink-bright); }
.cof-l-val small { font-size: 10px; color: var(--ink-faint); font-family: inherit; }
.cof-l-barre { grid-column: 2 / 4; display: block; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.cof-l-barre > i { display: block; height: 100%; background: #f87171; border-radius: 2px; transition: width .3s ease; }
.cof-ligne.is-ok .cof-l-barre > i { background: #34d399; }
.cof-l-icones { display: flex; gap: 5px; }
.cof-l-icones i {
  display: block; width: 18px; height: 18px; background: var(--el, #8a9cb5);
  -webkit-mask: var(--ico) center / contain no-repeat; mask: var(--ico) center / contain no-repeat;
}
.cof-l-icones i.vide { -webkit-mask: none; mask: none; background: none; border: 1px dashed rgba(201, 162, 70, .35); border-radius: 50%; width: 16px; height: 16px; }
.cof-l-bonus { grid-column: 2 / 4; font-size: 10.5px; color: var(--accent); }

@media (max-width: 1300px) {
  .coffret { grid-template-columns: 96px minmax(0, 1fr) 200px; }
  .cof-casier { grid-template-columns: repeat(10, minmax(0, 1fr)); grid-template-rows: repeat(4, 1fr); }
  .tranche { min-height: 16px; }
}
@media (max-width: 700px) {
  .coffret { grid-template-columns: 1fr; }
  .cof-couvercle { flex-direction: row; gap: 10px; border-right: 0; border-bottom: 1px solid rgba(201, 162, 70, .3); }
  .cof-casier { grid-template-columns: repeat(10, minmax(0, 1fr)); grid-template-rows: repeat(4, 1fr); }
  .tranche { min-height: 22px; }
  .cof-etiquette { border-left: 0; border-top: 1px solid rgba(201, 162, 70, .3); }
}

/* ══ LE COFFRET EN 3D ═════════════════════════════════════════════════════
   La boite rendue par Blender a gauche, puis le compte, puis l etiquette.
   Deux calques PNG, et entre eux la pile (SVG) et la carte vedette. */
.coffret { grid-template-columns: 170px 104px minmax(0, 1fr); }
.cof-casier { display: none; }
.cof3d {
  position: relative; width: 170px; height: 170px; margin: -24px 0 -24px -6px;
  overflow: visible; pointer-events: auto;
}
.cof3d > img, .cof3d-pile {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; user-select: none;
}
.cof3d-pile { overflow: visible; }
.cof3d-pile .cof3d-carte { stroke: #0b0a12; stroke-width: 4; stroke-linejoin: round; pointer-events: visiblePainted; }
.cof3d-pile .cof3d-carte.arrive { animation: cof3d-tombe .46s cubic-bezier(.2, 1.35, .4, 1) both; }
@keyframes cof3d-tombe {
  from { transform: translateY(-150px); opacity: 0; }
  60% { opacity: 1; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .cof3d-pile .cof3d-carte.arrive { animation: none; } }
/* Le plan de projection : 1000 x 1000 unites, comme le viewBox de la pile,
   ramene a la taille de la scene. */
.cof3d-plan {
  position: absolute; left: 0; top: 0; width: 1000px; height: 1000px;
  transform-origin: 0 0; transform: scale(.17); pointer-events: none;
}
.cof3d-vedette {
  position: absolute; left: 0; top: 0; width: 100px; height: 140px;
  transform-origin: 0 0; object-fit: cover;
}
@media (max-width: 1300px) {
  .coffret { grid-template-columns: 150px 96px minmax(0, 1fr); }
  .cof3d { width: 150px; height: 150px; }
  .cof3d-plan { transform: scale(.15); }
}
@media (max-width: 700px) {
  .coffret { grid-template-columns: 1fr; }
  .cof3d { margin: 0 auto; }
}

/* ══ LA VITRINE DE L ATELIER ═════════════════════════════════════════════
   Plus d onglets : la boite du deck, posee sur le plateau choisi, avec le de
   choisi. « Plateau » et « Dés » ouvrent le panneau de choix par-dessus. */
#view-atelier .atelier-onglets { display: none !important; }
@media (min-width: 501px) {
  #view-atelier .dk-haut { grid-template-columns: minmax(190px, 250px) 400px minmax(0, 1fr) auto; align-items: center; }
}
.vitrine { position: relative; }
.vt-scene {
  position: relative; height: 220px; border-radius: 14px; overflow: hidden;
  background: #0a0708 center / cover no-repeat;
  border: 1px solid rgba(201, 162, 70, .6);
  box-shadow: inset 0 0 50px rgba(0, 0, 0, .55), 0 12px 28px rgba(0, 0, 0, .45);
}
/* L ombre de la boite sur le plateau : un aplat sombre, pas un flou. */
.vt-boite::before {
  content: ""; position: absolute; left: 118px; top: 186px; width: 170px; height: 24px;
  border-radius: 50%; background: rgba(0, 0, 0, .45);
}
.vt-boite .cof3d { position: absolute; left: 80px; top: -8px; width: 240px; height: 240px; margin: 0; }
.vt-boite .cof3d-plan { transform: scale(.24); }
.vt-de-hote { position: absolute; right: 16px; bottom: 16px; width: 88px; height: 88px; }
.vt-de-hote canvas { display: block; width: 100%; height: 100%; filter: drop-shadow(0 6px 4px rgba(0, 0, 0, .55)); }
.vt-boutons { position: absolute; left: 10px; top: 10px; display: flex; flex-direction: column; gap: 6px; }
#view-atelier .vt-btn {
  padding: 6px 12px; font-size: 12.5px; font-weight: 700; border-radius: 8px;
  background: rgba(12, 9, 7, .85) !important; color: #ffe3a0 !important;
  border: 1px solid rgba(201, 162, 70, .6) !important; box-shadow: none !important; text-align: left;
}
#view-atelier .vt-btn:hover { background: rgba(58, 42, 18, .95) !important; color: #fff !important; }
/* L etiquette n a plus la boite : couvercle + lignes. */
.coffret { grid-template-columns: 104px minmax(0, 1fr); }

/* ── Le panneau Plateau et dés, par-dessus ── */
.at-voile { position: fixed; inset: 0; z-index: 119; background: rgba(4, 3, 2, .62); }
#view-atelier .atelier-table:not([hidden]) {
  position: fixed; inset: 6vh 7vw; z-index: 120; grid-row: auto; grid-column: auto;
  border-radius: 16px; border: 1px solid var(--line-gold);
  background: #15110e !important; box-shadow: 0 30px 80px rgba(0, 0, 0, .8);
  padding: 0 26px 30px; overflow-y: auto;
}
.at-barre {
  position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between;
  margin: 0 -26px 16px; padding: 14px 26px; background: #15110e; border-bottom: 1px solid rgba(201, 162, 70, .3);
}
.at-barre b { font-family: var(--font-title); font-size: 20px; color: var(--accent); letter-spacing: .04em; }
#view-atelier .at-fermer {
  padding: 8px 14px; border-radius: 8px; font-weight: 700;
  background: rgba(255, 255, 255, .05) !important; color: var(--ink) !important;
  border: 1px solid var(--line) !important; box-shadow: none !important;
}
#view-atelier .at-fermer:hover { border-color: rgba(201, 162, 70, .6) !important; color: #fff !important; }
@media (max-width: 700px) {
  #view-atelier .atelier-table:not([hidden]) { inset: 0; border-radius: 0; }
  .vt-scene { height: 190px; }
}

/* Les boutons de la vitrine passent en bas a gauche, cote a cote : en haut,
   ils mordaient sur le rebord de la boite. */
.vt-boutons { top: auto; bottom: 10px; left: 10px; flex-direction: row; }

/* ══ LA VITRINE EN TROIS TUILES ══════════════════════════════════════════
   Plateau, Deck, Dés : chaque accessoire dans sa tuile, legende en bas,
   « Modifier » au survol. Remplace la scene unique. */
@media (min-width: 501px) {
  #view-atelier .dk-haut { grid-template-columns: minmax(180px, 230px) 540px minmax(0, 1fr) auto; }
}
.vitrine { display: grid; grid-template-columns: 1.45fr 1fr .8fr; gap: 10px; }
.vt-boutons { display: none; }
#view-atelier .vt-tuile {
  position: relative; display: block; height: 200px; padding: 0; overflow: hidden;
  border-radius: 12px; cursor: pointer; text-align: left;
  border: 1px solid rgba(201, 162, 70, .45) !important;
  background: radial-gradient(ellipse 80% 70% at 50% 40%, #2a2019, #120d0a) !important;
  box-shadow: 0 10px 24px rgba(0, 0, 0, .45) !important;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
#view-atelier .vt-tuile:hover {
  transform: translateY(-3px);
  border-color: #e8c25a !important;
  box-shadow: 0 0 0 1px #e8c25a, 0 14px 30px rgba(0, 0, 0, .55) !important;
}
.vt-vue { position: absolute; inset: 0 0 42px 0; display: block; }
.vt-t-plateau .vt-vue { inset: 0; background: #0a0708 center / cover no-repeat; }
/* La table 3D s'arrete AU-DESSUS de l'etiquette (42 px) : sur toute la tuile,
   elle se centrait derriere l'etiquette et paraissait decalee. Fond de la
   tuile, comme ses voisines. */
.vt-t-plateau .vt-vue .vt-plateau-3d { position: absolute; left: 0; right: 0; top: 0; bottom: 42px; width: 100%; height: calc(100% - 42px); display: block; }
.vt-t-plateau .vt-vue.est-3d { background: none !important; }
/* La boite 3D de la vitrine (monterBoiteVitrine) : la composition a plat
   reste dessous, cachee des que la 3D est la. */
.vt-boite .vt-boite-3d { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.vt-boite.est-3d .cof3d { visibility: hidden; }
.vt-legende {
  position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column;
  padding: 6px 10px 7px; background: rgba(10, 8, 6, .88);
  border-top: 1px solid rgba(201, 162, 70, .3);
}
.vt-legende small { font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: #c9a246; font-weight: 800; }
.vt-legende b { font-size: 13.5px; color: #fff3d6; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vt-modifier {
  position: absolute; top: 8px; right: 8px; padding: 3px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 800; background: var(--gold-grad); color: #1a1202;
  opacity: 0; transform: translateY(-4px); transition: opacity .16s ease, transform .16s ease;
}
.vt-tuile:hover .vt-modifier { opacity: 1; transform: none; }

/* La boite, centree dans sa tuile */
.vt-boite::before { content: none; }
.vt-boite .cof3d { position: absolute; left: 50%; top: -14px; width: 190px; height: 190px; margin: 0 0 0 -95px; }
.vt-boite .cof3d-plan { transform: scale(.19); }
/* Le de, centre dans sa tuile */
.vt-de-hote { position: absolute; inset: 14px 10px 50px 10px; right: auto; bottom: auto; width: auto; height: auto; }
#view-atelier .vt-t-de .vt-de-hote { inset: 12px 0 48px 0; display: grid; place-items: center; }
#view-atelier .vt-t-de .vt-de-hote canvas { width: 118px; height: 118px; }
@media (max-width: 700px) {
  .vitrine { grid-template-columns: 1.3fr 1fr .8fr; }
  #view-atelier .vt-tuile { height: 160px; }
}

/*  ★ LA CARTE VEDETTE : le bouton dans les actions d une carte du deck, et
    la marque sur la carte choisie. */
#view-atelier .slot-actions button.vedette {
  background: rgba(12, 9, 7, .9) !important; color: #c9a246 !important;
  border: 1px solid rgba(201, 162, 70, .6) !important; font-size: 15px;
}
#view-atelier .slot-actions button.vedette:hover,
#view-atelier .slot-actions button.vedette.is-on {
  background: var(--gold-grad) !important; color: #1a1202 !important; border-color: #ffe082 !important;
}
.slot.is-vedette .cf { box-shadow: 0 0 0 3px #ffd36b, 0 0 22px rgba(255, 211, 107, .55), 0 12px 28px rgba(0, 0, 0, .6); }
.slot.is-vedette::before {
  content: "★ Vedette"; position: absolute; top: -9px; left: 10px; z-index: 13;
  padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 800;
  background: var(--gold-grad); color: #1a1202; box-shadow: 0 3px 8px rgba(0, 0, 0, .5);
}

/*  BLEU NUIT pour les menus de l Atelier (choisi le 13/09/2026) : le haut,
    la gauche, et ce qui s ouvre par-dessus. Il fait ressortir l or des
    bordures et le beige de la galerie. */
#view-atelier .deck-rail,
#view-atelier .filters,
#view-atelier .atelier-table:not([hidden]),
#view-atelier .at-barre,
#view-atelier .dk-liste,
#view-atelier .auto-pop,
#view-atelier .gal-vue { background: #1c2433 !important; }
#view-atelier .deck-rail { border-bottom: 1px solid rgba(201, 162, 70, .45); }
#view-atelier .filters { border-right: 1px solid rgba(201, 162, 70, .3); }
/* Les boutons et tuiles poses sur ce bleu : un cran plus clair, pas du brun. */
#view-atelier .filters .f-el,
#view-atelier .f-type,
#view-atelier .dk-outil,
#view-atelier .dk-outils .auto-group button { background: rgba(255, 255, 255, .05) !important; }
#view-atelier .jauge,
#view-atelier .coffret { background: linear-gradient(180deg, #243047, #1a2130) !important; }
#view-atelier .vt-tuile { background: radial-gradient(ellipse 80% 70% at 50% 40%, #2b3850, #141a26) !important; }
#view-atelier .vt-legende { background: rgba(14, 19, 30, .9); }
#view-atelier .at-tuile { background: rgba(255, 255, 255, .04) !important; }

/* Les coloris de la boite, dans le panneau du kit. */
.at-boites { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.at-boite-vue {
  display: grid; place-items: center; height: 170px;
  background: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(255, 255, 255, .08), transparent 70%);
}
.at-boite-vue img { width: 160px; height: 160px; object-fit: contain; }
/* Les dos de carte (js/dos.js) : la carte debout, detouree, un peu d'ombre. */
.at-dos-vue {
  display: grid; place-items: center; height: 170px;
  background: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(226, 176, 94, .14), transparent 72%);
}
.at-dos-vue img { height: 150px; width: auto; filter: drop-shadow(0 8px 12px rgba(0, 0, 0, .55)); }
/* LA LIGNE CLASSIQUE SE PERDAIT DANS LE FOND : un velours a 0x2a sur une
   tuile a peine plus claire. Le halo blanc des cuirs ne suffit pas ; on
   eclaire donc la boite par derriere, dans l'or de sa dorure, et un
   detourage dore la decoupe du fond. */
#deck-boite-classique .at-boite-vue {
  background: radial-gradient(ellipse 95% 88% at 50% 48%, rgba(226, 176, 94, .30), rgba(226, 176, 94, .12) 50%, transparent 92%);
}
#deck-boite-classique .at-boite-vue img {
  filter: drop-shadow(0 0 1px rgba(240, 200, 120, .55)) drop-shadow(0 0 18px rgba(226, 176, 94, .40));
}

/* ══ ATELIER : LE KIT A GAUCHE, LES FILTRES EN HAUT ══════════════════════
   La colonne de gauche presente le kit (boite, plateau, des) ; les filtres
   passent en une bande sous la barre du deck, juste au-dessus de la galerie
   qu ils filtrent. */
@media (min-width: 501px) {
  #view-atelier .dk-haut { grid-template-columns: minmax(200px, 280px) minmax(0, 1fr) auto; }

  /* La bande des filtres */
  #view-atelier .deck-rail .filtres-haut {
    display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 18px;
    margin-top: 12px; padding: 10px 0 2px; overflow: visible; max-height: none;
    position: static; transform: none; visibility: visible; box-shadow: none;
    border: 0 !important; border-top: 1px solid rgba(201, 162, 70, .25) !important;
    border-radius: 0; background: transparent !important;
  }
  #view-atelier .deck-rail .filtres-haut::before { content: none; }
  #view-atelier .deck-rail .filtres-haut .search-box { width: 220px; flex: none; }
  #view-atelier .deck-rail .filtres-haut .filter-group { flex-direction: row; align-items: center; gap: 8px; }
  #view-atelier .deck-rail .filtres-haut .filter-lbl { font-size: 10.5px; }
  #view-atelier .deck-rail .filtres-haut .filter-lbl small { display: none; }
  #view-atelier .deck-rail .filtres-haut .f-els,
  #view-atelier .deck-rail .filtres-haut .f-types,
  #view-atelier .deck-rail .filtres-haut .f-rars { display: flex; flex-direction: row; flex-wrap: wrap; gap: 4px; }
  #view-atelier .deck-rail .filtres-haut .f-el,
  #view-atelier .deck-rail .filtres-haut .f-type {
    flex-direction: row; width: auto; padding: 6px 10px; gap: 6px; font-size: 12px; border-radius: 999px;
  }
  #view-atelier .deck-rail .filtres-haut .f-el i,
  #view-atelier .deck-rail .filtres-haut .f-type-ico { width: 15px; height: 15px; }
  #view-atelier .deck-rail .filtres-haut .f-rar {
    width: auto; padding: 5px 10px; gap: 6px; font-size: 12px; border-radius: 999px;
    border: 1px solid var(--line) !important; background: rgba(255, 255, 255, .05);
  }
  #view-atelier .deck-rail .filtres-haut .f-rar.is-on { border-color: var(--rc) !important; }
  #view-atelier .deck-rail .filtres-haut .f-rar small { display: none; }
  #view-atelier .deck-rail .filtres-haut .f-reset { padding: 6px 12px; border-radius: 999px; }

  /* La colonne du kit */
  #view-atelier .kit {
    display: block; min-height: 0; overflow-y: auto; padding: 12px;
    background: #1c2433; border-right: 1px solid rgba(201, 162, 70, .3);
  }
  #view-atelier .kit .vitrine { display: flex; flex-direction: column; gap: 12px; }
  #view-atelier .kit .vt-tuile { width: 100%; }
  #view-atelier .kit .vt-t-boite { height: 270px; }
  #view-atelier .kit .vt-t-plateau { height: 170px; }
  #view-atelier .kit .vt-t-de { height: 150px; }
  #view-atelier .kit .vt-boite .cof3d { width: 240px; height: 240px; margin-left: -120px; top: -12px; }
  #view-atelier .kit .vt-boite .cof3d-plan { transform: scale(.24); }
}
@media (max-width: 700px) {
  #view-atelier .kit { display: none; }
}

/*  Le kit tient sans defiler sur un ecran de 900 px : les trois tuiles
    perdent un peu de hauteur plutot que de pousser les Des hors du cadre. */
@media (min-width: 501px) {
  #view-atelier .kit { overflow: hidden; }
  #view-atelier .kit .vitrine { gap: 10px; }
  #view-atelier .kit .vt-t-boite { height: 250px; }
  #view-atelier .kit .vt-t-plateau { height: 150px; }
  #view-atelier .kit .vt-t-de { height: 130px; }
  #view-atelier .kit .vt-boite .cof3d { width: 222px; height: 222px; margin-left: -111px; top: -10px; }
  #view-atelier .kit .vt-boite .cof3d-plan { transform: scale(.222); }
  #view-atelier .kit .vt-t-de .vt-de-hote canvas { width: 96px; height: 96px; }
}

/* ══ ATELIER : LA COMPOSITION SOUS LE KIT, LES FILTRES EN MAJESTE ════════
   Le coffret (compte, creatures, energies, elements) descend sous les des.
   La barre du haut devient trois colonnes : le deck, les filtres, les
   actions -- et les filtres ont enfin la place d etre de vrais boutons. */
@media (min-width: 501px) {
  /* ── La barre du haut : dk-haut s efface, ses enfants rejoignent la grille */
  #view-atelier .deck-rail {
    display: grid; grid-template-columns: minmax(190px, 250px) minmax(0, 1fr) auto;
    column-gap: 24px; align-items: center; padding: 14px 22px;
  }
  #view-atelier .dk-haut { display: contents; }
  #view-atelier .dk-ident { grid-column: 1; grid-row: 1; }
  #view-atelier .dk-actions { grid-column: 3; grid-row: 1; }
  #view-atelier .deck-rail .fan-container { display: none; }
  #view-atelier .deck-rail .filtres-haut {
    grid-column: 2; grid-row: 1; margin: 0; padding: 0 0 0 24px;
    border-top: 0 !important; border-left: 1px solid rgba(201, 162, 70, .25) !important;
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  }
  #view-atelier .deck-rail .filtres-haut .filter-lbl { display: none; }
  #view-atelier .deck-rail .filtres-haut .filter-group + .filter-group {
    padding-left: 14px; border-left: 1px solid rgba(255, 255, 255, .08);
  }

  /* ── La recherche */
  #view-atelier .deck-rail .filtres-haut .search-box { width: 250px; }
  #view-atelier .deck-rail .filtres-haut .search-box input {
    height: 40px; padding: 0 14px 0 36px; font-size: 14px; border-radius: 999px;
    background: rgba(255, 255, 255, .06); border: 1px solid rgba(255, 255, 255, .12);
    color: var(--ink-bright);
  }
  #view-atelier .deck-rail .filtres-haut .search-box input:focus {
    outline: none; border-color: #e8c25a; box-shadow: 0 0 0 3px rgba(232, 194, 90, .18);
  }
  #view-atelier .deck-rail .filtres-haut .search-icon { left: 14px; font-size: 13px; }

  /* ── Les boutons : une pastille, une pierre a gauche, le nom */
  #view-atelier .deck-rail .filtres-haut .f-el,
  #view-atelier .deck-rail .filtres-haut .f-type,
  #view-atelier .deck-rail .filtres-haut .f-rar {
    position: relative; display: inline-flex; align-items: center; gap: 8px;
    height: 40px; width: auto; padding: 0 16px 0 7px; border-radius: 999px;
    font-size: 13px; font-weight: 600; color: var(--ink) !important;
    background: linear-gradient(180deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .03)) !important;
    border: 1px solid rgba(255, 255, 255, .12) !important;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 2px 6px rgba(0, 0, 0, .25) !important;
    transition: transform .14s ease, border-color .14s ease, background .14s ease, box-shadow .14s ease;
  }
  #view-atelier .deck-rail .filtres-haut .f-el:hover,
  #view-atelier .deck-rail .filtres-haut .f-type:hover,
  #view-atelier .deck-rail .filtres-haut .f-rar:hover {
    transform: translateY(-1px); color: #fff !important;
    border-color: rgba(232, 194, 90, .6) !important;
  }

  /* La pierre : un disque colore sous l icone */
  #view-atelier .deck-rail .filtres-haut .f-el::before,
  #view-atelier .deck-rail .filtres-haut .f-type::before {
    content: ""; position: absolute; left: 6px; top: 50%; width: 28px; height: 28px;
    margin-top: -14px; border-radius: 50%;
    background: color-mix(in srgb, var(--el, #c9a246) 22%, #0f1520);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--el, #c9a246) 45%, transparent);
  }
  #view-atelier .deck-rail .filtres-haut .f-el i,
  #view-atelier .deck-rail .filtres-haut .f-type-ico {
    position: relative; z-index: 1; width: 16px; height: 16px; margin: 0 6px 0 6px; flex: none;
  }
  #view-atelier .deck-rail .filtres-haut .f-el i { background: var(--el) !important; }
  #view-atelier .deck-rail .filtres-haut .f-type-ico { color: #e8c25a; }

  /* Allume : la couleur de l element, ou l or pour les types */
  #view-atelier .deck-rail .filtres-haut .f-el.is-on {
    color: #fff !important; border-color: var(--el) !important;
    background: linear-gradient(180deg, color-mix(in srgb, var(--el) 38%, #1c2433), color-mix(in srgb, var(--el) 20%, #1c2433)) !important;
    box-shadow: 0 0 0 1px var(--el), 0 0 16px color-mix(in srgb, var(--el) 45%, transparent) !important;
  }
  #view-atelier .deck-rail .filtres-haut .f-el.is-on::before { background: color-mix(in srgb, var(--el) 55%, #0f1520); }
  #view-atelier .deck-rail .filtres-haut .f-el.is-on i { background: #fff !important; }
  #view-atelier .deck-rail .filtres-haut .f-type.is-on {
    color: #1a1202 !important; border-color: #ffe082 !important;
    background: var(--gold-grad) !important;
    box-shadow: 0 0 16px rgba(245, 185, 66, .4) !important;
  }
  #view-atelier .deck-rail .filtres-haut .f-type.is-on::before { background: rgba(0, 0, 0, .22); box-shadow: none; }
  #view-atelier .deck-rail .filtres-haut .f-type.is-on .f-type-ico { color: #1a1202; }

  /* Les raretes : une gemme qui brille */
  #view-atelier .deck-rail .filtres-haut .f-rar { padding-left: 12px; }
  #view-atelier .deck-rail .filtres-haut .f-rar .f-swatch {
    width: 12px; height: 12px; border-radius: 3px; transform: rotate(45deg);
    background: var(--rc); box-shadow: 0 0 8px var(--rc), inset 0 0 0 1px rgba(255, 255, 255, .35);
  }
  #view-atelier .deck-rail .filtres-haut .f-rar span { flex: none; }
  #view-atelier .deck-rail .filtres-haut .f-rar.is-on {
    color: #fff !important; border-color: var(--rc) !important;
    background: linear-gradient(180deg, color-mix(in srgb, var(--rc) 32%, #1c2433), color-mix(in srgb, var(--rc) 14%, #1c2433)) !important;
    box-shadow: 0 0 0 1px var(--rc), 0 0 14px color-mix(in srgb, var(--rc) 40%, transparent) !important;
  }

  #view-atelier .deck-rail .filtres-haut .f-reset {
    height: 40px; padding: 0 16px; border-radius: 999px; font-size: 13px;
  }

  /* ── La colonne du kit : la composition sous les des */
  #view-atelier .kit .vitrine { gap: 8px; }
  #view-atelier .kit .vt-t-boite { height: 210px; }
  #view-atelier .kit .vt-t-plateau { height: 120px; }
  #view-atelier .kit .vt-t-de { height: 104px; }
  #view-atelier .kit .vt-boite .cof3d { width: 184px; height: 184px; margin-left: -92px; top: -8px; }
  #view-atelier .kit .vt-boite .cof3d-plan { transform: scale(.184); }
  #view-atelier .kit .vt-t-de .vt-de-hote { inset: 6px 0 44px 0; }
  #view-atelier .kit .vt-t-de .vt-de-hote canvas { width: 62px; height: 62px; }
  #view-atelier .kit .vt-legende { padding: 4px 10px 5px; }
  #view-atelier .kit .vt-legende b { font-size: 12.5px; }

  #view-atelier .kit .dk-jauges { display: block; margin-top: 8px; }
  #view-atelier .kit .coffret { grid-template-columns: 1fr; }
  #view-atelier .kit .cof-couvercle {
    flex-direction: row; align-items: baseline; justify-content: space-between; gap: 8px;
    padding: 6px 14px; border-right: 0; border-bottom: 1px solid rgba(201, 162, 70, .3);
  }
  #view-atelier .kit .cof-total { font-size: 24px; }
  #view-atelier .kit .cof-etiquette { border-left: 0; padding: 7px 14px 9px; gap: 5px; }
}

/*  LE NOM DU DECK MONTE AU-DESSUS DE SA BOITE, dans la colonne du kit. La
    barre du haut ne garde que les filtres et les actions. */
@media (min-width: 501px) {
  #view-atelier .deck-rail { grid-template-columns: minmax(0, 1fr) auto; }
  #view-atelier .deck-rail .filtres-haut {
    grid-column: 1; padding-left: 0; border-left: 0 !important;
  }
  #view-atelier .dk-actions { grid-column: 2; }
  #view-atelier .kit { overflow: visible; position: relative; z-index: 5; }
  #view-atelier .kit .dk-ident { gap: 4px; margin-bottom: 8px; }
  #view-atelier .kit .dk-liste-btn { padding: 4px 10px; }
  #view-atelier .kit .dk-nom .deck-name { font-size: 18px; padding: 2px 24px 2px 0; }
  #view-atelier .kit .dk-liste { width: 320px; }
  #view-atelier .kit .vt-t-boite { height: 196px; }
  #view-atelier .kit .vt-t-plateau { height: 110px; }
  #view-atelier .kit .vt-t-de { height: 96px; }
  #view-atelier .kit .vt-boite .cof3d { width: 170px; height: 170px; margin-left: -85px; top: -8px; }
  #view-atelier .kit .vt-boite .cof3d-plan { transform: scale(.17); }
  #view-atelier .kit .vt-t-de .vt-de-hote canvas { width: 56px; height: 56px; }
}

/* ══ LE KIT PREND TOUTE LA HAUTEUR ═══════════════════════════════════════
   Boite, plateau et des se partagent la colonne (3 / 2 / 1.5) ; la
   composition reste en bas. La boite et le de suivent leur tuile. */
@media (min-width: 501px) {
  #view-atelier .kit { display: flex; flex-direction: column; min-height: 0; }
  #view-atelier .kit .dk-ident { flex: none; }
  #view-atelier .kit .vitrine { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
  #view-atelier .kit .vt-t-boite { flex: 3 1 0; height: auto; min-height: 150px; }
  #view-atelier .kit .vt-t-plateau { flex: 2 1 0; height: auto; min-height: 100px; }
  #view-atelier .kit .vt-t-de { flex: 1.5 1 0; height: auto; min-height: 90px; }
  #view-atelier .kit .dk-jauges { flex: none; }
  #view-atelier .kit .vt-boite .cof3d {
    width: var(--cof, 170px); height: var(--cof, 170px);
    margin-left: calc(var(--cof, 170px) / -2); top: -4%;
  }
  #view-atelier .kit .vt-boite .cof3d-plan { transform: scale(var(--k, .17)); }
  #view-atelier .kit .vt-t-de .vt-de-hote { inset: 0 0 42px 0; }
  #view-atelier .kit .vt-t-de .vt-de-hote canvas { width: var(--de, 56px); height: var(--de, 56px); }
}

/*  LE DOS REJOINT LA VITRINE (Alexandre, 20/10/2026) : il ne se choisit plus
    qu'a l'Atelier. Pour ne rien voler a la boite ni au plateau, il partage
    la derniere rangee avec les des : la colonne passe en grille. */
@media (min-width: 501px) {
  #view-atelier .kit .vitrine {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(140px, 2.6fr) minmax(90px, 1.6fr) minmax(130px, 2.2fr);
  }
  #view-atelier .kit .vt-t-boite, #view-atelier .kit .vt-t-plateau { grid-column: 1 / -1; }
  #view-atelier .kit .vt-t-de { grid-column: 1; grid-row: 3; }
  #view-atelier .kit .vt-t-dos { grid-column: 2; grid-row: 3; }
  #view-atelier .kit .vt-tuile { height: auto; min-height: 0; }
}
/*  Le panneau du kit a une barre collante en haut : une rangee ouverte
    depuis la vitrine s'arrete sous elle, titre visible. */
#atelier-table .at-bloc { scroll-margin-top: 76px; }
#view-atelier .vt-t-dos .vt-dos-hote .vt-dos-3d { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#view-atelier .vt-t-dos .vt-dos-hote.est-3d img { visibility: hidden; }
#view-atelier .vt-t-dos .vt-dos-hote img {
  position: absolute; inset: 6px 0 4px; margin: auto;
  width: 100%; height: calc(100% - 10px); object-fit: contain;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .6));
}

/* ══ LE MENU DU HAUT, EN QUATRE PANNEAUX ═════════════════════════════════
   Rechercher | Élément
   Type       | Rareté
   Chaque panneau a son titre dore et son fond : on lit d un coup d oeil ce
   que filtre chaque rangee de boutons. */
@media (min-width: 501px) {
  #view-atelier .deck-rail { padding: 12px 20px; column-gap: 20px; }
  #view-atelier .deck-rail .filtres-haut {
    display: grid !important; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
    grid-template-areas: "rech elem" "type rar"; gap: 10px;
  }
  #view-atelier .deck-rail .filtres-haut .filter-group,
  #view-atelier .deck-rail .filtres-haut .filter-group + .filter-group {
    display: flex; flex-direction: column; align-items: stretch; gap: 7px;
    padding: 8px 12px 10px !important; border-radius: 12px;
    background: rgba(255, 255, 255, .035);
    border: 1px solid rgba(255, 255, 255, .08) !important;
  }
  #view-atelier .deck-rail .filtres-haut .fg-rech { grid-area: rech; }
  #view-atelier .deck-rail .filtres-haut .fg-elem { grid-area: elem; }
  #view-atelier .deck-rail .filtres-haut .fg-type { grid-area: type; }
  #view-atelier .deck-rail .filtres-haut .fg-rar { grid-area: rar; }
  #view-atelier .deck-rail .filtres-haut .filter-lbl {
    display: flex !important; align-items: baseline; justify-content: space-between;
    font-size: 10.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: #c9a246;
  }
  #view-atelier .deck-rail .filtres-haut .filter-lbl small {
    display: inline; letter-spacing: 0; text-transform: none; font-weight: 600; color: var(--ink-faint);
  }
  #view-atelier .deck-rail .filtres-haut .fg-ligne { display: flex; gap: 8px; align-items: center; }
  #view-atelier .deck-rail .filtres-haut .search-box { flex: 1; width: auto; }
  #view-atelier .deck-rail .filtres-haut .search-box input { height: 36px; }
  #view-atelier .deck-rail .filtres-haut .f-reset { height: 36px; flex: none; }
  #view-atelier .deck-rail .filtres-haut .f-el,
  #view-atelier .deck-rail .filtres-haut .f-type,
  #view-atelier .deck-rail .filtres-haut .f-rar { height: 34px; padding: 0 12px 0 5px; font-size: 12.5px; gap: 6px; }
  #view-atelier .deck-rail .filtres-haut .f-rar { padding-left: 11px; }
  #view-atelier .deck-rail .filtres-haut .f-el::before,
  #view-atelier .deck-rail .filtres-haut .f-type::before { left: 5px; width: 24px; height: 24px; margin-top: -12px; }
  #view-atelier .deck-rail .filtres-haut .f-el i,
  #view-atelier .deck-rail .filtres-haut .f-type-ico { width: 14px; height: 14px; margin: 0 5px; }
  #view-atelier .deck-rail .filtres-haut .f-els,
  #view-atelier .deck-rail .filtres-haut .f-types,
  #view-atelier .deck-rail .filtres-haut .f-rars { gap: 6px; }
}

/* Deux colonnes egales : a 1600 px, « Pieges » tombait seul sur une seconde
   ligne du panneau Type. */
@media (min-width: 501px) {
  #view-atelier .deck-rail .filtres-haut { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* La boite, centree et agrandie dans sa tuile (taille et marge calculees par
   ajusterTaillesKit). */
@media (min-width: 501px) {
  #view-atelier .kit .vt-boite .cof3d { top: var(--cof-top, 0px); }
}
@media (min-width: 501px) {
  #view-atelier .kit .vt-boite .cof3d { left: var(--cof-left, 0px); margin-left: 0; }
}

/* ══ LES ACTIONS DU DECK ══════════════════════════════════════════════════
   « Construire » : trois outils au trait, alignes. « Jouer » : rouge, avec
   un de blanc a huit faces. */
@media (min-width: 501px) {
  #view-atelier .dk-actions { align-items: center; gap: 16px; }
  #view-atelier .dk-outils { gap: 6px; min-width: 176px; }
  .dk-outils-titre {
    font-size: 10.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: #c9a246;
    margin-bottom: 2px;
  }
  #view-atelier .dk-outils .dk-outil,
  #view-atelier .dk-outils .auto-group button {
    display: inline-flex; align-items: center; gap: 8px; height: 34px;
    font-size: 13px !important; font-weight: 600;
  }
  #view-atelier .dk-outils .auto-group .auto-caret { justify-content: center; width: 34px; padding: 0 !important; }
  .dk-ico {
    width: 16px; height: 16px; flex: none; fill: none; stroke: #e8c25a;
    stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  }
  #deck-clear .dk-ico { stroke: #f0a39b; }
  #view-atelier #deck-clear:hover { border-color: rgba(240, 120, 110, .6) !important; }
}

/* Le bouton Jouer, rouge */
#view-atelier .dk-jouer .play-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  min-width: 190px; padding: 16px 28px !important; font-size: 20px !important; font-weight: 800;
  letter-spacing: .03em; color: #fff !important; border-radius: 12px;
  background: linear-gradient(180deg, #e84a3f 0%, #b8261f 100%) !important;
  border: 1px solid #ff8f80 !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 8px 22px rgba(200, 40, 30, .45) !important;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
#view-atelier .dk-jouer .play-btn:hover:not(:disabled) {
  background: linear-gradient(180deg, #f35a4e 0%, #c92f27 100%) !important;
  transform: translateY(-1px);
}
#view-atelier .dk-jouer .play-btn:disabled {
  background: linear-gradient(180deg, #5a3432, #3e2322) !important;
  border-color: rgba(255, 143, 128, .25) !important; color: rgba(255, 255, 255, .45) !important;
  box-shadow: none !important; text-shadow: none;
}
.de8 { width: 28px; height: 28px; flex: none; filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .35)); }
.de8-corps { fill: #ffffff; stroke: #2a0e0c; stroke-width: 1.3; stroke-linejoin: round; }
.de8-face { fill: rgba(0, 0, 0, .12); }
.de8-arete { fill: none; stroke: #2a0e0c; stroke-width: 1.1; stroke-linejoin: round; opacity: .55; }
.play-btn:disabled .de8 { opacity: .55; }
#view-atelier .dk-jouer .play-why { color: #ff9d92; }
#view-atelier .dk-jouer .play-why.is-ok { color: #6ee7b7; }

/* Le menu du remplissage : les vraies icones d element */
#view-atelier .auto-pop { width: 330px; background: #1c2433 !important; }
.auto-pop-titre { font-size: 13px !important; color: var(--ink-bright) !important; margin-bottom: 2px !important; }
.auto-pop-aide { margin: 0 0 10px; font-size: 11.5px; color: var(--ink-faint); }
#view-atelier .auto-pop .el-chip {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px 0 8px;
  border-radius: 999px; font-size: 13px; font-weight: 600; color: var(--ink);
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12);
}
#view-atelier .auto-pop .el-chip i {
  display: block; width: 16px; height: 16px; flex: none; background: var(--el);
  -webkit-mask: var(--ico) center / contain no-repeat; mask: var(--ico) center / contain no-repeat;
}
#view-atelier .auto-pop .el-chip:hover { border-color: var(--el); color: #fff; }
/* Eteinte = en retrait (texte gris, icone grise, fond vide) ; allumee = pleine
   couleur de l'element, bord epais, icone blanche et coche. Les deux etats
   doivent se distinguer d'un coup d'oeil, pas a la nuance de bordure pres. */
#view-atelier .auto-pop .el-chip:not(.is-on) { color: var(--ink-dim); background: transparent; }
#view-atelier .auto-pop .el-chip:not(.is-on) i { background: var(--ink-faint); }
#view-atelier .auto-pop .el-chip:not(.is-on):hover i { background: var(--el); }
#view-atelier .auto-pop .el-chip.is-on {
  color: #fff !important; font-weight: 800;
  background: color-mix(in srgb, var(--el) 62%, #0b0f18) !important;
  border: 2px solid color-mix(in srgb, var(--el) 70%, #fff) !important;
  padding: 0 10px 0 7px;
  box-shadow: 0 0 14px color-mix(in srgb, var(--el) 55%, transparent);
}
#view-atelier .auto-pop .el-chip.is-on i { background: #fff; }
#view-atelier .auto-pop .el-chip.is-on::after { content: "✓"; font-size: 13px; font-weight: 900; margin-left: 1px; }
#view-atelier .auto-pop .el-note { display: block; margin-top: 10px; font-size: 12px; color: var(--ink-dim); }

/* ══ MON PROFIL ═══════════════════════════════════════════════════════════
   La carte du joueur dans la barre du haut, et la page entiere. */

/* ── La carte du haut */
.profil-chip {
  display: inline-flex; align-items: center; gap: 10px;
  height: 52px; padding: 4px 16px 4px 4px; margin-right: 10px;
  border-radius: 999px; cursor: pointer; text-align: left;
  background: linear-gradient(180deg, #243047, #171e2c);
  border: 1px solid rgba(201, 162, 70, .55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 4px 14px rgba(0, 0, 0, .35);
  transition: border-color .15s ease, transform .15s ease;
}
.profil-chip:hover { border-color: #e8c25a; transform: translateY(-1px); }
.pc-avatar {
  position: relative; flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; overflow: hidden;
  background: #0f1520; box-shadow: 0 0 0 2px #c9a246, 0 0 10px rgba(232, 194, 90, .35);
}
.pc-avatar .dl-rond { width: 100%; height: 100%; border-radius: 50%; overflow: hidden; }
.pc-avatar img { width: 100%; height: 100%; object-fit: cover; }
.pc-avatar .dl-initiales { font-weight: 800; font-size: 15px; color: #ffe3a0; }
.pc-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pc-nom { font-size: 13.5px; color: #fff3d6; max-width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-niveau { font-style: normal; font-size: 11px; color: #c9a246; font-weight: 700; }
.pc-jauge { display: block; width: 110px; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, .1); overflow: hidden; }
.pc-jauge i { display: block; height: 100%; background: var(--gold-grad, #e8c25a); }

/* ── Les notifications (js/notifications.js) : une pastille sur l'avatar, un
   panneau sous la carte du haut. La pastille est posee sur la carte et non
   dans le rond, qui coupe ce qui depasse. */
.profil-chip { position: relative; }
.pc-notif {
  position: absolute; top: -3px; left: 30px; z-index: 2;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  display: grid; place-items: center;
  font: 800 10.5px/1 'Outfit', sans-serif; color: #fff;
  background: #d8432f; box-shadow: 0 0 0 2px #171e2c, 0 0 10px rgba(216, 67, 47, .6);
  pointer-events: none; animation: pc-notif-pouls 2.4s ease-in-out infinite;
}
.pc-notif[hidden] { display: none; }
@keyframes pc-notif-pouls {
  0%, 100% { box-shadow: 0 0 0 2px #171e2c, 0 0 6px rgba(216, 67, 47, .45); }
  50% { box-shadow: 0 0 0 2px #171e2c, 0 0 14px rgba(216, 67, 47, .9); }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .pc-notif { animation: none; } }

.notif-panneau {
  position: fixed; z-index: 9000;
  max-height: min(70vh, 520px); display: flex; flex-direction: column;
  border-radius: 14px; overflow: hidden;
  background: linear-gradient(180deg, #1f2a3e, #141b28);
  border: 1px solid rgba(201, 162, 70, .55);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(255, 255, 255, .05);
  color: #f3e9d2; font-family: 'Outfit', sans-serif;
}
.np-tete {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid rgba(201, 162, 70, .25);
}
.np-tete b { font-family: 'Cinzel', serif; font-size: 14px; letter-spacing: .04em; color: #ffe3a0; }
.np-actions { display: flex; align-items: center; gap: 6px; }
.np-profil {
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  font: 600 12px 'Outfit', sans-serif; color: #1a1406;
  background: var(--gold-grad, #e8c25a); border: 0;
}
/* Plus fort que `button:hover:not(:disabled)` (le fond sombre des boutons du
   site), qui effacait le bouton dore au survol. */
.notif-panneau .np-profil:hover:not(:disabled) {
  background: var(--gold-grad, #e8c25a); border: 0; filter: brightness(1.08);
}
.np-quitter {
  padding: 6px 11px; border-radius: 999px; cursor: pointer;
  font: 600 12px 'Outfit', sans-serif; color: #ffe3a0;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(201, 162, 70, .45);
}
.notif-panneau .np-quitter:hover:not(:disabled) {
  background: rgba(232, 194, 90, .14); border-color: #e8c25a; color: #fff;
}
.np-liste { overflow-y: auto; overscroll-behavior: contain; padding: 6px; }
.np-vide { margin: 0; padding: 18px 12px; font-size: 13px; line-height: 1.45; color: #b9b1a0; text-align: center; }
.np-item {
  display: flex; gap: 11px; align-items: flex-start; justify-content: flex-start; width: 100%;
  padding: 10px; border-radius: 10px; border: 0; background: transparent; box-shadow: none;
  color: inherit; font: inherit; text-align: left;
}
button.np-item { cursor: pointer; }
.notif-panneau button.np-item:hover:not(:disabled) {
  background: rgba(255, 255, 255, .05); border: 0; box-shadow: none; transform: none;
}
.notif-panneau button.np-item.is-neuve:hover:not(:disabled) {
  background: rgba(232, 194, 90, .14); box-shadow: inset 3px 0 0 #e8c25a;
}
.np-item + .np-item { margin-top: 2px; }
.np-item.is-neuve { background: rgba(232, 194, 90, .09); box-shadow: inset 3px 0 0 #e8c25a; }
.np-icone {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; color: #ffe3a0;
  background: rgba(201, 162, 70, .16); box-shadow: inset 0 0 0 1px rgba(201, 162, 70, .4);
}
.np-icone svg { width: 18px; height: 18px; }
.np-vente { color: #9fe0b0; background: rgba(80, 180, 110, .14); box-shadow: inset 0 0 0 1px rgba(80, 180, 110, .4); }
.np-classement { color: #c7b8ff; background: rgba(140, 115, 230, .15); box-shadow: inset 0 0 0 1px rgba(140, 115, 230, .4); }
.np-txt { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.np-titre { font-size: 13px; font-weight: 700; color: #fff3d6; }
.np-texte { font-size: 12.5px; color: #d8cfbd; overflow-wrap: anywhere; }
.np-prix { font-size: 12.5px; font-weight: 700; color: #e8c25a; }
.np-quand { font-style: normal; font-size: 11px; color: #8f8879; }
.notif-panneau .np-tout {
  display: block; width: 100%; margin-top: 4px; padding: 9px 10px;
  border: 0; border-top: 1px solid rgba(201, 162, 70, .2); border-radius: 0 0 10px 10px;
  background: transparent; box-shadow: none;
  font: 600 12.5px 'Outfit', sans-serif; color: #e8c25a; text-align: center;
}
.notif-panneau .np-tout:hover:not(:disabled) {
  background: rgba(232, 194, 90, .08); border-color: rgba(201, 162, 70, .2); box-shadow: none; transform: none;
}
.np-duree { margin: 4px 6px 6px; font-size: 11px; line-height: 1.4; color: #8f8879; text-align: center; }

/* ── La page
   LE PROFIL TIENT EN UN ECRAN, SUR LE FOND DU SITE (Alexandre, 20/10/2026).
   Le beige faisait page pas finie a cote de toutes les autres vues, et il
   fallait defiler jusqu'au kit. Deux colonnes : a gauche l'identite, debout,
   de haut en bas ; a droite les statistiques puis le kit, qui prend toute la
   hauteur qui reste -- ce sont ses vitrines 3D qui s'etirent, pas la page. */
#view-profil {
  overflow-y: auto;
  background:
    radial-gradient(900px 620px at 18% 30%, rgba(232, 194, 90, .07), transparent 70%),
    radial-gradient(1100px 700px at 85% 110%, rgba(90, 120, 190, .07), transparent 70%);
}
.profil-page {
  box-sizing: border-box; height: 100%; min-height: 600px;
  max-width: 1320px; margin: 0 auto; padding: 22px 32px 26px;
  display: grid; gap: 18px 22px;
  grid-template-columns: minmax(300px, 340px) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "carte stats" "carte kit";
}
.pf-carte, .pf-bloc {
  position: relative;
  background: linear-gradient(180deg, rgba(26, 33, 50, .92), rgba(12, 16, 26, .94));
  border: 1px solid rgba(201, 162, 70, .28); border-radius: 18px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 236, 190, .06);
}
.pf-bloc-stats { grid-area: stats; }
.pf-bloc-kit { grid-area: kit; display: flex; flex-direction: column; min-height: 0; }

/* La carte d'identite : une colonne, l'avatar en tete dans sa lueur. */
.pf-carte {
  grid-area: carte; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: clamp(10px, 2vh, 18px);
  padding: clamp(18px, 3.4vh, 30px) 26px clamp(16px, 2.6vh, 24px);
  background:
    radial-gradient(ellipse 90% 42% at 50% 0%, rgba(232, 194, 90, .16), transparent 70%),
    linear-gradient(180deg, rgba(26, 33, 50, .95), rgba(12, 16, 26, .96));
  border-color: rgba(201, 162, 70, .45);
}
/* Un filet d'or en haut, comme le liseré des cartes. */
.pf-carte::before {
  content: ''; position: absolute; left: 22%; right: 22%; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, #e8c25a, transparent);
}
.pf-avatar {
  flex: none; width: clamp(96px, 19vh, 168px); height: clamp(96px, 19vh, 168px); border-radius: 50%; display: grid; place-items: center; overflow: hidden;
  background: #0f1520;
  box-shadow: 0 0 0 4px #141a27, 0 0 0 6px #c9a246, 0 0 0 7px rgba(255, 236, 190, .25), 0 0 46px rgba(232, 194, 90, .32);
}
/* La carte du personnage remplace le rond (js/carte_perso.js) ; sa hauteur
   suit celle de l'ecran, comme le rond, pour que le profil tienne. */
.pf-carte-perso { flex: none; width: auto; height: clamp(100px, 19vh, 200px); cursor: pointer; }
/* L'ombre seule tient au survol (contre `button:hover`) ; la taille, non --
   sinon la carte reprendrait celle du site au survol dans le jeu (jeu.css). */
.pf-carte-perso,
button.pf-carte-perso:hover:not(:disabled) {
  box-shadow: 0 0 0 1px rgba(255, 236, 190, .25), 0 10px 30px rgba(0, 0, 0, .6), 0 0 40px rgba(232, 194, 90, .22);
}
.pf-a-carte > .pf-avatar { display: none; }
.pf-avatar .dl-rond { width: 100%; height: 100%; border-radius: 50%; overflow: hidden; }
.pf-avatar img { width: 100%; height: 100%; object-fit: cover; }
.pf-avatar .dl-initiales { font-size: 60px; font-weight: 800; color: #ffe3a0; }
.pf-ident {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  width: 100%; min-width: 0; flex: 1; text-align: center;
}
.pf-titre { font-size: 11px; font-weight: 800; letter-spacing: .26em; text-transform: uppercase; color: #c9a246; }
.pf-nom {
  margin: 0; max-width: 100%; font-family: var(--font-title); font-size: 28px; line-height: 1.1;
  color: #fff3d6; overflow-wrap: anywhere; text-shadow: 0 2px 14px rgba(232, 194, 90, .18);
}
.pf-desc { margin: 2px 0 0; color: var(--ink-dim); font-size: 13px; line-height: 1.45; max-width: 34ch; }

/*  Les deux progressions, chacune dans son encart : le niveau du profil (or)
    et la saison (violet). Le titre a gauche, le niveau a droite, la jauge
    dessous, la ligne de detail en dernier. */
.pf-progression {
  display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 6px 10px;
  width: 100%; box-sizing: border-box; margin-top: clamp(4px, 1.2vh, 10px); padding: clamp(8px, 1.4vh, 12px) 14px clamp(8px, 1.3vh, 11px);
  border-radius: 12px; text-align: left;
  background: rgba(0, 0, 0, .22); border: 1px solid rgba(255, 255, 255, .06);
}
.pf-progression + .pf-progression { margin-top: 2px; }
.pf-prog-titre { font-size: 10.5px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-dim); }
.pf-niveau { display: contents; }
.pf-niveau b { font-family: var(--font-num); font-size: 17px; color: #ffe3a0; justify-self: end; }
.pf-niveau span { grid-column: 1 / -1; grid-row: 3; font-size: 12px; color: var(--ink-dim); }
/*  Sans saison lue (pas de portefeuille), le message tient toute la ligne. */
.pf-niveau span:only-child { grid-row: auto; }
/*  LA JAUGE D'XP avait la platitude d'un bloc gris : a zero pour cent elle
    ressemblait a un element qui n'a pas fini de charger. Un creux et une
    lueur suffisent a la faire lire comme une reserve qu'on va remplir. */
.pf-jauge {
  grid-column: 1 / -1; height: 8px; border-radius: 999px; overflow: hidden;
  background: rgba(0, 0, 0, .5);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .75), inset 0 0 0 1px rgba(255, 220, 150, .12);
}
.pf-jauge i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #b9762a, #ffd478 60%, #fff2c8);
  box-shadow: 0 0 12px rgba(255, 200, 110, .7);
  transition: width .6s cubic-bezier(.16, 1, .3, 1);
}
.pf-xp-total { grid-column: 1 / -1; grid-row: 4; font-size: 11px; color: var(--ink-faint); }
.pf-saison .pf-jauge i {
  background: linear-gradient(90deg, #5b3aa8, #a98bff 60%, #e6dcff);
  box-shadow: 0 0 12px rgba(170, 140, 255, .6);
}
.pf-saison .pf-niveau b { color: #d9ccff; }
/* Le passe de saison offert, a activer (main.js, `majSaisonProfil`) : une
   ligne sous la jauge, sur toute la largeur. */
.pf-passe-offert { grid-column: 1 / -1; grid-row: 5; display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 4px 10px; margin-top: 2px; padding: 6px 6px 6px 10px; border-radius: 10px;
  font-size: 12.5px; color: #e9d7ff; background: rgba(190, 110, 255, .12); border: 1px solid rgba(190, 110, 255, .4); }
.pf-passe-offert > span { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-passe-offert small { flex: 1 1 100%; font-size: 11px; color: var(--ink-dim); }
.pf-passe-activer { flex: none; padding: 4px 14px; font-size: 12.5px; }

/* Les gestes, en bas de la carte : le principal en or, le second en filet. */
.pf-gestes {
  display: grid; grid-template-columns: 1fr; gap: 8px; width: 100%;
  margin-top: auto; padding-top: clamp(8px, 1.6vh, 14px);
}
#view-profil .pf-modifier {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  margin: 0; padding: 10px 12px; border-radius: 10px; font: 700 13px var(--font-ui); text-decoration: none;
  background: rgba(255, 255, 255, .04) !important; color: #ffe3a0 !important;
  border: 1px solid rgba(201, 162, 70, .55) !important; box-shadow: none !important;
  transition: background .15s ease, border-color .15s ease;
}
#view-profil .pf-modifier:hover { background: rgba(232, 194, 90, .14) !important; border-color: #e8c25a !important; }
#view-profil .pf-gestes > .pf-modifier:first-child {
  background: linear-gradient(180deg, #f3cf6e, #c9962e) !important; color: #1a1408 !important;
  border-color: #f3cf6e !important; box-shadow: 0 6px 18px rgba(232, 194, 90, .22) !important;
}
#view-profil .pf-gestes > .pf-modifier:first-child:hover { filter: brightness(1.08); }

/* Les blocs de droite : un titre en petites capitales, suivi d'un filet. */
.pf-bloc { padding: 18px 22px 20px; }
.pf-bloc h2 {
  display: flex; align-items: center; gap: 14px;
  margin: 0 0 14px; font-family: var(--font-title); font-size: 14px; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: #e8c25a;
}
.pf-bloc h2::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, rgba(201, 162, 70, .45), transparent);
}

/*  LES STATISTIQUES, sans boites : huit chiffres sur deux lignes, separes
    par des filets. La premiere ligne (le bilan) parle plus fort que la
    seconde (les records). */
.pf-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }
.pf-stat {
  display: flex; flex-direction: column; gap: 4px; padding: 6px 18px 8px;
  border-left: 1px solid rgba(255, 255, 255, .07);
}
.pf-stat:nth-child(4n + 1) { border-left: 0; padding-left: 2px; }
.pf-stat:nth-child(n + 5) { margin-top: 10px; padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, .07); }
.pf-stat b { font-family: var(--font-num); font-size: 30px; font-weight: 600; color: #fff3d6; line-height: 1; }
.pf-stat:nth-child(n + 5) b { font-size: 20px; }
.pf-stat span { font-size: 12px; color: var(--ink-dim); letter-spacing: .02em; }
/*  Le tiret s'efface : il dit « pas encore », pas « zero ». */
.pf-stat.est-vide b { color: var(--ink-faint); opacity: .6; }
.pf-stat.est-vide span { color: var(--ink-faint); }
.pf-stat.est-ok b { color: #6ee7b7; }
.pf-stat.est-ko b { color: #fca5a5; }
.pf-stat.est-or b { color: #ffd36b; }
.pf-note { margin: 10px 0 0; font-size: 12px; color: var(--ink-faint); }

/*  LE KIT prend la hauteur qui reste : quatre vitrines en portrait. */
.pf-kit {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px;
}
#view-profil .pf-tuile {
  display: flex; flex-direction: column; overflow: hidden; padding: 0; min-height: 0; text-align: left; cursor: pointer;
  border-radius: 14px;
  background: radial-gradient(ellipse 90% 60% at 50% 40%, #26324a, #10151f 80%) !important;
  border: 1px solid rgba(201, 162, 70, .3) !important; box-shadow: 0 10px 24px rgba(0, 0, 0, .35) !important;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
#view-profil .pf-tuile:hover {
  transform: translateY(-3px); border-color: #e8c25a !important;
  box-shadow: 0 14px 30px rgba(0, 0, 0, .45), 0 0 0 1px rgba(232, 194, 90, .25) !important;
}
.pf-vue {
  display: grid; place-items: center; flex: 1; min-height: 150px; background: center / cover no-repeat;
  container-type: size;
}
.pf-vue img { width: 70%; max-width: 170px; height: auto; max-height: 80%; object-fit: contain; }
.pf-de { width: min(64cqw, 64cqh); height: min(64cqw, 64cqh); }
.pf-vue-dos { background: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(226, 176, 94, .14), transparent 72%); }
.pf-vue-dos img { width: auto; height: 62%; filter: drop-shadow(0 8px 12px rgba(0, 0, 0, .55)); }
.pf-tuile-txt {
  display: flex; flex-direction: column; gap: 2px; padding: 11px 14px 13px;
  background: rgba(8, 11, 18, .88); border-top: 1px solid rgba(201, 162, 70, .25);
}
.pf-tuile-txt small { font-size: 10px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: #c9a246; }
.pf-tuile-txt b { font-size: 15px; color: #fff3d6; }
.pf-tuile-txt span { font-size: 11.5px; color: var(--ink-faint); }
/* « Modifier dans l'Atelier », dit au survol, au pied de chaque tuile. */
#view-profil .pf-tuile .pf-tuile-txt::after {
  content: 'Atelier →'; position: absolute; right: 14px; bottom: 13px;
  font-size: 11px; font-weight: 700; color: #e8c25a; opacity: 0; transition: opacity .15s ease;
}
#view-profil .pf-tuile .pf-tuile-txt { position: relative; }
#view-profil .pf-tuile:hover .pf-tuile-txt::after { opacity: 1; }

/*  PORTABLE BAS (720 px) : le total d'XP cumule repete la ligne du dessus,
    il cede sa place pour que la carte d'identite tienne. */
@media (max-height: 780px) and (min-width: 901px) {
  .pf-progression:not(.pf-saison) .pf-xp-total { display: none; }
}
/*  ECRAN TROP BAS : la page defile plutot que d'ecraser les vitrines. */
@media (max-height: 640px) and (min-width: 901px) {
  .profil-page { height: auto; }
  .pf-kit { min-height: 300px; }
}

/*  Sous 900 px (tablette en portrait), une seule colonne qui tient encore
    dans l'ecran : la carte d'identite en grille serree -- l'avatar, le nom,
    les gestes, puis les deux progressions en barres d'une ligne -- les
    statistiques sur quatre colonnes, et le kit d'une rangee qui prend la
    hauteur qui reste. mobile.css resserre les tailles sous 700 px. */
@media (max-width: 900px) {
  .profil-page {
    display: flex; flex-direction: column; height: 100%; min-height: 0; padding: 16px 18px 18px; gap: 12px;
    overflow-y: auto;
  }
  .pf-carte {
    flex: none; overflow: visible;
    display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
    grid-template-areas: "av titre" "av nom" "av gestes" "prof prof" "saison saison";
    gap: 3px 18px; padding: 18px 20px; text-align: left;
  }
  .pf-carte::before { display: none; }
  .pf-ident { display: contents; }
  .pf-avatar { grid-area: av; width: 104px; height: 104px; }
  .pf-a-carte > .pf-avatar { display: grid; }
  .pf-carte-perso { display: none; }
  .pf-titre { grid-area: titre; text-align: left; }
  .pf-nom { grid-area: nom; text-align: left; }
  .pf-desc { display: none; }
  .pf-gestes { grid-area: gestes; display: flex; flex-wrap: nowrap; gap: 8px; width: auto; margin: 0; padding-top: 6px; }
  .pf-progression {
    grid-area: prof; margin-top: 10px; padding: 8px 12px;
    grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: 2px 12px;
  }
  .pf-progression.pf-saison { grid-area: saison; margin-top: 6px; }
  .pf-prog-titre { grid-column: 1; grid-row: 1; }
  .pf-niveau b { grid-column: 2; grid-row: 1; justify-self: start; font-size: 15px; }
  .pf-jauge { grid-column: 3; grid-row: 1; }
  .pf-niveau span, .pf-niveau span:only-child { grid-column: 1 / -1; grid-row: 2; }
  .pf-xp-total { grid-row: 3; }
  .pf-bloc-stats { flex: none; }
  .pf-bloc-kit { flex: 1; min-height: 0; }
  .pf-kit { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
  .pf-vue { min-height: 0; }
  .pc-txt { display: none; }
  .profil-chip { padding: 4px; }
}
}

/*  LA PAGE PROFIL DEFILE DANS SON CADRE, pas le document : le jeu entier est
    bati sur un document qui ne defile jamais, et la barre du haut glissait
    avec lui. Meme calage que les autres vues plein ecran. */
#view-profil.is-on {
  height: calc(100dvh - var(--topbar-h)); overflow-y: auto; overscroll-behavior: contain;
}

/*  La carte du joueur tient DANS la barre du haut (58 px) : a 52 px elle la
    faisait grandir, et toutes les vues calees sur --topbar-h debordaient. */
.profil-chip { height: 42px; padding: 3px 14px 3px 3px; gap: 9px; }
.pc-avatar { width: 36px; height: 36px; box-shadow: 0 0 0 2px #c9a246, 0 0 8px rgba(232, 194, 90, .3); }
.pc-avatar .dl-initiales { font-size: 13px; }
.pc-txt { gap: 1px; }
.pc-nom { font-size: 12.5px; line-height: 1.1; }
.pc-niveau { font-size: 10.5px; line-height: 1.1; }
.pc-jauge { width: 96px; }

/*  La vue d une tuile du kit prend toute la largeur : celle du plateau n'a
    qu un fond, sans image ni canvas pour lui donner une taille, et tombait a
    zero pixel de large. */
#view-profil .pf-tuile .pf-vue { width: 100%; align-self: stretch; }

/*  LE PLATEAU DU KIT, EN 3D : la toile couvre la vignette, la photo dessous. */
#view-profil .pf-tuile .pf-vue-plateau { position: relative; overflow: hidden; }
#view-profil .pf-tuile .pf-vue-plateau .pf-plateau-3d { position: absolute; inset: 0; margin: auto; width: 100cqw; height: min(100cqw, 100cqh); display: block; }
#view-profil .pf-tuile .pf-vue-plateau.est-3d { background-image: none !important; }
#view-profil .pf-tuile .pf-vue-boite, #view-profil .pf-tuile .pf-vue-dos { position: relative; overflow: hidden; }
/*  LES VITRINES 3D DANS UN CARRE : leurs cameras sont reglees pour une
    vignette carree. Dans une tuile haute, la boite remplissait tout et le
    plateau se perdait ; le carre se centre, la lueur de la tuile l'entoure. */
#view-profil .pf-tuile .pf-vue .pf-3d { position: absolute; inset: 0; margin: auto; width: min(100cqw, 100cqh); height: min(100cqw, 100cqh); display: block; }
#view-profil .pf-tuile .pf-vue.est-3d > img { visibility: hidden; }

/*  DES ETIQUETTES DE MEME TAILLE (Alexandre, 18/10/2026) : chacune prenait
    la largeur de son texte, centree ou a gauche selon sa tuile. Toutes
    couvrent maintenant la largeur de la tuile, collees en bas, et les tuiles
    d'une rangee ont la meme hauteur. */
.pf-kit { grid-auto-rows: 1fr; }
#view-profil .pf-tuile { justify-content: space-between; }
#view-profil .pf-tuile .pf-tuile-txt { align-self: stretch; width: auto; margin-top: auto; box-sizing: border-box; }
#view-profil .pf-tuile .pf-tuile-txt > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ══ LE PORTEFEUILLE ═════════════════════════════════════════════════════
   Meme langage que la carte du joueur : pilule sombre, filet d'or. */
.wallet { position: relative; margin-right: 10px; }
.wallet-btn {
  height: 42px; padding: 0 16px; border-radius: 999px; cursor: pointer;
  font: 600 12.5px/1 inherit; color: #f1e3b8; white-space: nowrap;
  background: linear-gradient(180deg, #243047, #171e2c);
  border: 1px solid rgba(201, 162, 70, .55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 4px 14px rgba(0, 0, 0, .35);
}
.wallet-btn:hover { border-color: #e8c25a; }
.wallet-btn.is-connecte { font-family: ui-monospace, Consolas, monospace; color: #9fe0b4; }
.wallet-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 1000;
  min-width: 240px; padding: 8px; border-radius: 12px;
  background: #151b28; border: 1px solid rgba(201, 162, 70, .45);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .5);
  display: flex; flex-direction: column; gap: 4px;
}
.wallet-titre { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: #a89668; padding: 4px 8px; }
.wallet-adresse { font: 11px ui-monospace, Consolas, monospace; color: #cfd6e4; padding: 6px 8px; word-break: break-all; }
.wallet-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 8px;
  background: transparent; border: 0; color: #eee; font: inherit; font-size: 13px;
  text-align: left; cursor: pointer; text-decoration: none;
}
.wallet-item:hover { background: rgba(232, 194, 90, .12); }
.wallet-item:disabled { opacity: .5; cursor: wait; }
.wallet-item img { width: 22px; height: 22px; border-radius: 5px; }
/*  CE QU'ON POSSEDE SUR LA CHAINE : dore, parce que c'est un avoir, et
 *  separe de l'adresse par un filet -- l'adresse dit QUI, la ligne dit QUOI. */
/*  LA MARQUE DU MODE TEST, dans la barre du haut.
 *
 *  Un bandeau pleine largeur en bas recouvrait les onglets du telephone : une
 *  navigation masquee est pire qu'un mode test discret. Ici la mention ne
 *  prend la place de rien, suit la page partout, et le fond raye de la barre
 *  la rend impossible a confondre avec le vrai site -- y compris sur une
 *  capture d'ecran envoyee a quelqu'un.
 */
/*  La ligne « N grimoires en main » sert aussi a dire non : a sec elle
 *  s'eteint, en refus elle s'allume en rouge. Elle est deja sous les yeux du
 *  joueur au moment ou il clique -- inutile d'inventer une autre bulle. */
.rip-en-main.est-vide { opacity: .65; }
.rip-en-main.est-refus { color: #ff9b8a; opacity: 1; font-weight: 700; }

/*  DEUX MENTIONS COTE A COTE, ET DEUX COULEURS DIFFERENTES : elles ne disent
 *  pas la meme chose. L'or pour TEST -- rien n'est reel. Le bleu pour DEVNET
 *  -- la chaine est bien la, mais c'est un reseau d'essai. */

/*  LE PANNEAU DE LA CHAINE, en tete des statistiques. Il se distingue du reste
 *  de la page parce qu'il ne dit pas la meme chose : le reste compte ce que ce
 *  navigateur a vu, lui lit ce qui est. */
#stats-chaine { padding: 0 22px; }
#stats-chaine[hidden] { display: none; }
@media (max-width: 700px) { #stats-chaine { padding: 0 12px; } }
.ch-bloc {
  margin: 0 0 18px; padding: 16px 18px; border-radius: 12px;
  background: rgba(10, 13, 21, .55);
  border: 1px solid rgba(232, 194, 90, .22);
}
.ch-tete { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.ch-tete b { font: 700 14px/1 var(--font-title, inherit); letter-spacing: .1em; color: var(--or, #e8c25a); }
.ch-reseau {
  padding: 1px 6px; border-radius: 3px;
  font: 800 8px/1.4 system-ui, sans-serif; letter-spacing: .16em;
  color: #04121f; background: linear-gradient(180deg, #7fd4ff, #35a8e0);
}
.ch-sous { flex: 1 1 100%; font-size: 11px; color: var(--ink-faint, #8b93a5); }
.ch-grille {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.ch-chiffre {
  padding: 10px 12px; border-radius: 9px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
}
.ch-chiffre b { display: block; font: 700 22px/1.1 var(--font-title, inherit); color: #f2e6c8; }
.ch-libelle { display: block; margin-top: 3px; font-size: 11px; color: #cfd6e4; }
.ch-precision { display: block; margin-top: 2px; font-size: 10px; color: var(--ink-faint, #8b93a5); }
.ch-adresses {
  display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 14px;
  padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, .07);
}
.ch-adresse { display: flex; align-items: baseline; gap: 7px; font-size: 11px; }
.ch-nom { color: var(--ink-faint, #8b93a5); }
.ch-lien { color: #7fd4ff; text-decoration: none; font-family: ui-monospace, Consolas, monospace; }
.ch-lien:hover { text-decoration: underline; }
.ch-attente { font-size: 12px; color: var(--ink-faint, #8b93a5); }
/*  L'ecart ne s'affiche que s'il existe -- donc quand il s'affiche, il crie. */
.ch-alerte {
  margin-top: 12px; padding: 9px 12px; border-radius: 8px; font-size: 12px;
  color: #ffd2c6; background: rgba(255, 90, 60, .12);
  border: 1px solid rgba(255, 90, 60, .45);
}
@media (max-width: 700px) { .ch-bloc { padding: 13px 14px; } }

.brand-mentions { display: flex; gap: 4px; margin-bottom: 2px; }
.brand-test {
  align-self: flex-start;
  padding: 1px 6px; border-radius: 3px;
  font: 800 8px/1.3 system-ui, sans-serif; letter-spacing: .18em;
  color: #1a1206; background: var(--gold-grad, #e8c25a);
  border: 1px solid rgba(0, 0, 0, .35);
}
.brand-test.est-devnet {
  color: #04121f;
  background: linear-gradient(180deg, #7fd4ff, #35a8e0);
  border-color: rgba(0, 0, 0, .35);
}
/*  Le fond raye de la barre ne se pose QUE pour le mode test : en devnet la
 *  chaine est reelle, et rayer la barre laisserait croire a une simulation. */
body.en-devnet:not(.en-test) .topbar {
  border-bottom-color: rgba(127, 212, 255, .5);
}
body.en-test .topbar {
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(232, 194, 90, .10) 0 10px,
      rgba(232, 194, 90, .03) 10px 20px),
    rgba(10, 13, 21, .88);
  border-bottom-color: rgba(232, 194, 90, .55);
}

.wallet-paquets {
  font-size: 12px; color: var(--or, #e8c25a); padding: 6px 8px 8px;
  margin-bottom: 4px; border-bottom: 1px solid rgba(232, 194, 90, .18);
}
.wallet-paquets.est-test { color: #ffd98a; }
/*  LE SOL DU PORTEFEUILLE (main.js, transak.js) : discret quand il suffit,
 *  orange quand il ne permet plus d'ouvrir un grimoire. */
.wallet-sol { font-size: 12px; color: #cfd6e4; padding: 0 8px 6px; }
.wallet-sol.est-bas { color: #ffb36b; }
.wallet-transak { font-weight: 700; }
.logo-transak { width: 20px; height: 20px; flex: none; }
.fs-pied button .logo-transak { width: 18px; height: 18px; margin-right: 8px; vertical-align: -4px; }
/*  LE FORMULAIRE DU DON. Il vit DANS le menu du portefeuille, a la place du
 *  bouton qui l'a appele : une fenetre de plus pour deux champs, ce serait du
 *  ceremonial pour rien. */
.don-forme { display: flex; flex-direction: column; gap: 6px; padding: 6px 8px 8px; }
.don-champ {
  width: 100%; box-sizing: border-box;
  padding: 7px 9px; border-radius: 7px;
  background: rgba(0, 0, 0, .35); color: #eee;
  border: 1px solid rgba(232, 194, 90, .28);
  font: 12px ui-monospace, Consolas, monospace;
}
.don-champ:focus { outline: none; border-color: rgba(232, 194, 90, .7); }
.don-nombre { font-family: inherit; width: 90px; }
.don-envoi { justify-content: center; border: 1px solid rgba(232, 194, 90, .35); }
.don-envoi:hover { background: rgba(232, 194, 90, .16); }
.don-mot { font-size: 11px; color: var(--ink-faint, #8b93a5); min-height: 14px; }

.wallet-erreur { font-size: 12px; color: #ff9b8a; padding: 6px 8px; }
@media (max-width: 720px) { .wallet-btn { padding: 0 10px; font-size: 11px; } }

/* ══ MARCHE ════════════════════════════════════════════════════════════════
   Une vitrine, pas un classeur. On vient ici pour CHERCHER et PAYER, pas
   pour feuilleter. Grille, prix en SOL, filtres du Cartable plus le prix. */
body.marche-on { overflow: hidden; }
body.marche-on main { padding: 0; max-width: none; margin: 0; }
#view-marche.is-on {
  display: flex; flex-direction: column;
  height: calc(100dvh - var(--topbar-h));
  min-height: 0;
}
.marche {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(201, 162, 39, .10), transparent 60%),
    linear-gradient(180deg, #0b0910 0%, #07060b 100%);
}
.marche .cartable-tete { flex: none; }
.marche-onglets, .stats-onglets {
  display: flex; gap: 6px; flex: none;
}
.marche-onglets button, .stats-onglets button {
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(201, 162, 39, .22);
  color: var(--ink-dim, #a4b3cc);
  padding: 6px 12px; border-radius: 999px;
  font-size: 12.5px; letter-spacing: .04em;
}
.marche-onglets button.is-on, .stats-onglets button.is-on {
  background: rgba(245, 185, 66, .16);
  border-color: rgba(245, 185, 66, .55);
  color: var(--ink-bright, #fff);
  font-weight: 700;
}
.ma-mode-test {
  display: inline-flex; align-items: center; gap: 7px;
  margin-left: 4px; padding: 5px 11px; border-radius: 999px;
  border: 1px solid rgba(129, 254, 151, .35);
  background: rgba(129, 254, 151, .08);
  color: #b7f7c4; font-size: 12px; cursor: pointer; user-select: none;
  flex: none;
}
.ma-mode-test input { accent-color: #81fe97; margin: 0; }
.ma-mode-test:not(:has(:checked)) {
  border-color: rgba(201, 162, 39, .22);
  background: rgba(255, 255, 255, .04);
  color: var(--ink-dim, #a4b3cc);
}
.ma-prix-filtre input {
  width: 88px; padding: 6px 8px; font-size: 12px;
}
.marche-bandeau {
  flex: none;
  padding: 8px clamp(12px, 2vw, 28px) 0;
}
.ma-note, .ma-msg {
  margin: 0 0 8px; font-size: 12.5px; color: var(--ink-faint, #8d86a0);
}
.ma-msg--ok { color: #81fe97; }
.ma-msg--err { color: #ff9b8a; }
.marche-corps {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 16px clamp(12px, 2vw, 28px) 40px;
}
.ma-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
  gap: 22px 16px;
  align-content: start;
}
.ma-tuile {
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px 10px 12px;
  border-radius: 14px;
  background: rgba(12, 10, 18, .62);
  border: 1px solid rgba(201, 162, 39, .16);
  position: relative;
}
.ma-visuel {
  display: block; width: 100%; padding: 0; border: 0;
  background: transparent; cursor: pointer; border-radius: 10px;
  box-shadow: none;
}
.ma-visuel .cf { width: 100%; height: auto; display: block; }
.ma-nom {
  margin: 0; font-family: var(--font-title, inherit);
  font-size: 14px; color: var(--ink, #ece6f5);
  letter-spacing: .03em; line-height: 1.2;
}
.ma-meta { margin: 0; font-size: 11.5px; color: var(--ink-faint, #8d86a0); }
.ma-prix {
  margin: 0; font-size: 15px; font-weight: 800;
  color: #f5b942; font-variant-numeric: tabular-nums;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px;
}
.ma-prix--lg { font-size: 22px; }
.ma-prix-usd {
  font-size: 12px; font-weight: 600;
  color: var(--ink-faint, #8d86a0);
}
.ma-prix--lg .ma-prix-usd { font-size: 14px; }
.ma-prix-live { margin: 0; }
.ma-taux {
  margin: 0; font-size: 12px;
  color: var(--ink-faint, #8d86a0);
  font-variant-numeric: tabular-nums;
}
.ma-vendeur { margin: 0; font-size: 11px; color: var(--ink-faint, #8d86a0); font-family: ui-monospace, Consolas, monospace; }
.ma-badge {
  position: absolute; top: 14px; right: 14px;
  background: rgba(10, 8, 16, .82); color: #f5b942;
  border: 1px solid rgba(245, 185, 66, .4);
  border-radius: 999px; padding: 2px 8px; font-size: 11px; font-weight: 700;
}
/*  LA BASCULE SOL / DOLLAR du filtre de prix. Deux touches serrees, pas un
    menu : le choix est binaire et on le reprend souvent. */
.ma-unite {
  display: inline-flex; flex: none; padding: 2px; gap: 2px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .35);
  box-shadow: inset 0 0 0 1px rgba(255, 210, 140, .18);
}
.ma-unite button {
  border: 0; cursor: pointer; padding: 5px 11px; border-radius: 999px;
  font: inherit; font-size: 12px; font-weight: 750;
  color: rgba(253, 241, 214, .72); background: none;
  transition: background .15s ease, color .15s ease;
}
.ma-unite button:hover { color: #fff; }
.ma-unite button.est-on {
  color: #2a1c05;
  background: linear-gradient(180deg, #ffe6ac, #eeba55);
  box-shadow: 0 1px 6px rgba(0, 0, 0, .4);
}

.ma-actions {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 2px;
}
.ma-actions button { padding: 7px 12px; font-size: 12.5px; }
.ma-dispo, .ma-etat { font-size: 12px; color: var(--ink-dim, #a4b3cc); }
.ma-vide {
  max-width: 460px; margin: 48px auto; text-align: center;
  display: flex; flex-direction: column; gap: 14px; align-items: center;
}
.ma-vide p { margin: 0; color: var(--ink, #ece6f5); font-size: 16px; line-height: 1.5; }

.ma-voile {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(4, 6, 11, .72);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.ma-panneau {
  display: flex; gap: 28px; align-items: center;
  max-width: 720px; width: 100%;
  padding: 22px; border-radius: 18px;
  background: linear-gradient(180deg, #16121c, #0c0a10);
  border: 1px solid rgba(201, 162, 39, .35);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
}
.ma-panneau-carte { width: min(240px, 38vw); flex: none; }
.ma-panneau-carte .cf { width: 100%; display: block; }
.ma-panneau-txt { display: flex; flex-direction: column; gap: 10px; min-width: 0; flex: 1; }
.ma-panneau-txt h2 {
  margin: 0; font-family: var(--font-title, inherit);
  font-size: 22px; color: var(--ink-bright, #fff);
}
.ma-reperes {
  margin: 4px 0 14px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid rgba(201, 162, 70, .25); background: rgba(255, 255, 255, .03);
}
.ma-repere { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 10px; margin: 0 0 4px; font-size: 13px; color: var(--ink-dim); }
.ma-repere b { color: var(--ink); font-variant-numeric: tabular-nums; }
.ma-repere small { flex-basis: 100%; font-size: 11px; color: var(--ink-faint); }
.ma-reperes-note { display: block; margin-top: 6px; font-size: 11px; line-height: 1.35; color: var(--ink-faint); }
.ma-prix-lab {
  display: flex; flex-direction: column; gap: 6px;
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint, #8d86a0);
}
.ma-prix-lab input { font-size: 18px; padding: 10px 12px; }

@media (max-width: 1100px) {
  .ma-grille { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}

@media (max-width: 720px) {
  .ma-panneau { flex-direction: column; align-items: stretch; }
  .ma-panneau-carte { width: min(200px, 70vw); margin: 0 auto; }
  .marche-onglets, .stats-onglets { width: 100%; }
  .marche-onglets button, .stats-onglets button { flex: 1; min-height: 40px; }
}

@media (max-width: 900px), (orientation: portrait) and (max-width: 1100px) {
  .marche .ct-mots small { display: none; }
  body.marche-filtres-ouverts .marche .cartable-outils {
    display: flex;
    flex: 1 0 100%;
    max-height: 40vh; overflow-y: auto;
    padding-top: 4px;
  }
}

@media (max-width: 700px) {
  /*  La barre du bas : chips assez bas pour qu'elle tienne sur une ligne. */
  .wallet { margin-right: 0; }
  .wallet-btn {
    height: 32px; max-width: 84px; padding: 0 8px;
    font-size: 10px; overflow: hidden; text-overflow: ellipsis;
  }
  .wallet-btn:not(.is-connecte) {
    font-size: 0; width: 32px; max-width: 32px; padding: 0;
  }
  .wallet-btn:not(.is-connecte)::after { content: '◎'; font-size: 16px; }
  .wallet-menu {
    top: auto; bottom: calc(100% + 8px); right: 0;
    max-width: min(280px, calc(100vw - 16px));
    max-height: min(70vh, 420px); overflow-y: auto;
  }
  .profil-chip { height: 32px; padding: 2px; margin-right: 0; }
  .pc-avatar { width: 28px; height: 28px; box-shadow: 0 0 0 1.5px #c9a246; }
  .pc-avatar .dl-initiales { font-size: 11px; }

  body.marche-on #view-marche.is-on {
    height: calc(100dvh - var(--topbar-h));
  }
  .marche .cartable-tete {
    gap: 8px; padding: 8px 10px;
    flex-direction: column; align-items: stretch;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .marche .cartable-titre { min-width: 0; width: 100%; }
  .ma-mode-test { margin-left: auto; padding: 6px 10px; min-height: 36px; }
  .ma-mode-test span { font-size: 0; }
  .ma-mode-test span::after { content: 'Test'; font-size: 12px; }
  .marche .ct-replier { min-height: 36px; padding: 6px 12px; }
  .marche-onglets button { min-height: 40px; font-size: 13px; padding: 8px 6px; }
  .marche-bandeau { padding: 4px 10px 0; }
  .marche-bandeau .ma-note { display: none; }
  .marche-bandeau .ma-msg { display: block; font-size: 12px; margin-bottom: 6px; }
  .ma-taux { font-size: 11px; margin-bottom: 2px; }
  .marche-corps {
    padding: 10px 10px 18px;
    -webkit-overflow-scrolling: touch;
  }
  .ma-grille {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 8px;
  }
  .ma-tuile { padding: 8px 8px 10px; gap: 6px; }
  .ma-nom { font-size: 12.5px; }
  .ma-meta { font-size: 11px; }
  .ma-prix { font-size: 13px; flex-direction: column; align-items: flex-start; gap: 0; }
  .ma-prix-usd { font-size: 11px; }
  .ma-vendeur { font-size: 10px; }
  .ma-actions { flex-direction: column; align-items: stretch; }
  .ma-actions button {
    width: 100%; min-height: 40px; font-size: 13px; padding: 8px 10px;
  }

  .marche .ct-cherche,
  .ma-prix-filtre input,
  .marche .ct-tri select {
    font-size: 16px; min-height: 40px; width: 100%;
  }
  .ma-prix-filtre input { width: 100%; }

  .marche .ct-cherche { flex: 1 1 100%; }

  body.marche-filtres-ouverts .marche .cartable-outils {
    position: fixed; left: 0; right: 0;
    bottom: var(--topbar-h); z-index: 75;
    flex: none; width: auto; max-height: min(62vh, 480px);
    padding: 14px 12px 16px;
    background: linear-gradient(180deg, #16121c, #0c0a10);
    border: 1px solid rgba(201, 162, 39, .35); border-bottom: 0;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -18px 44px rgba(0, 0, 0, .7);
  }

  .ma-voile {
    align-items: flex-end;
    padding: 8px 8px calc(8px + var(--topbar-h));
    z-index: 85;
  }
  .ma-panneau {
    max-height: min(88dvh, calc(100dvh - var(--topbar-h) - 12px));
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    width: 100%; gap: 14px;
    padding: 14px 14px 16px;
    border-radius: 16px 16px 10px 10px;
  }
  .ma-panneau-carte { width: min(168px, 48vw); }
  .ma-panneau-txt h2 { font-size: 18px; }
  .ma-prix--lg { font-size: 18px; }
  .ma-prix-lab input { font-size: 16px; min-height: 44px; }
  .ma-vide { margin: 28px 12px; }
  .ma-vide p { font-size: 15px; }

  /* ── ACCUEIL : hero + grimoire, le reste est dans Règles / onglets ── */
  .home { min-height: 0; margin-bottom: 4px; }
  .hero-cta-group [data-go="marche"] { display: none; }
  .hero-cta-note { display: none; }
  .appel-ligne, .appel-kicker, .vitrine-raretes { display: none; }
  .home-booster-altar { padding: 8px 10px; gap: 8px; }
  .appel-titre { font-size: 16px; }

  /* ── CARTABLE : filtres en feuille, le classeur reste visible ── */
  #view-cartable .cartable-tete {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body.ct-filtres-ouverts #view-cartable .cartable-outils {
    position: fixed; left: 0; right: 0;
    bottom: var(--topbar-h); z-index: 75;
    display: flex; flex: none; width: auto;
    max-height: min(62vh, 480px); overflow-y: auto;
    padding: 14px 12px 16px;
    background: linear-gradient(180deg, #16121c, #0c0a10);
    border: 1px solid rgba(201, 162, 39, .35); border-bottom: 0;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -18px 44px rgba(0, 0, 0, .7);
  }
  #view-cartable .ct-cherche,
  #view-cartable .ct-tri select {
    font-size: 16px; min-height: 40px;
  }
  #view-cartable .ct-cherche { flex: 1 1 100%; width: 100%; }

  /* ── FORGE : autel compact, le registre défile dans l'écran ── */
  body:has(#view-forge.is-on) { overflow: hidden; }
  #view-forge.is-on {
    overflow: hidden;
    height: calc(100dvh - var(--topbar-h));
  }
  #view-forge .ct-mots small { display: none; }
  #view-forge .cartable-tete { padding: 8px 10px; }
  .forge-corps {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 8px 10px 18px;
    gap: 12px;
  }
  .fg-autel { height: min(38vh, 280px); flex: none; }
  .fg-creuset-case { width: 88px; }
  /*  LE REGISTRE DU BURN NE DEBORDE PLUS DE SON PANNEAU.
   *
   *  `.fg-burn` porte `min-height: 0` -- juste, sur un ecran large ou il est
   *  une colonne a cote de l'autel et doit pouvoir se tasser. Au telephone il
   *  passe SOUS l'autel, dans une colonne qui defile : le tassement n'a plus
   *  de sens, mais la regle reste, et le panneau se laisse ecraser bien en
   *  dessous de son contenu. Avec `overflow: visible` par-dessus, les figures
   *  sortent par le bas -- les barres et les nombres se retrouvaient poses a
   *  meme le mur de pierre, sans fond derriere eux.
   *
   *  Il prend donc la hauteur de ce qu'il contient, et ne se fait plus
   *  raboter : c'est la colonne qui defile, pas le panneau qui rapetisse. */
  .fg-burn { overflow: visible; flex: none; min-height: auto; }
}
/*  L'ATELIER EN FEUILLES : telephone, et tablette debout (27/09/2026). */
@media (max-width: 700px), (max-width: 1100px) and (orientation: portrait) {

  #view-atelier.en-feuilles .search-box input {
    font-size: 16px; min-height: 40px;
  }
  #view-atelier.en-feuilles .gallery { padding-bottom: 24px; }
}

/*  LA PAGE D'OUVERTURE DU CLASSEUR DES CREATURES : L'ANNEAU.
 *
 *  Six pochettes seulement, disposees en couronne : les six Energies, une par
 *  element, dans l'ordre de la Roue. Ce sont les six tuiles du plateau, et la
 *  page les montre comme le plateau les montre -- Feu en haut, puis on tourne
 *  dans le sens des aiguilles. Le classeur fait ensuite le tour de l'anneau
 *  dans le meme sens que la partie.
 *
 *  LA GRILLE NE CHANGE PAS DE FORME : ce sont toujours quatre colonnes sur
 *  trois rangees, et chaque pochette va se poser a sa place. Une couronne
 *  calculee en angles se serait decalee a chaque largeur d'ecran, et les
 *  calques (vernis, filigrane) reperent leurs fenetres en pourcentage de la
 *  pochette -- ils ont besoin d'une case de grille, pas d'une rotation. */
.cart-grille--anneau { position: relative; }
.cart-grille--anneau .cart-poche:nth-child(1) { grid-area: 1 / 2; }  /* Feu     */
.cart-grille--anneau .cart-poche:nth-child(2) { grid-area: 1 / 3; }  /* Air     */
.cart-grille--anneau .cart-poche:nth-child(3) { grid-area: 2 / 4; }  /* Eau     */
.cart-grille--anneau .cart-poche:nth-child(4) { grid-area: 3 / 3; }  /* Terre   */
.cart-grille--anneau .cart-poche:nth-child(5) { grid-area: 3 / 2; }  /* Lumiere */
.cart-grille--anneau .cart-poche:nth-child(6) { grid-area: 2 / 1; }  /* Ether   */

/*  LE CREUX DE L'ANNEAU.
    Au centre, la ou aucune pochette ne va, la feuille porte la trace du
    plateau : un hexagone en creux, tres retenu. Il ne doit jamais se lire
    comme une pochette vide -- donc pas de hachures, pas de bord net, rien
    qui appelle une carte. `pointer-events: none` : on penche les cartes
    par-dessus lui sans qu'il n'intercepte jamais le pointeur. */
.cart-grille--anneau::before {
  content: '';
  position: absolute;
  left: 25%; right: 25%; top: 50%;
  aspect-ratio: 1;
  transform: translateY(-50%);
  pointer-events: none;
  clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  background:
    radial-gradient(closest-side,
      rgba(255, 255, 255, .055), rgba(255, 255, 255, .012) 62%, transparent 78%);
}

/*  LES QUATRE CLASSEURS SUR L'ETAGERE.
 *
 *  Ce ne sont pas des filtres mais des objets qu'on prend en main : chacun
 *  porte son nom et ce qu'on y a rempli. Celui qui est ouvert se detache par
 *  le RELIEF -- il avance, les trois autres restent au fond. Un simple
 *  changement de couleur les aurait fait lire comme des cases a cocher, et
 *  c'est exactement ce dont on sortait.
 *
 *  `data-classeur` porte l'identite de chacun : c'est la que viendra se
 *  poser la couverture personnalisee, sans toucher a ce squelette. */
/*  QUATRE CLASSEURS FERMES, RELIES DE CUIR (sept. 2026).
 *  La couverture est cuite par card-render/fabriquer_couvertures.py : une
 *  illustration de la categorie pressee dans le cuir, cerclee d'or. Le titre
 *  reste en HTML pour rester net et francais, en dorure. Le reflet qui
 *  balaie au survol est un gradient : la lumiere glisse sur le cuir cire. */
.ct-classeurs {
  display: flex; gap: 14px; flex-wrap: wrap;
  perspective: 900px; padding: 4px 2px 8px;
}
.ct-classeur {
  position: relative; overflow: hidden;
  width: 96px; aspect-ratio: 3 / 4;
  display: flex; flex-direction: column; justify-content: space-between; align-items: center;
  padding: 9px 6px 7px 12px;
  border: 0; border-radius: 3px 8px 8px 3px;
  background: #1a1210 var(--couv) center / cover no-repeat;
  color: #f3d58a; cursor: pointer;
  box-shadow:
    inset 5px 0 6px -3px rgba(0, 0, 0, .8),      /* le mors du dos */
    inset 0 0 0 1px rgba(255, 220, 150, .08),
    3px 5px 0 -1px #d9cfb8,                      /* la tranche des feuilles */
    4px 7px 14px rgba(0, 0, 0, .7);
  filter: saturate(.9) brightness(.92);
  transform: rotateY(8deg) translateY(2px);
  transform-origin: left center;
  transition: transform .35s cubic-bezier(.16, 1, .3, 1), filter .3s ease, box-shadow .3s ease;
}
.ct-classeur[data-classeur="Creature"] { --couv: url("https://medias.kairostcg.com/classeurs/Creature.webp"); }
.ct-classeur[data-classeur="Lieu"]     { --couv: url("https://medias.kairostcg.com/classeurs/Lieu.webp"); }
.ct-classeur[data-classeur="Piege"]    { --couv: url("https://medias.kairostcg.com/classeurs/Piege.webp"); }
.ct-classeur[data-classeur="Effet"]    { --couv: url("https://medias.kairostcg.com/classeurs/Effet.webp"); }
.ct-classeur::after {
  content: ""; position: absolute; inset: -40% -60%;
  background: linear-gradient(105deg, transparent 40%, rgba(255, 236, 190, .28) 50%, transparent 60%);
  transform: translateX(-60%); transition: transform .9s ease;
  pointer-events: none;
}
.ct-classeur:hover { filter: saturate(1.05) brightness(1.08); transform: rotateY(0deg) translateY(-2px); }
.ct-classeur:hover::after { transform: translateX(60%); }
.ct-classeur.is-on {
  filter: none;
  transform: rotateY(0deg) translateY(-5px) scale(1.04);
  box-shadow:
    inset 5px 0 6px -3px rgba(0, 0, 0, .8),
    3px 5px 0 -1px #e6dcc4,
    0 0 0 1px rgba(245, 185, 66, .7),
    0 0 22px rgba(245, 185, 66, .35),
    4px 12px 22px rgba(0, 0, 0, .8);
}
.ct-cl-nom, .ct-cl-compte {
  position: relative; z-index: 1;
  padding: 1px 6px; border-radius: 3px;
  background: rgba(10, 6, 4, .55);
}
.ct-cl-nom {
  font-family: var(--font-title); font-weight: 800;
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  background-image: linear-gradient(180deg, #fff2c4, #e2b04a 55%, #9c6a1e);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .9));
}
.ct-cl-compte {
  font-size: 9.5px; color: #ecd9a8; opacity: .85;
  font-variant-numeric: tabular-nums;
}


/*  LES INTERCALAIRES D'ELEMENT.
 *
 *  Ce sont les languettes d'un classeur, pas six boutons. Elles doivent donc
 *  SORTIR DU PAPIER : collees au bord droit des pages, sans intervalle entre
 *  elles, formant une seule colonne continue. La premiere version les posait
 *  au-dela de la fleche, espacees, arrondies -- elles flottaient a cote du
 *  classeur sans rien toucher, et ne ressemblaient plus a rien.
 *
 *  ELLES SONT TOUTES DE LA MEME COULEUR AU REPOS, l'or du classeur. Donner a
 *  chacune la teinte de son element paraissait evident et s'est revele
 *  mauvais : l'Eau et la Terre sont sombres, elles disparaissaient sur le
 *  fond, pendant que le Feu criait. Six poids differents pour six choses de
 *  meme rang. La couleur de l'element ne sert donc qu'a dire OU L'ON EST --
 *  une seule a la fois, et elle se remarque justement parce qu'elle est
 *  seule. */
/*  ACCROCHES AU CUIR. La colonne est une enfant de la reliure (cartable.js),
    posee en absolu contre son bord exterieur : `100%` est le bord interieur
    du cuir, `--ct-bord` le traverse. Plus aucun calcul de rangee ne peut
    laisser de jour entre les deux. */
.ct-elements-marge {
  position: absolute;
  top: 50%;
  left: calc(100% + var(--ct-bord));
  transform: translateY(-50%);
  z-index: 1;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 0;
}
.ct-onglet {
  /*  A L'ECHELLE DU CLASSEUR, pas a celle d'une icone de barre d'outils.
   *  Premiere version : 27 px de large contre des cartes de 210. Une
   *  languette d'intercalaire doit s'attraper sans viser, donc elle se mesure
   *  au papier qu'elle borde, jamais a la place qu'elle economise. */
  --sortie: 0px;
  width: calc(var(--ct-ong) - 8px + var(--sortie));
  height: clamp(46px, 7.2vh, 70px);
  display: grid; grid-template: 1fr / 1fr; place-items: center;
  padding: 0 0 0 calc(var(--sortie) * .6);
  /*  Pas de bord a GAUCHE : c'est le cote qui entre sous le cuir. Un trait
      la aurait ferme la languette et l'aurait detachee du classeur. */
  border: 1px solid rgba(222, 184, 96, .22);
  border-left: 0;
  border-radius: 0 9px 9px 0;
  /*  Du meme cuir que le classeur, un ton plus sombre, et une ombre a la
      racine : la languette sort de DESSOUS la couverture. */
  background:
    linear-gradient(90deg, rgba(0, 0, 0, .55), transparent 9px),
    linear-gradient(rgba(0, 0, 0, .28), rgba(0, 0, 0, .42)),
    var(--ct-cuir-img, none) 0 0 / 256px 256px,
    var(--ct-cuir-fond, #2a2018);
  box-shadow: 2px 3px 6px rgba(0, 0, 0, .5);
  cursor: pointer;
  /*  ELLE S'ALLONGE, ELLE NE GLISSE PAS. Un `translateX` la decollait du
      cuir : la languette « ici » flottait a neuf pixels du classeur. */
  transition: width .2s cubic-bezier(.2, .8, .2, 1), height .2s cubic-bezier(.2, .8, .2, 1),
    padding .2s cubic-bezier(.2, .8, .2, 1),
    background-color .16s ease, border-color .16s ease;
}
.ct-onglet + .ct-onglet { border-top: 0; }
.ct-onglet:first-child { border-radius: 0 12px 9px 0; }
.ct-onglet:last-child { border-radius: 0 9px 12px 0; }

.ct-onglet > i {
  display: block;
  width: 56%; aspect-ratio: 1;
  /*  L'or du classeur au repos -- le meme que les fleches. L'icone sert de
      pochoir : une seule image, la couleur vient d'ici. */
  background: rgba(201, 162, 39, .55);
  -webkit-mask-image: var(--ico); mask-image: var(--ico);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  transition: background .16s ease;
}
.ct-onglet:hover { --sortie: 4px; }
.ct-onglet:hover > i { background: rgba(222, 184, 96, .95); }

/*  « ON EST ICI » : la languette sort franchement du classeur et prend enfin
    la couleur de son element. C'est le seul endroit du cartable ou une
    couleur dit une position et non une rarete. */
.ct-onglet.is-ici {
  --sortie: 12px;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, .5), transparent 9px),
    linear-gradient(color-mix(in srgb, var(--el, #c9a227) 34%, transparent),
                    color-mix(in srgb, var(--el, #c9a227) 18%, rgba(0, 0, 0, .4))),
    var(--ct-cuir-img, none) 0 0 / 256px 256px,
    var(--ct-cuir-fond, #2a2018);
  border-color: color-mix(in srgb, var(--el, #c9a227) 70%, transparent);
  box-shadow: 2px 3px 8px rgba(0, 0, 0, .55),
    0 0 14px -2px color-mix(in srgb, var(--el, #c9a227) 55%, transparent);
}
.ct-onglet.is-ici > i {
  background: var(--el, #c9a227);
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--el, #c9a227) 70%, transparent));
}

/*  Une seule page a l'ecran : la place manque a droite, les languettes
    pendent SOUS le cuir, a l'horizontale -- toujours accrochees a son bord.
    Meme requete que l'ecran etroit du classeur (ETROIT dans cartable.js). */
@media (orientation: portrait) and (max-width: 1100px), (max-width: 900px) and (min-height: 501px) {
  .ct-elements-marge {
    top: calc(100% + var(--ct-bord)); left: 50%;
    transform: translateX(-50%);
    flex-direction: row; align-items: flex-start; justify-content: center;
    /*  Aussi large que le cuir, pas plus : les six languettes se partagent
        sa largeur. Mesurees sur l'ecran, elles debordaient d'un classeur
        en 3 x 4, plus etroit que la scene. */
    width: calc(100% + 2 * var(--ct-bord) - 16px);
  }
  .ct-onglet,
  .ct-onglet + .ct-onglet,
  .ct-onglet:first-child,
  .ct-onglet:last-child {
    width: auto; flex: 0 1 64px; min-width: 0;
    height: calc(var(--ct-ong-h, 50px) - 10px + var(--sortie));
    padding: calc(var(--sortie) * .6) 0 0;
    border: 1px solid rgba(222, 184, 96, .22); border-top: 0;
    border-radius: 0 0 9px 9px;
    background:
      linear-gradient(180deg, rgba(0, 0, 0, .55), transparent 9px),
      linear-gradient(rgba(0, 0, 0, .28), rgba(0, 0, 0, .42)),
      var(--ct-cuir-img, none) 0 0 / 256px 256px,
      var(--ct-cuir-fond, #2a2018);
  }
  .ct-onglet + .ct-onglet { border-left: 0; }
  .ct-onglet.is-ici {
    background:
      linear-gradient(180deg, rgba(0, 0, 0, .5), transparent 9px),
      linear-gradient(color-mix(in srgb, var(--el, #c9a227) 34%, transparent),
                      color-mix(in srgb, var(--el, #c9a227) 18%, rgba(0, 0, 0, .4))),
      var(--ct-cuir-img, none) 0 0 / 256px 256px,
      var(--ct-cuir-fond, #2a2018);
  }
}


/*  L'ETAGERE : les quatre cartables fermes, avant d'en ouvrir un. */
.ct-etagere { display: none; }
#view-cartable.en-etagere > .cartable { display: none; }
/*  La vue a la hauteur de l'ecran et la page ne defile pas
 *  (`body.collection-mode`) : sur un PC court, la deuxieme rangee de tuiles
 *  passait sous le bas, hors d'atteinte. L'etagere defile donc elle-meme, et
 *  la rangee se retrecit d'abord a la hauteur pour que les quatre tiennent. */
#view-cartable.en-etagere > .ct-etagere {
  display: flex; flex-direction: column; align-items: center;
  padding: clamp(16px, 3.5vh, 40px) clamp(16px, 3vw, 48px) clamp(16px, 3vh, 32px); text-align: center;
  height: 100%; box-sizing: border-box; overflow-x: hidden; overflow-y: auto;
}
.ct-etagere-titre {
  margin: 0; font-family: var(--font-title); font-weight: 900;
  font-size: clamp(26px, 3.4vw, 40px); letter-spacing: .14em; text-transform: uppercase;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ct-etagere-sous { margin: 6px 0 clamp(14px, 3vh, 32px); color: var(--ink-dim); font-size: 14px; }
/*  LA GRILLE PREND TOUTE LA FENETRE. Elle tenait dans 760 px au milieu d'un
 *  grand vide : sur un PC, la moitie de l'ecran ne servait a rien. Les deux
 *  rangees se partagent maintenant la hauteur qui reste, et la largeur va
 *  jusqu'a 1480 px ; sous 240 px de rangee, c'est l'etagere qui defile. */
.ct-etagere-rang {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(240px, 1fr));
  width: min(1480px, 100%); flex: 1 0 auto;
  gap: clamp(14px, 2.4vh, 28px) clamp(14px, 2vw, 28px);
}

/*  ECRAN BAS (22/10/2026, tele 4K a 300 % : 1280 x 595 CSS). Une rangee ne
 *  descendait pas sous 240 px : la deuxieme passait sous le bord. Sur un PC
 *  bas, les deux rangees se partagent ce qui reste, jusqu'a 140 px. */
@media (min-width: 701px) and (max-height: 760px) {
  #view-cartable.en-etagere > .ct-etagere { padding-top: 10px; padding-bottom: 12px; }
  .ct-etagere-titre { font-size: 28px; }
  .ct-etagere-sous { margin: 2px 0 10px; font-size: 13px; }
  .ct-etagere-rang { grid-template-rows: repeat(2, minmax(140px, 1fr)); flex: 1 1 auto; gap: 12px 16px; }
}

/*  LA TUILE D'UN CLASSEUR : un degrade, et une poussiere qui virevolte.
 *
 *  Deux tentatives ont ete refusees avant celle-ci. La couverture WebP en
 *  fond, dont l'emblème -- haut de cinq cents pixels, taille pour un livre
 *  debout -- passait en geant derriere le texte. Puis un medaillon d'or
 *  frappe, qui faisait joli mais laissait la tuile vide autour de lui.
 *
 *  Ici la couleur porte le classeur et le mouvement le rend vivant ; depuis
 *  le 20/10, une carte choisie a la main se pose au centre, en arriere-plan
 *  (`.ct-tu-carte`) -- une carte, pas un emblème. Le canvas est SOUS le texte et
 *  ne recoit aucun clic ; c'est le bouton entier qui reste cliquable.
 */
.ct-tuile {
  position: relative; overflow: hidden; text-align: center;
  display: block;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .10); border-radius: 18px;
  color: #f6e6c2; cursor: pointer; font: inherit;
  background:
    radial-gradient(85% 70% at 22% 0%, var(--haut), transparent 62%),
    radial-gradient(70% 60% at 100% 100%, var(--reflet), transparent 60%),
    linear-gradient(152deg, var(--c1) 0%, var(--c2) 58%, #07060c 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .14),
    0 14px 30px rgba(0, 0, 0, .55);
  transition: transform .24s cubic-bezier(.16, 1, .3, 1), box-shadow .24s ease, border-color .24s ease;
}
.ct-tuile[data-classeur="Creature"] {
  --c1: #7d211b; --c2: #35090d; --haut: rgba(255, 170, 120, .30); --reflet: rgba(255, 90, 70, .18);
}
.ct-tuile[data-classeur="Lieu"] {
  --c1: #1d6242; --c2: #06251b; --haut: rgba(150, 255, 200, .26); --reflet: rgba(60, 220, 150, .16);
}
.ct-tuile[data-classeur="Piege"] {
  --c1: #1f3572; --c2: #070e28; --haut: rgba(150, 190, 255, .26); --reflet: rgba(70, 120, 255, .18);
}
.ct-tuile[data-classeur="Effet"] {
  --c1: #5f2274; --c2: #1c0929; --haut: rgba(230, 170, 255, .26); --reflet: rgba(180, 90, 255, .18);
}
.ct-tu-poudre {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none;
}

/*  `button:hover:not(:disabled)` (0,2,1) repeignait le fond en bleu nuit :
 *  au survol, chaque tuile perdait sa couleur. On repose le degrade ici, a
 *  une specificite qui passe devant. */
.ct-tuile.ct-tuile:hover:not(:disabled) {
  background:
    radial-gradient(85% 70% at 22% 0%, var(--haut), transparent 62%),
    radial-gradient(70% 60% at 100% 100%, var(--reflet), transparent 60%),
    linear-gradient(152deg, var(--c1) 0%, var(--c2) 58%, #07060c 100%);
}
.ct-tuile:hover {
  transform: translateY(-5px);
  border-color: rgba(255, 255, 255, .26);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 22px 44px rgba(0, 0, 0, .62);
}

/*  LE PLAN DE LA TUILE. Il est en absolu sur toute la surface parce qu'un
 *  bouton dimensionne sa boite interne sur son contenu : en grille comme en
 *  bloc, `width: 100%` s'y mesurait a 164 px pour une tuile de 312. */
.ct-tu-plan {
  position: absolute; inset: 0;
  display: grid; grid-template-rows: 1fr auto; align-items: center;
}
/*  Le titre n'a PAS de marge propre : il occupe la rangee libre de la grille
 *  et s'y centre. L'air au-dessus de lui est donc exactement celui qui le
 *  separe du socle -- c'est la grille qui tient l'equilibre, pas une valeur
 *  reglee a la main qui se decale des que la tuile change de hauteur. */
/*  LA CARTE EN ARRIERE-PLAN, AU CENTRE. Grande, sous le titre et le socle :
 *  le texte passe devant elle. La tuile est un conteneur de taille (`cqh`,
 *  `cqi`), la carte se regle donc sur sa hauteur et reste dedans, penchee
 *  a peine : elle se redresse et grossit sur place, et garde toujours une
 *  marge -- elle est ENTIERE, jamais rognee par le bord ni fondue. Le socle
 *  passe devant son pied. Aucun clic : c'est la tuile qui ouvre. */
.ct-tuile { container-type: size; }
.ct-tu-plan { z-index: 2; }
.ct-tu-tete {
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  padding: 0 14px; min-height: 0;
}
.ct-tu-tete .ct-tu-nom {
  text-align: center;
  font-size: clamp(16px, min(6.4cqi, 14cqh), 54px);
  /* Le titre est pose sur l'image : une ombre dense le detache. */
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .9)) drop-shadow(0 0 14px rgba(0, 0, 0, .85));
}
.ct-tu-carte {
  position: absolute; z-index: 1; left: 50%; top: 50%;
  /*  Hauteur seule : la largeur suit l'image. Les vignettes sont en
   *  320x503, pas en 63/88 -- imposer ce format avec `object-fit: cover`
   *  rognait le haut et le bas de la carte. */
  height: 80cqh; width: auto;
  border-radius: 10px; pointer-events: none;
  transform: translate(-50%, -54%) rotate(4deg);
  opacity: .92;
  filter: brightness(.62) drop-shadow(0 0 12px color-mix(in srgb, var(--rc, transparent) 40%, transparent));
  transition: transform .5s cubic-bezier(.16, 1, .3, 1), opacity .3s ease, filter .3s ease;
}
.ct-tuile:hover .ct-tu-carte { transform: translate(-50%, -54%) rotate(0deg) scale(1.05); opacity: 1;
  filter: brightness(.85) drop-shadow(0 0 16px color-mix(in srgb, var(--rc, transparent) 55%, transparent)); }

/*  LE TITRE PORTE LA TUILE. Il etait discret, pose au milieu d'un degrade :
 *  on lisait la couleur avant le mot. Il passe donc en grand, avec une ombre
 *  portee qui le decolle du fond quel que soit le grain qui passe dessous. */
.ct-tu-nom {
  font-family: var(--font-title); font-weight: 900;
  letter-spacing: .1em; text-transform: uppercase;
  /*  L'INTERLIGNE NE DOIT PAS SERRER : un degrade applique au texte se
   *  decoupe sur la boite de la ligne, et a 1.05 l'accent de « PIEGES »
   *  passait a la trappe. */
  font-size: clamp(20px, 2.6vw, 34px); line-height: 1.24; padding: 2px 0;
  background: linear-gradient(180deg, #fff6dc 0%, #ffd98a 45%, #d9a441 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .65)) drop-shadow(0 0 18px rgba(255, 196, 96, .28));
}

/*  LE SOCLE D'INFORMATION. */
/*  LE RYTHME DU SOCLE.
 *
 *  Les trois lignes etaient a intervalle egal et le tout pousse contre le
 *  bord : les gemmes touchaient le bas de la tuile. Elles respirent
 *  desormais -- le nombre et sa jauge vont ensemble, donc serres ; les
 *  gemmes sont une autre information, donc detachees ; et le bas garde plus
 *  de marge que le haut, sinon le bloc parait tomber. */
.ct-tu-pied {
  display: grid; gap: 0;
  padding: clamp(8px, 1.6cqi, 14px) clamp(14px, 3cqi, 28px) clamp(13px, 2.4cqi, 22px);
  background: linear-gradient(180deg, rgba(0, 0, 0, .12), rgba(0, 0, 0, .58));
  border-top: 1px solid rgba(255, 255, 255, .10);
  backdrop-filter: blur(2px);
}
.ct-tu-haut { display: flex; align-items: center; gap: clamp(12px, 2vw, 18px); }
.ct-tu-grand { display: flex; align-items: baseline; gap: 5px; line-height: 1; min-width: 0; }
.ct-tu-grand b {
  font-family: var(--font-title); font-weight: 900;
  font-size: clamp(30px, 7cqi, 64px); line-height: .88;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(180deg, #fff6dc, #ffcf74 58%, #e2a83c);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .55));
}
.ct-tu-sur {
  font-size: clamp(13px, 2.2cqi, 20px); font-weight: 800;
  color: rgba(253, 241, 214, .55); font-variant-numeric: tabular-nums;
}
/*  Le pourcentage reste lisible, mais il ne dispute plus la vedette au
 *  nombre : une pastille discrete, calee a droite. */
.ct-tu-pct {
  flex: none;
  padding: 3px 9px; border-radius: 999px;
  font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums;
  color: rgba(255, 224, 160, .95);
  background: rgba(0, 0, 0, .35);
  box-shadow: inset 0 0 0 1px rgba(255, 210, 140, .22);
}
.ct-tu-pct.est-pleine {
  color: #2a1c05;
  background: linear-gradient(180deg, #ffe9b4, #f0c063);
  box-shadow: 0 0 12px rgba(255, 200, 110, .6);
}

.ct-tu-jauge {
  /*  La jauge partage sa ligne avec le nombre : elle prend ce qui reste. */
  flex: 1 1 auto; min-width: 0;
  display: block; height: 8px; border-radius: 999px; overflow: hidden;
  background: rgba(0, 0, 0, .55);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .8), inset 0 0 0 1px rgba(255, 255, 255, .06);
}
.ct-tu-jauge i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #b9762a, #ffd478 60%, #fff2c8);
  box-shadow: 0 0 12px rgba(255, 200, 110, .75);
  transition: width .6s cubic-bezier(.16, 1, .3, 1);
}
.ct-tu-jauge.est-pleine i { background: linear-gradient(90deg, #ffd478, #fff6dc); }

/*  LES TROPHEES : allumee, la gemme se voit de loin ; eteinte, c'est une
 *  case a remplir. */
.ct-tu-bas {
  display: flex; align-items: center; gap: 12px;
  margin-top: clamp(12px, 1.8vh, 18px);
}
.ct-tu-rars { display: flex; flex: 1 1 auto; justify-content: space-between; gap: 4px; }
.ct-tu-rar { display: inline-flex; align-items: center; gap: 5px; }
.ct-tu-gemme {
  width: clamp(10px, 1.6cqi, 13px); height: clamp(10px, 1.6cqi, 13px); border-radius: 2px; transform: rotate(45deg);
  background: var(--rc);
  box-shadow: 0 0 8px var(--rc), inset 0 0 0 1px rgba(255, 255, 255, .45);
}
.ct-tu-nb {
  font-size: clamp(12px, 1.9cqi, 15px); font-weight: 800; font-variant-numeric: tabular-nums;
  color: rgba(253, 241, 214, .92);
}
.ct-tu-rar.est-vide .ct-tu-gemme {
  background: transparent; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28);
}
.ct-tu-rar.est-vide .ct-tu-nb { color: rgba(253, 241, 214, .3); }

.ct-vers-etagere { margin-right: 6px; white-space: nowrap; }
@media (max-width: 700px) {
  /*  UNE SEULE COLONNE. A deux, la tuile tombait sous 170 px : le titre
   *  debordait et la pastille du pourcentage sortait du cadre. Une colonne
   *  rend au titre la place de s'ecrire en entier. */
  /*  LES QUATRE TUILES TIENNENT TOUJOURS DANS LA FENETRE.
   *
   *  Une proportion fixe ne pouvait pas y suffire : reglee pour un ecran de
   *  812 px, la quatrieme tuile repassait sous la barre sur un ecran de 830.
   *  Les tuiles se PARTAGENT donc la hauteur restante -- quatre rangees d'une
   *  fraction chacune -- et la page ne defile plus, quel que soit l'appareil. */
  /*  MAIS JAMAIS SOUS LEUR CONTENU. Dans Brave au telephone, les deux
   *  barres du navigateur laissent ~530 px : la fraction tombait a 95 px et
   *  la ligne des gemmes etait coupee au bas de la tuile. Une tuile garde
   *  donc de quoi tout ecrire (116 px) ; si la fenetre est plus courte
   *  encore, c'est l'etagere qui defile, plutot que de rogner. */
  #view-cartable.en-etagere > .ct-etagere { height: 100%; overflow-x: hidden; overflow-y: auto; }
  .ct-etagere-rang {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: repeat(4, minmax(116px, 1fr));
    flex: 1 0 auto; gap: 10px;
  }
  .ct-tuile { aspect-ratio: auto; height: 100%; min-height: 0; }
  .ct-tu-tete { padding: 2px 14px 0; }
  .ct-tu-nom { font-size: clamp(18px, 6vw, 26px); }
  .ct-tu-pied { gap: 6px; padding: 8px 13px 9px; }
  .ct-tu-grand b { font-size: clamp(24px, 7vw, 32px); }
  #view-cartable.en-etagere > .ct-etagere { padding: 10px 12px 14px; }
  .ct-etagere-titre { font-size: 24px; }
  .ct-etagere-sous { margin: 5px 0 10px; font-size: 13px; }
  .ct-tu-rars { font-size: 11px; }
  .ct-tu-bas { margin-top: 2px; }
}

/* ══ CARTABLE : UNE SEULE BANDE, LA RARETE EN AVANT ══════════════════════
   Plus d'elements (les intercalaires s'en chargent), plus de classeurs (on
   les choisit a l'etagere), plus de tri ni de reinitialiser. Il reste la
   rarete et « seulement mes cartes », en grand, et une recherche discrete.
   La bande est toujours visible : plus de bouton « Filtres ». */
#view-cartable .ct-bande,
body.ct-filtres-ouverts #view-cartable .ct-bande {
  position: static; display: flex; flex: 1 1 auto; flex-wrap: wrap;
  align-items: center; gap: 10px 16px;
  max-height: none; overflow: visible; padding: 0; background: none; border: 0;
}
#view-cartable .ct-bande .f-rars { display: flex; flex-wrap: wrap; gap: 6px; }
#view-cartable .ct-bande .f-rar {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  height: 38px; width: auto; padding: 0 16px 0 13px; border-radius: 999px;
  font-size: 13px; font-weight: 650; color: var(--ink) !important;
  background: linear-gradient(180deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .03)) !important;
  border: 1px solid rgba(255, 255, 255, .12) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 2px 6px rgba(0, 0, 0, .25) !important;
  transition: transform .14s ease, border-color .14s ease, background .14s ease, box-shadow .14s ease;
}
#view-cartable .ct-bande .f-rar:hover {
  transform: translateY(-1px); color: #fff !important; border-color: color-mix(in srgb, var(--rc) 70%, transparent) !important;
}
#view-cartable .ct-bande .f-rar .f-swatch {
  width: 12px; height: 12px; border-radius: 3px; transform: rotate(45deg);
  background: var(--rc); box-shadow: 0 0 8px var(--rc), inset 0 0 0 1px rgba(255, 255, 255, .35);
}
#view-cartable .ct-bande .f-rar.is-on {
  color: #fff !important; border-color: var(--rc) !important;
  background: linear-gradient(180deg, color-mix(in srgb, var(--rc) 34%, #1c2433), color-mix(in srgb, var(--rc) 14%, #1c2433)) !important;
  box-shadow: 0 0 0 1px var(--rc), 0 0 16px color-mix(in srgb, var(--rc) 45%, transparent) !important;
}

/* « Seulement mes cartes » : un interrupteur, pas une case perdue */
#view-cartable .ct-bande .ct-poss {
  display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  height: 38px; padding: 0 16px 0 8px; border-radius: 999px;
  font-size: 13px; font-weight: 650; color: var(--ink);
  background: linear-gradient(180deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .03));
  border: 1px solid rgba(255, 255, 255, .12);
  user-select: none;
}
#view-cartable .ct-bande .ct-poss input {
  appearance: none; -webkit-appearance: none; margin: 0; cursor: pointer;
  position: relative; width: 38px; height: 22px; border-radius: 999px; flex: none;
  background: rgba(255, 255, 255, .12); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
  transition: background .18s ease;
}
#view-cartable .ct-bande .ct-poss input::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
  background: #cfc7b3; transition: transform .18s ease, background .18s ease;
}
#view-cartable .ct-bande .ct-poss input:checked { background: var(--gold-grad, #e8c25a); }
#view-cartable .ct-bande .ct-poss input:checked::after { transform: translateX(16px); background: #1a1202; }
#view-cartable .ct-bande .ct-poss:has(input:checked) {
  color: #fff; border-color: rgba(232, 194, 90, .7); box-shadow: 0 0 14px rgba(245, 185, 66, .25);
}

/* La recherche passe au bout, plus discrete */
#view-cartable .ct-recherche { position: relative; margin-left: auto; width: 220px; flex: 0 1 220px; }
#view-cartable .ct-recherche input {
  width: 100%; height: 38px; padding: 0 14px 0 34px; font-size: 13px; border-radius: 999px;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .1); color: var(--ink-bright);
}
#view-cartable .ct-recherche input:focus { outline: none; border-color: #e8c25a; box-shadow: 0 0 0 3px rgba(232, 194, 90, .18); }
#view-cartable .ct-recherche .search-icon {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%); font-size: 12px; pointer-events: none;
}

@media (max-width: 700px) {
  /*  LA BANDE PASSE A LA LIGNE, ELLE NE DEFILE PLUS.
   *
   *  Elle defilait de cote pour ne pas manger la hauteur. L'intention etait
   *  bonne, l'effet non : rien n'annonce qu'une bande defile, donc on voyait
   *  Commune, Peu commune, Rare -- et on ignorait qu'Epique, Legendaire,
   *  Mythique et « seulement mes cartes » existaient. Un filtre invisible est
   *  un filtre absent.
   *
   *  Deux lignes coutent une quarantaine de pixels, et il y en a : la page du
   *  classeur tient dessous. Les pastilles se resserrent pour que les six
   *  raretes tiennent en deux lignes, jamais trois. */
  #view-cartable .ct-bande,
  body.ct-filtres-ouverts #view-cartable .ct-bande {
    flex: 1 0 100%; flex-wrap: wrap; overflow: visible; gap: 6px; padding-bottom: 2px;
  }
  #view-cartable .ct-bande .f-rars { flex-wrap: wrap; gap: 6px; flex: 1 1 100%; }
  #view-cartable .ct-bande .f-rar {
    height: 34px; flex: 1 1 auto; min-width: 0; justify-content: center;
    padding: 0 10px; font-size: 12px; white-space: nowrap;
  }
  /*  L'interrupteur prend sa propre ligne : c'est une question a part -- pas
   *  « quelle rarete » mais « les miennes ou toutes ». */
  #view-cartable .ct-bande .ct-poss {
    height: 34px; flex: 1 1 100%; justify-content: center;
    font-size: 12px; white-space: nowrap;
  }
  #view-cartable .ct-recherche { display: none; }
}

/* ── LE DECK REFUSE SE DIT ────────────────────────────────────────────────
   Quarante cartes et « Jouer » grise, sans un mot : c'etait le cas d'un deck
   a neuf creatures. Le bandeau dit ce qui manque et quoi faire. */
.deck-alerte {
  margin: 8px 28px 4px; padding: 10px 14px; border-radius: 10px;
  background: rgba(120, 30, 20, .92); color: #ffe9e2;
  border: 1px solid rgba(255, 140, 110, .55);
  font-size: 14px; font-weight: 600; line-height: 1.35;
}
.deck-alerte[hidden] { display: none; }
.ba-btn.est-bloque { opacity: .55; filter: grayscale(.6); }
@media (max-width: 700px) { .deck-alerte { margin: 0 8px 8px; font-size: 13px; } }

/* ══ LE DUEL DES DÉS ══════════════════════════════════════════════════════
   Deux médaillons encadrent la fenêtre du lancer d'ouverture : le mien à
   gauche (côté de mon portrait), celui d'en face à droite. Le chiffre ne
   paraît qu'une fois le dé couché ; le gagnant s'allume, le perdant s'éteint.
   Voir `duelDes()` dans main.js. */
.duel-des { position: absolute; inset: 0; z-index: 48; pointer-events: none; opacity: 0; transition: opacity .3s ease; }
.duel-des.est-ouvert { opacity: 1; }
.dd-jeton {
  position: absolute; transform: translateY(-50%);
  /* « COMMENCE » est le mot le plus long que la pastille ait a porter : la
     largeur et les marges laterales sont taillees pour lui, sinon le verdict
     debordait du jeton du gagnant. */
  /* LA PASTILLE SE TAILLE SUR SON CONTENU. Fixee a 84 px, « COMMENCE »
     debordait ; fixee plus large avec une coupe, il se lisait « Comm... ».
     Le mot commande donc la largeur, entre un plancher qui garde la forme
     ronde et un plafond qui empeche un nom long de s'etaler. */
  width: max-content; min-width: 96px; max-width: 150px;
  padding: 10px 10px 9px; border-radius: 16px; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: radial-gradient(120% 90% at 50% 20%, rgba(52, 40, 70, .96), rgba(12, 10, 18, .97));
  border: 1px solid rgba(201, 162, 70, .45);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .6);
  transition: transform .35s cubic-bezier(.2, 1.4, .4, 1), opacity .35s ease, filter .35s ease,
              box-shadow .35s ease, border-color .35s ease;
}
.dd-moi { --dd-c: #6fd8ff; }
.dd-eux { --dd-c: #ff8f7a; }
.dd-nom {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 700 11px/1.1 var(--font-body), sans-serif; color: var(--dd-c);
}
.dd-valeur {
  font: 900 40px/1 var(--font-title), Georgia, serif; color: #fff6df;
  text-shadow: 0 0 14px color-mix(in srgb, var(--dd-c) 70%, transparent);
  min-height: 40px;
}
.dd-de { font: 700 9px/1 var(--font-body), sans-serif; letter-spacing: .14em; text-transform: uppercase; color: #8e8799; }
.dd-verdict {
  max-width: 100%; white-space: nowrap;
  min-height: 12px; font: 800 9px/1.2 var(--font-body), sans-serif;
  letter-spacing: .04em; text-transform: uppercase; text-align: center; color: #ffd978;
}
.dd-jeton.attend .dd-valeur { opacity: .45; animation: dd-attend 1.1s ease-in-out infinite; }
@keyframes dd-attend { 50% { opacity: .9; } }
.dd-jeton.roule .dd-valeur { filter: blur(1px); }
.dd-jeton.revele .dd-valeur { animation: dd-pop .45s cubic-bezier(.2, 1.8, .4, 1); }
@keyframes dd-pop { 0% { transform: scale(.4); } 100% { transform: scale(1); } }
.dd-jeton.gagne {
  transform: translateY(-50%) scale(1.12);
  border-color: #ffd978;
  box-shadow: 0 0 0 2px rgba(255, 217, 120, .6), 0 0 34px rgba(245, 185, 66, .75), 0 12px 30px rgba(0, 0, 0, .6);
}
.dd-jeton.gagne .dd-valeur { color: #ffe7a6; text-shadow: 0 0 20px rgba(245, 185, 66, .95); }
.dd-jeton.perd { opacity: .55; filter: grayscale(.7); transform: translateY(-50%) scale(.92); }
.dd-jeton.egalite { animation: dd-secoue .5s ease; }
@keyframes dd-secoue { 20%, 60% { translate: -5px 0; } 40%, 80% { translate: 5px 0; } }
@media (max-width: 700px) {
  .dd-jeton { min-width: 88px; padding: 8px 8px 7px; }
  .dd-valeur { font-size: 34px; min-height: 34px; }
}
/* EN BANDEAU, au-dessus et au-dessous de la fenetre : nom, chiffre, verdict
   sur une ligne. Le haut s'accroche par le bas, le bas par le haut. */
.duel-des.empile .dd-jeton {
  /*  Le plafond de 150 px vaut pour la pastille ronde. En bandeau, nom,
      chiffre, de et « COMMENCE » tiennent sur UNE ligne : plafonnee, la
      pastille laissait le verdict deborder hors du plateau au telephone. */
  max-width: calc(100% - 16px);
  width: auto; min-width: 150px; flex-direction: row; gap: 10px;
  padding: 6px 14px; border-radius: 999px;
}
.duel-des.empile .dd-eux { transform: translate(-50%, -100%); }
.duel-des.empile .dd-moi { transform: translate(-50%, 0); }
.duel-des.empile .dd-eux.gagne { transform: translate(-50%, -100%) scale(1.08); }
.duel-des.empile .dd-moi.gagne { transform: translate(-50%, 0) scale(1.08); }
.duel-des.empile .dd-eux.perd { transform: translate(-50%, -100%) scale(.94); }
.duel-des.empile .dd-moi.perd { transform: translate(-50%, 0) scale(.94); }
.duel-des.empile .dd-valeur { font-size: 30px; min-height: 0; }
.duel-des.empile .dd-nom { font-size: 13px; max-width: 90px; }
.duel-des.empile .dd-verdict:empty { display: none; }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .dd-jeton, :where(html:not(.mouvement-plein)) .dd-jeton .dd-valeur { animation: none !important; transition: none; }
}

/* ══ LA BARRE DE VIE, SOUS LA CARTE DE LA LOUPE ════════════════════════════
   Un tube de verre, un liquide lumineux à la couleur de l'élément (voir
   VIE_COULEURS, carte_vivante.js), un reflet qui court à sa surface. La
   tranche qu'un coup va emporter se peint en rouge -- d'où le Feu en orange. */
.vie-barre {
  position: relative; height: 22px; margin-top: 10px; border-radius: 999px; overflow: hidden;
  background: linear-gradient(180deg, #16131d, #0b0a10);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .8), inset 0 -1px 1px rgba(255, 255, 255, .08),
              0 0 0 1px rgba(255, 255, 255, .06);
}
.vie-liquide {
  position: absolute; left: 0; top: 2px; bottom: 2px; border-radius: 999px; overflow: hidden;
  /* Un liquide qui éclaire de l'intérieur : cœur plus clair, bords profonds,
     un reflet doux en haut. Pas de motif : la lumière et les bulles suffisent. */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .45) 0%, rgba(255, 255, 255, .08) 38%, rgba(255, 255, 255, 0) 60%),
    radial-gradient(120% 140% at 50% 55%, var(--vie-clair) 0%, var(--vie-fonce) 85%);
  box-shadow: 0 0 10px color-mix(in srgb, var(--vie-fonce) 70%, transparent),
              inset 0 0 8px color-mix(in srgb, var(--vie-clair) 60%, transparent);
  transition: width .6s cubic-bezier(.3, .9, .3, 1);
  animation: vie-lueur 3.2s ease-in-out infinite;
}
/* Deux couches de petites bulles, à deux vitesses : elles dérivent vers la
   droite en remontant à peine, comme dans un tube qu'on tient à plat. */
.vie-liquide::before, .vie-liquide::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-repeat: repeat;
}
.vie-liquide::before {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, .75) 0 1.2px, transparent 1.8px),
    radial-gradient(circle, rgba(255, 255, 255, .5) 0 0.9px, transparent 1.4px);
  background-size: 46px 18px, 31px 14px;
  background-position: 6px 11px, 19px 4px;
  animation: vie-bulles-a 9s linear infinite;
  opacity: .8;
}
.vie-liquide::after {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, .65) 0 1.6px, rgba(255, 255, 255, .15) 2.2px, transparent 2.8px);
  background-size: 73px 20px;
  background-position: 30px 8px;
  animation: vie-bulles-b 14s linear infinite;
  opacity: .7;
}
@keyframes vie-lueur {
  50% { box-shadow: 0 0 16px color-mix(in srgb, var(--vie-fonce) 90%, transparent),
                    inset 0 0 12px color-mix(in srgb, var(--vie-clair) 80%, transparent); }
}
@keyframes vie-bulles-a { to { background-position: 52px -7px, 50px -10px; } }
@keyframes vie-bulles-b { to { background-position: 103px -12px; } }
.vie-liquide.vie-perte {
  --vie-clair: #ff8a7a; --vie-fonce: #d0141b;
  border-radius: 0 999px 999px 0;
  /* Le rouge entre en fondu depuis la gauche : il se glisse sous la fin du
     liquide de l'élément, qui s'efface par-dessus lui (voir .fondu). */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px);
          mask-image: linear-gradient(90deg, transparent 0, #000 16px);
  animation: vie-lueur 3.2s ease-in-out infinite, vie-perte 1.1s ease-in-out infinite alternate;
}
.vie-liquide.fondu {
  z-index: 1; border-radius: 999px 0 0 999px;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 16px), transparent);
          mask-image: linear-gradient(90deg, #000 calc(100% - 16px), transparent);
}
@keyframes vie-perte { to { filter: brightness(.72); } }
.vie-texte {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center;
  font: 800 12px/1 var(--font-body), sans-serif; letter-spacing: .03em;
  color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .9), 0 0 6px rgba(0, 0, 0, .6);
}
/*  UN CHIFFRE QUI N'EST PAS ENCORE ACQUIS SE LIT AUTREMENT.
 *
 *  L'apercu d'une capacite a seuil montre la REUSSITE du de. Le chiffre est
 *  donc vrai « au mieux », et rien ne doit lui donner l'aplomb d'un fait : la
 *  mention se serre, se teinte d'ambre, et la ligne perd un peu d'opacite. */
.vie-texte.est-pari { color: #ffd98a; font-weight: 700; }

@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .vie-liquide, :where(html:not(.mouvement-plein)) .vie-liquide::before, :where(html:not(.mouvement-plein)) .vie-liquide::after, :where(html:not(.mouvement-plein)) .vie-perte { animation: none; } }

/*  LES BONUS ET LES MALUS DANS LA LOUPE.
 *
 *  Le titre d'un groupe porte son compte : « ATTAQUE   10 -> ⚔ 20 ». C'est la
 *  qu'on lit le resultat, une fois ; les rangees en dessous ne portent que ce
 *  qui s'ajoute. Le chiffre de chaque rangee est cale a droite, sur la meme
 *  colonne que tous les autres -- c'est l'alignement qui fait la lecture d'un
 *  compte, pas la couleur. */
.loupe-mods { display: flex; flex-direction: column; gap: 3px; }
.loupe-mods-tete {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin: 10px 0 3px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint, #8d86a0);
}
.loupe-mods-tete:first-child { margin-top: 0; }
/* Le resume d'un groupe (« +10 % DEF ») ne sert que replie, au telephone. */
.loupe-mods .loupe-mods-resume { display: none; }
.loupe-mods-calcul {
  display: inline-flex; align-items: baseline; gap: 6px;
  letter-spacing: 0; text-transform: none;
  font-family: var(--font-num, monospace); font-variant-numeric: tabular-nums;
}
.calc-socle { font-size: 12px; font-weight: 700; color: var(--ink-dim, #b8b2c6); }
.calc-fleche { font-size: 11px; color: var(--ink-faint, #8d86a0); }
.calc-total { font-size: 15px; font-weight: 800; color: #8dffc0; }
.calc-total.calc-def { color: #7cc4ff; }
.loupe-mod {
  display: flex; align-items: baseline; gap: 10px;
  padding: 5px 9px; border-radius: 7px;
  background: rgba(255, 255, 255, .035);
  border-left: 2px solid rgba(255, 255, 255, .14);
}
.loupe-mod-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.loupe-mod-txt b { font-size: 12px; font-weight: 700; color: var(--ink, #ece6f5); }
.loupe-mod-txt small { font-size: 10px; line-height: 1.3; color: var(--ink-faint, #8d86a0); }
.loupe-mods-note { font-size: 10px; line-height: 1.35; color: var(--ink-faint, #8d86a0); font-style: italic; padding: 2px 9px 4px; }
.loupe-mod-val {
  flex: none; font-family: var(--font-num, monospace);
  font-size: 12.5px; font-weight: 800; font-variant-numeric: tabular-nums;
  color: var(--ink-dim, #b8b2c6);
}
.loupe-mod.atk { border-left-color: #6ee7a8; }
.loupe-mod.atk .loupe-mod-val { color: #6ee7a8; }
.loupe-mod.def { border-left-color: #7cc4ff; }
.loupe-mod.def .loupe-mod-val { color: #7cc4ff; }
.loupe-mod.est-malus { border-left-color: #ff7a7a; }
.loupe-mod.est-malus .loupe-mod-val { color: #ff9a9a; }
.loupe-mod.est-bloc .loupe-mod-val { font-size: 11px; color: #cfc6ff; }
.loupe-mod.etat { border-left-color: #e8c25a; background: rgba(232, 194, 90, .07); }

/*  LE COMPTE DU COUP, dans l'apercu au survol et sous la carte visee.
 *  La meme grammaire que les bonus de la loupe -- le compte a droite du
 *  titre, une ligne par retenue -- en plus serre : ici on survole, on ne
 *  s'installe pas. */
.mc-live-calc, .lc-compte {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 8px; padding: 7px 9px; border-radius: 8px;
  background: rgba(124, 196, 255, .07);
  border: 1px solid rgba(124, 196, 255, .22);
}
.mc-live-calc-tete {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint, #8d86a0);
}
.mc-live-calc-l {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 11px; color: var(--ink-dim, #b8b2c6);
}
.mc-live-calc-l b {
  font-family: var(--font-num, monospace); font-variant-numeric: tabular-nums;
  font-weight: 800; color: #ff9a9a;
}
/*  Sous la carte visee, le compte respire un peu plus : on est arrete devant
    un bouton « Attaquer », pas en train de passer. */
.lc-compte { width: 100%; gap: 3px; padding: 9px 10px; }
.lc-compte .loupe-mods-tete { margin: 0 0 2px; }
.lc-compte-nu { font-size: 11px; color: var(--ink-faint, #8d86a0); }

/* ══ CENT QUARANTE CARTES SUR UN TELEPHONE ═════════════════════════════════
 *
 * Le devoilement d'un lot de dix a ete dessine pour une souris sur un ecran
 * de bureau. Au doigt, trois choses le mettent a genoux, et elles n'ont rien
 * a voir avec la taille de l'ecran -- c'est le MOTEUR qui plie :
 *
 *   1. L'apparition anime un `filter: blur()` de neuf pixels. Un flou ne se
 *      compose pas : il se REDESSINE a chaque image, sur toute la surface de
 *      la carte. Cent quarante cartes floues qui se redressent en meme temps,
 *      c'est la vague qui hache au lieu de couler.
 *
 *   2. L'aura d'attente tourne EN BOUCLE, pour toujours, sur chaque carte non
 *      retournee. `will-change: opacity` demande au navigateur une couche
 *      GPU par carte : cent quarante couches de la taille d'une carte, plus
 *      leur ombre de trente-quatre pixels. La memoire graphique d'un
 *      telephone n'a pas ca a donner, et ce qu'elle ne peut pas garder, elle
 *      le refait -- en permanence.
 *
 *   3. Le survol reste COLLE apres un appui. Une carte touchee garde son
 *      `scale(1.55)` et ses deux `drop-shadow`, et le doigt qui glisse la
 *      traine avec lui. C'est le tressautement qu'a vu le fils d'Alexandre.
 *
 * Rien de tout cela ne change a la souris. */
@media (hover: none), (pointer: coarse) {
  /* LE SURVOL NE COLLE PLUS. Sans souris il n'y a pas de survol a montrer :
     l'agrandissement et les ombres portees ne doivent jamais s'installer.
     Pour lire une carte, il y a l'appui -- il ouvre la fiche. */
  .reveal-card-slot:not(.is-flipped):hover,
  .reveal-card-slot.is-flipped:hover {
    transform: none;
    filter: none;
    z-index: auto;
  }
  /* Sauf l'effacement des Communes dans un lot : il sert a trouver les
     rares d'un coup d'oeil, et un appui ne doit pas le lever au hasard. */
  .reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-commune:hover,
  .reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-peu-commune:hover {
    filter: brightness(.55) saturate(.7);
  }
  .reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-rare:hover,
  .reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-epique:hover,
  .reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-legendaire:hover,
  .reveal-cards-row.is-lot .reveal-card-slot.is-flipped.glow-mythique:hover {
    transform: scale(1.08);
  }

  /*  L'APPARITION SANS FLOU -- ET PLUS SEULEMENT EN LOT.
   *
   *  On avait cru qu'un paquet seul passait : quatorze cartes, ca ne fait
   *  que quatorze flous. Mais un flou de neuf pixels ne coute pas par carte,
   *  il coute par SURFACE redessinee, et quatorze cartes couvrent tout
   *  l'ecran d'un telephone. Le dernier telephone d'Alexandre hachait sur
   *  un paquet seul exactement comme sur dix.
   *
   *  Le geste reste entier : la carte nait couchee et se redresse. Elle nait
   *  seulement nette -- le redressement se compose sur le GPU, le flou non. */
  .reveal-card-slot.parait {
    animation-name: carteSePoseSobre;
  }

  /*  LE SCEAU NE SE FLOUTE PLUS, IL EST DEJA FLOU.
   *
   *  Son disque etait un degrade radial PLUS un `filter: blur(6px)`, et il
   *  grandissait de .25 a 1.5 : a chaque image, le navigateur refait le flou
   *  a la nouvelle taille. Un degrade dont les arrets sont assez doux donne
   *  le meme rond de lumiere, peint UNE fois et seulement transforme. */
  .carte-sceau i {
    filter: none;
    background: radial-gradient(ellipse at 50% 50%,
      rgba(255, 240, 200, .9) 0%, rgba(250, 210, 130, .62) 26%,
      rgba(245, 185, 66, .34) 52%, transparent 78%);
  }
  /*  L'anneau portait deux ombres floues et passait de .2 a 2.35 : meme
   *  histoire. Il garde son trait, il perd son halo. */
  .carte-sceau b { box-shadow: none; }

  /* L'AURA D'ATTENTE S'ARRETE DE RESPIRER EN LOT. Elle reste -- la carte non
     retournee doit se distinguer de celle qui l'est -- mais elle ne demande
     plus sa couche GPU ni ses soixante images par seconde. */
  .reveal-cards-row.is-lot .reveal-card-slot:not(.is-flipped)::after {
    animation: none;
    opacity: .8;
    will-change: auto;
    box-shadow: 0 0 20px rgba(245, 185, 66, .5);
  }

  /* Les deux pulsations des plus hautes raretes animent une OMBRE PORTEE,
     donc un flou recalcule a chaque image. A une carte pres c'est un
     bonheur ; a plusieurs dans une grille de cent quarante, c'est le
     defilement qui se met a coller. La lueur reste, fixe. */
  .reveal-cards-row.is-lot .reveal-card-slot.glow-legendaire.is-flipped,
  .reveal-cards-row.is-lot .reveal-card-slot.glow-mythique.is-flipped {
    animation: none;
  }
}

/*  LA BULLE DU REGISTRE SUIT LE POINTEUR -- ET IL N'Y EN A PAS.
 *
 *  Chaque ligne des figures du burn ouvre sa bulle sur `pointermove` et la
 *  referme sur `pointerleave`. Au doigt, le premier appui l'ouvre et RIEN ne
 *  la referme : elle reste collee par-dessus les barres, a l'endroit ou le
 *  doigt est passe. Ce qu'elle dit tient de toute facon dans la ligne. */
@media (hover: none), (pointer: coarse) {
  .fg-bulle { display: none !important; }
}

@keyframes carteSePoseSobre {
  0%   { opacity: 0; transform: translateY(-26px) scale(1.08) rotate(-2deg); }
  24%  { opacity: 1; }
  60%  { transform: translateY(2px) scale(.985) rotate(0deg); }
  78%  { transform: translateY(-1px) scale(1.006); }
  100% { opacity: 1; transform: none; }
}

/*  ══ LA FETE DU GRIMOIRE, AU DOIGT ═════════════════════════════════════
 *
 *  L'arrivee du grimoire est raide sur telephone, et elle l'est pour une
 *  raison qu'on ne voit pas dans le dessin : presque tout ce qui bouge dans
 *  cette scene anime un FLOU, et un flou ne se compose pas -- il se
 *  redessine, sur le processeur, a chaque image.
 *
 *    - le voile anime son `backdrop-filter` de 0 a 10 px : le navigateur
 *      refloute TOUT L'ECRAN soixante fois par seconde, pendant que le reste
 *      de la scene demarre ;
 *    - le livre descend en `blur(8px)` qui s'efface, puis flotte sans fin
 *      avec deux `drop-shadow` recalcules a chaque image ;
 *    - le halo est un disque de 460 px floute a 22 px, et il RESPIRE : il
 *      change d'echelle en boucle, donc son flou est refait en boucle ;
 *    - les rayons de la version Legend font 1600 px de cote et tournent pour
 *      toujours, degrade conique sous masque.
 *
 *  Sur une machine de bureau, rien de tout cela ne se sent. Au doigt, les
 *  quatre se paient en meme temps et la descente saute par a-coups.
 *
 *  On ne retire aucun geste : le livre descend toujours, se charge, flotte ;
 *  le halo monte et respire ; les rayons tournent. Ils le font seulement
 *  par `transform` et `opacity`, les deux seules choses qu'un telephone
 *  compose sans repeindre. */
@media (hover: none), (pointer: coarse) {
  /*  LE VOILE EST FLOU DES LE DEBUT, IL NE LE DEVIENT PAS. Le flou d'arriere-
   *  plan est pose une fois, et c'est l'opacite qui fait l'entree. */
  .af-voile {
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation-name: af-fondu-plat;
  }
  @keyframes af-fondu-plat { from { opacity: 0; } to { opacity: 1; } }

  /*  LE LIVRE GARDE SON OMBRE, FIXE. Une seule ombre portee, jamais animee :
   *  la couche est peinte une fois et ne fait plus que se deplacer. */
  .af-grimoire {
    filter: drop-shadow(0 18px 24px rgba(0, 0, 0, .8));
    animation:
      af-descente-plate 1.7s var(--doux) .1s both,
      af-charge-plate .7s ease-in-out calc(var(--eclat) - .7s),
      af-flotte-plate 4.5s ease-in-out calc(var(--eclat) + .2s) infinite;
  }
  @keyframes af-descente-plate {
    0%   { opacity: 0; transform: translateY(-46vh) scale(.72) rotate(-6deg); }
    45%  { opacity: 1; }
    100% { opacity: 1; transform: translateY(0) scale(1) rotate(0); }
  }
  @keyframes af-charge-plate {
    0%   { transform: scale(1); }
    70%  { transform: scale(.94); }
    100% { transform: scale(1.08); }
  }
  @keyframes af-flotte-plate {
    0%, 100% { transform: translateY(0) scale(1.04); }
    50%      { transform: translateY(-12px) scale(1.04); }
  }
  /*  L'eclat du livre au moment ou il se charge n'est plus un `brightness`
   *  sur l'image : c'est le halo derriere lui qui monte. On ne perd pas la
   *  montee de lumiere, on la met la ou elle ne coute rien. */

  /*  LE HALO NE CHANGE PLUS D'ECHELLE EN BOUCLE. Il monte une fois -- la
   *  tension a besoin de ce grandissement -- puis il ne fait plus que
   *  respirer en opacite, comme l'aura des cartes. */
  .af-halo {
    filter: blur(14px);
    animation: af-halo-monte var(--eclat) ease-in .3s both,
               af-halo-souffle 3.4s ease-in-out calc(var(--eclat) + .3s) infinite;
  }
  @keyframes af-halo-souffle { 0%, 100% { opacity: .85; } 50% { opacity: .5; } }

  /*  LES RAYONS A LA TAILLE DE L'ECRAN. Mille six cents pixels de degrade
   *  conique sous masque, c'est une couche de deux millions et demi de
   *  pixels qu'un telephone garde en memoire graphique pour la tourner. */
  .af-rayons {
    width: 120vmax; height: 120vmax; left: -60vmax; top: -60vmax;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
 *  LA BIBLIOTHEQUE DES DECKS
 *
 *  Une etagere, pas une liste : chaque deck y est sa boite, celle qu'on lui a
 *  choisie, avec son nom dessous. On clique la boite pour charger le deck.
 * ══════════════════════════════════════════════════════════════════════════ */
.bib-voile {
  position: fixed; inset: 0; z-index: 400;
  display: grid; place-items: center; padding: 20px;
  background: rgba(6, 5, 10, .78);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.bib-voile[hidden] { display: none; }
.bib {
  display: flex; flex-direction: column;
  width: min(940px, 100%); max-height: min(86vh, 760px);
  background: linear-gradient(180deg, #171320, #100d16);
  border: 1px solid var(--line-gold, rgba(201, 162, 70, .45));
  border-radius: 18px; box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
  overflow: hidden;
}
.bib-tete {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 18px; border-bottom: 1px solid rgba(201, 162, 70, .25);
}
.bib-tete h2 {
  margin: 0; font-family: var(--font-title); font-size: 22px; color: #ffe3a0;
  display: flex; align-items: center; gap: 10px;
}
.bib-tete h2 b {
  font: 700 12px/1 var(--font-num, sans-serif);
  padding: 4px 9px; border-radius: 999px;
  background: rgba(245, 185, 66, .18); color: #ffe3a0;
}
.bib-fermer {
  width: 36px; height: 36px; border-radius: 50%; font-size: 16px;
  background: rgba(255, 255, 255, .05); color: var(--ink-dim, #b9b2a4);
  border: 1px solid rgba(201, 162, 70, .3); cursor: pointer;
}
.bib-fermer:hover { color: #ffe3a0; border-color: #e8c25a; }
.bib-corps { padding: 16px 18px 20px; overflow-y: auto; }
.bib-corps .dk-nouveau { width: 100%; margin-bottom: 14px; }
.bib-grille {
  display: grid; gap: 16px 14px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.bib-deck {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 8px 12px; border-radius: 14px; cursor: pointer;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .07);
  transition: transform .16s, border-color .16s, background .16s;
}
.bib-deck:hover { transform: translateY(-3px); border-color: #c9a246; background: rgba(245, 185, 66, .07); }
.bib-deck:focus-visible { outline: 2px solid #e8c25a; outline-offset: 3px; }
.bib-deck.is-on { border-color: #e8c25a; box-shadow: inset 0 0 0 1px rgba(232, 194, 90, .5); }
.bib-boite { position: relative; width: 100%; aspect-ratio: 1 / 1; display: grid; place-items: center; }
/*  La scene de la boite, a l'echelle de la vignette. `.cof3d-plan` est un
    carre de 1000 px que l'atelier reduit a sa taille : ici 150, donc .15. */
.bib-scene { position: relative; width: 150px; height: 150px; }
.bib-scene > img, .bib-scene .cof3d-pile {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; user-select: none;
}
.bib-scene .cof3d-pile { overflow: visible; }
.bib-scene .cof3d-plan { transform: scale(.15); }
.bib-actif, .bib-incomplet {
  position: absolute; top: 0; left: 0;
  font: 800 9.5px/1 var(--font-num, sans-serif); letter-spacing: .08em;
  text-transform: uppercase; padding: 4px 8px; border-radius: 999px;
}
.bib-actif { background: var(--gold-grad, #f5b942); color: #1a1202; }
/* « Incomplet » se pose EN BAS A DROITE : en haut, il passait sous la croix
   de suppression, et les deux se lisaient l'un sur l'autre. */
.bib-incomplet {
  background: rgba(214, 96, 96, .9); color: #fff;
  top: auto; bottom: 0; left: auto; right: 0;
}
/* Les elements du deck, en icones : la meme famille que partout ailleurs. */
.bib-els { position: absolute; bottom: 0; left: 0; display: flex; gap: 4px; }
.bib-els i {
  display: block; width: 16px; height: 16px; background: var(--el, #8a9cb5);
  -webkit-mask: var(--ico) center / contain no-repeat; mask: var(--ico) center / contain no-repeat;
}
.bib-x {
  position: absolute; top: -2px; right: -2px;
  width: 26px; height: 26px; border-radius: 50%; font-size: 15px; line-height: 1;
  background: rgba(10, 8, 14, .85); color: var(--ink-dim, #b9b2a4);
  border: 1px solid rgba(255, 255, 255, .15); cursor: pointer;
  opacity: 0; transition: opacity .16s;
}
.bib-deck:hover .bib-x, .bib-x:focus-visible { opacity: 1; }
.bib-x:hover { color: #ff9b9b; border-color: #d66060; }
.bib-nom {
  max-width: 100%; font-family: var(--font-title); font-size: 15px; color: #fff3d6;
  text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bib-meta { font-size: 11px; color: var(--ink-faint, #8b8577); }

/*  L'etoile de vedette, dans la liste du deck. Eteinte, elle se voit sans
    s'imposer ; allumee, elle est en or, et la ligne porte un liseré. */
.dl-vedette {
  width: 34px; height: 34px; border-radius: 50%;
  font-size: 15px; line-height: 1; cursor: pointer;
  color: rgba(226, 214, 190, .35);
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
  transition: color .16s, border-color .16s, background .16s;
}
.dl-vedette:hover { color: #ffe3a0; border-color: rgba(245, 185, 66, .5); }
.dl-vedette.is-on {
  color: #1a1202; background: var(--gold-grad, #f5b942); border-color: transparent;
}
.dl-ligne.est-vedette { box-shadow: inset 0 0 0 1px rgba(245, 185, 66, .45); }

/*  TROIS NOMBRES SOUS LA CARTE TENUE DE PRES. Discrets : l'illustration
    reste le sujet. L'or pour les libelles et le lien, l'encre pour le reste. */
.zoom-stats {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 14px;
  margin: 10px auto 0; max-width: 360px; width: 100%;
  font-size: 13px; line-height: 1.4; color: var(--ink, #e8e0f0); text-align: left;
}
.zoom-stats dt {
  color: #c9a227; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  align-self: baseline;
}
.zoom-stats dd { margin: 0; }
/*  Sous la carte, les paires restent des lignes ; a cote, ce sont des
    tuiles (voir `.zoom-fiche .zoom-stat`). */
.zoom-stat { display: contents; }
.zoom-stats dd b { font-weight: inherit; }
.zoom-stats dd small { font-size: inherit; }
.zoom-stats-lien { color: #c9a227; text-decoration: underline; text-underline-offset: 2px; }
.zoom-stats-plus {
  justify-self: start; margin-top: 2px; padding: 0; border: 0; background: none;
  color: #c9a227; font: inherit; font-size: 12px; cursor: pointer;
}
.zoom-stats-plus:hover { text-decoration: underline; text-underline-offset: 2px; }

/*  LE DECK OFFERT : un sceau a la place de la croix de suppression, et le
    bouton « Creer une variante » dans les outils, a la place de ceux qu'il
    grise. */
.bib-offert {
  position: absolute; top: 6px; right: 6px;
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px;
  color: #1a1206; background: linear-gradient(180deg, #f3d57a, #c9a227);
}
.dk-outil:disabled { opacity: .45; cursor: not-allowed; }
.dk-variante[hidden] { display: none; }

/*  UNE CARTE EN VENTE : toujours a soi, pas jouable. Le bleu de la forge
    et du marche, pas l'or de la rarete -- ce n'est pas un merite. */
.cart-en-vente {
  position: absolute; left: 6px; bottom: 6px; z-index: 3;
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px;
  color: #06141c; background: #5fb3d9;
}
/* LA MENTION DU PRET, SUR LA CARTE EN GRAND ET SOUS ELLE. */
.zoom-pretee {
  position: absolute; top: 12px; left: 50%; z-index: 4;
  transform: translateX(-50%) translateZ(1px);
  padding: 4px 14px; border-radius: 999px; pointer-events: none;
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: #1a1206; background: linear-gradient(180deg, #f3d98a, #c9a246);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .55);
}
/*  LA CARTE DE DEPART : meme place que « Prêtée » et « FREE », en bleu-gris
 *  plutot qu or -- elle est a soi, mais ne se brule pas. */
.zoom-pretee.est-depart { color: #e8eef8; background: linear-gradient(180deg, #5b6f92, #34435f); }
.cart-pastille-free.est-depart { color: #e8eef8; background: rgba(52, 67, 95, .95); border-color: rgba(170, 190, 225, .6); letter-spacing: .1em; }
.zoom-pret {
  display: grid; gap: 4px; margin: 10px auto 0; max-width: 440px; width: 100%;
  padding: 10px 12px; border-radius: 10px; text-align: left;
  background: rgba(201, 162, 70, .12); border: 1px solid rgba(201, 162, 70, .45);
  font-size: 13px; line-height: 1.4; color: var(--ink, #e8e0f0);
}
.dg-slot.is-flipped { cursor: zoom-in; }
.zoom-en-vente {
  display: grid; gap: 4px; margin: 10px auto 0; max-width: 440px; width: 100%;
  padding: 10px 12px; border-radius: 10px; text-align: left;
  background: rgba(95, 179, 217, .12); border: 1px solid rgba(95, 179, 217, .45);
  font-size: 13px; line-height: 1.4; color: var(--ink, #e8e0f0);
}
.zoom-en-vente b { color: #7cc6e8; }
.zoom-stats-vente { color: #7cc6e8; }
.match-result-hors { color: #f0b36b; margin-top: 8px; font-size: 13px; }

/*  LE SUIVI DE LA FORGE : les cartes s'embrasent une a une, la carte forgee
    s'allume. Par-dessus tout, comme une fenetre d'action. */
.fs-voile {
  position: fixed; inset: 0; z-index: 400; display: grid; place-items: center;
  background: rgba(6, 4, 8, .78); padding: 16px;
}
.fs-boite {
  width: min(640px, 100%); max-height: 92vh; overflow: auto;
  background: #120d0a; border: 1px solid rgba(201, 162, 39, .45); border-radius: 16px;
  padding: 20px; text-align: center; color: var(--ink, #e8e0f0);
  box-shadow: 0 0 60px rgba(226, 112, 58, .18);
}
.fs-titre { margin: 0 0 6px; font-size: 20px; color: #e8c56a; }
.fs-sous { margin: 0 0 12px; font-size: 13px; color: var(--ink-dim, #b8b0c8); }
.fs-barre { height: 6px; border-radius: 999px; background: rgba(255, 255, 255, .08); overflow: hidden; margin-bottom: 14px; }
.fs-barre i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #e2703a, #f3d57a); transition: width .5s ease; }
.fs-rang { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.fs-carte {
  position: relative; width: 64px; aspect-ratio: 320 / 503; border-radius: 6px; overflow: hidden;
  border: 2px solid var(--rc, #888); background: #1c1512;
  transition: filter .8s ease, opacity .8s ease, transform .8s ease;
}
.fs-carte img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fs-nom-seul { font-size: 9px; padding: 4px; display: block; }
.fs-etat {
  position: absolute; left: 0; right: 0; bottom: 0; font-size: 9px; padding: 2px 0;
  background: rgba(0, 0, 0, .7); color: #d8cfe4;
}
.fs-brule { filter: grayscale(1) brightness(.45); opacity: .55; transform: scale(.94); animation: fs-feu .9s ease; }
.fs-brule .fs-etat { color: #f0a868; }
@keyframes fs-feu {
  0% { box-shadow: 0 0 0 rgba(226, 112, 58, 0); filter: none; }
  40% { box-shadow: 0 0 22px rgba(226, 112, 58, .95); filter: brightness(1.4) saturate(1.4); }
  100% { box-shadow: 0 0 0 rgba(226, 112, 58, 0); }
}
.fs-fleche { margin: 10px 0 6px; color: #c9a227; font-size: 18px; }
.fs-nait { width: 104px; margin: 0 auto; filter: grayscale(1) brightness(.5); }
.fs-nait.fs-allume { filter: none; box-shadow: 0 0 34px rgba(243, 213, 122, .8); animation: fs-nait 1.2s ease; }
.fs-nait.fs-allume .fs-etat { color: #f3d57a; }
@keyframes fs-nait { 0% { transform: scale(.9); } 50% { transform: scale(1.08); } 100% { transform: scale(1); } }
.fs-pied { margin-top: 14px; }
.fs-pied:empty { display: none; }

/*  LA FENETRE GLOBALE : meme habit que le suivi de la forge, par-dessus tout.
    Plus haute que les voiles d'ecran (card-zoom 3500, dg-fond 3000). */
.fg-globale { z-index: 5000; }
.fg-kicker { display: block; font-size: 10px; letter-spacing: .18em; color: #c9a227; margin-bottom: 6px; }
.fg-texte { line-height: 1.5; }
.fg-attente {
  width: 28px; height: 28px; margin: 6px auto 0; border-radius: 50%;
  border: 3px solid rgba(201, 162, 39, .25); border-top-color: #e8c56a;
  animation: fg-tourne .9s linear infinite;
}
@keyframes fg-tourne { to { transform: rotate(360deg); } }
.fs-voile:not(.fg-globale) { z-index: 5000; }

/* ══ L'ATELIER SUR TABLETTE (701 a 1100 px) ═══════════════════════════════
 * Pense pour le bureau, le menu du haut mettait les filtres et les actions
 * cote a cote : a 768 px, les quatre panneaux de filtres n'avaient plus que
 * 340 px et empilaient leurs boutons un par ligne -- 600 px de haut avant la
 * premiere carte, et une galerie a deux colonnes sous un etui geant
 * (signale le 25/09/2026 : « pas top en tablette »). Ici les filtres prennent
 * toute la largeur, les actions passent en une ligne dessous, la colonne du
 * kit se resserre et la galerie reprend trois colonnes. */
@media (min-width: 501px) and (max-width: 1100px) {
  #view-atelier .deck-rail {
    grid-template-columns: minmax(0, 1fr); row-gap: 10px; padding: 10px 14px;
  }
  #view-atelier .deck-rail .filtres-haut { grid-column: 1; grid-row: 1; gap: 8px; }
  #view-atelier .deck-rail .filtres-haut .filter-group,
  #view-atelier .deck-rail .filtres-haut .filter-group + .filter-group { padding: 7px 10px 9px !important; }
  #view-atelier .dk-actions {
    grid-column: 1; grid-row: 2;
    display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 12px;
  }
  #view-atelier .dk-outils {
    flex-direction: row; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0;
  }
  #view-atelier .dk-outils-titre { margin: 0 4px 0 0; }
  #view-atelier .dk-jouer { display: flex; align-items: center; gap: 10px; }
  #view-atelier .dk-jouer .play-btn { min-width: 0; padding: 10px 20px !important; font-size: 17px !important; }
  #view-atelier .atelier-body { grid-template-columns: 210px minmax(0, 1fr); }
  #view-atelier .kit { padding: 10px; }
  #view-atelier .gallery { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px 12px; }
  #view-atelier .gal-barre { padding: 12px 16px 4px; }
}

/* ══ UNE PARTIE SUR UN TELEPHONE COUCHE ═══════════════════════════════════
 * 844 x 390 : la barre du haut prenait 67 px, le pupitre de droite en
 * faisait 436 pour 332 disponibles, et « Fin du tour » tombait a 472 --
 * hors de l'ecran, la partie ne pouvait plus avancer. Comme en portrait, la
 * barre du haut se retire pendant le duel (« Abandonner » reste la sortie),
 * et le pupitre devient une colonne a hauteur d'ecran dont seul le corps
 * defile : « Fin du tour » est toujours au pied, toujours atteignable. */
@media (orientation: landscape) and (max-height: 520px) {
  body.play-on .topbar { display: none; }
  body.play-on { --topbar-h: 0px; }
  body.play-on .game-module {
    top: 8px; bottom: 8px; right: 8px; width: 196px;
    padding: 8px 10px;
    display: flex; flex-direction: column; overflow: hidden;
  }
  body.play-on .game-module .duel-portrait { display: none; }
  body.play-on .game-module .module-label { margin-bottom: 4px; }
  body.play-on .game-module .module-rule { margin: 5px 4px; }
  body.play-on .game-module .prompt {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overscroll-behavior: contain;
    justify-content: flex-start;
  }
  body.play-on .module-end-turn { flex: 0 0 auto; margin-top: 6px; }
  body.play-on .main-col { top: 8px; bottom: 8px; }
}

/* ══ LE GRIMOIRE SE VOIT DES LA PREMIERE FENETRE (701 px et plus) ═════════
 * L'accueil doit vendre : or la tuile du grimoire commencait a 700-900 px du
 * haut -- sous le pli sur un portable 1366 x 768 (55 px visibles, son seul
 * cadre), sur un iPad a peine. Rien ne disait qu'il y avait quelque chose a
 * acheter plus bas (signale le 26/09/2026).
 *   . la tuile passe a l'horizontale, comme au telephone : le livre a
 *     gauche, l'accroche a droite, puis la vitrine et le bouton en pleine
 *     largeur. Le livre ET son titre arrivent ensemble dans l'ecran ;
 *   . l'accueil remonte (42 px de marge en tete) et le bandeau se tasse
 *     selon la HAUTEUR de l'ecran ;
 *   . en colonne unique, l'eventail perd le vide qu'il gardait au-dessus
 *     des cartes. */
@media (min-width: 701px) {
  .home { margin-top: 14px; }
  .home-hero {
    padding-top: clamp(22px, 3.6vh, 44px);
    padding-bottom: clamp(20px, 3.2vh, 40px);
  }
  .home-booster-altar {
    display: grid; grid-template-columns: auto minmax(0, 1fr);
    align-items: center; justify-items: start; text-align: left;
    column-gap: clamp(20px, 3vw, 40px); row-gap: 12px;
    padding: clamp(18px, 2.6vh, 30px) clamp(20px, 3vw, 40px);
  }
  .home-booster-altar .altar-stats-side,
  .home-booster-altar .altar-appel { display: contents; }
  .home-booster-altar .altar-pack-side {
    grid-column: 1; grid-row: 1 / span 3; align-self: center; padding-bottom: 30px;
  }
  .home-booster-altar .altar-pack-preview {
    width: clamp(130px, 15vh, 180px); height: clamp(130px, 15vh, 180px);
  }
  .home-booster-altar .appel-kicker,
  .home-booster-altar .appel-titre,
  .home-booster-altar .appel-ligne { grid-column: 2; min-width: 0; margin: 0; }
  .home-booster-altar .appel-kicker { align-self: end; }
  .home-booster-altar .appel-ligne { align-self: start; max-width: 620px; }
  .home-booster-altar .vitrine-raretes,
  .home-booster-altar .altar-pack-actions { grid-column: 1 / -1; justify-self: center; }
  .home-booster-altar .vitrine-raretes { margin-top: 4px; width: 100%; }
  .home-booster-altar .altar-pack-actions { width: 100%; margin-top: 4px; }
  /* Sous un livre de 130-180 px, l'invite debordait sur la tuile ; le
     compteur dore dit deja combien il en reste, et le bouton fait l'appel. */
  .home-booster-altar .altar-invite { display: none; }
  .home-booster-altar .altar-pack-count-tag { white-space: nowrap; }
}
@media (min-width: 701px) and (max-width: 1100px) {
  .hero-cards-fan { height: calc(var(--carte-h) * 1.22); }
  .hero-cards-caption { margin-top: 14px; }
}
/* Des 900 px, le texte et l'eventail reprennent leurs deux colonnes (le
   palier etait a 1100) : en colonne unique ils s'empilaient sur 600 px, et
   c'est ce qui repoussait le grimoire sous le pli d'une tablette couchee. */
@media (min-width: 900px) and (max-width: 1100px) {
  .home-hero { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); align-items: center; }
  .hero-text-col { align-items: flex-start; text-align: left; }
  .hero-cta-group, .hero-chips { justify-content: flex-start; }
  .hero-cards-fan { --carte-w: clamp(92px, 10.5vw, 120px); height: calc(var(--carte-h) * 1.4); }
}
/* Tablette en portrait (colonne unique) : l'eventail et les boutons se
   resserrent, les trois boutons tiennent sur une ligne. */
@media (min-width: 701px) and (max-width: 899px) {
  main { padding-top: 12px; }
  .hero-cards-fan { --carte-w: 84px; }
  .hero-cta-group { flex-wrap: nowrap; gap: 8px; }
  .hero-cta-group .btn-hero-cta { padding: 10px 14px; font-size: 13.5px; white-space: nowrap; }
}

/* ══ LE TUTORIEL (js/tuto.js, 26/09/2026) ═══════════════════════════════════
   Trois pieces : l'ECRAN (bienvenue, victoire, deck prete, merci), la BULLE
   du guide pendant la partie, et le bouton QUITTER, toujours la. Le meme
   parchemin sombre filete d'or que les fenetres du duel : le guide appartient
   a l'arene, ce n'est pas une boite de dialogue du navigateur.
   Etages : la bulle passe sous l'annonce d'un Pouvoir (400) pour ne pas la
   cacher ; l'ecran passe au-dessus du deck prete (3000) et des fenetres
   globales (5000) ; « Quitter » au-dessus de l'ecran, sa question encore
   au-dessus. */
.tuto-kicker {
  font-family: var(--font-title);
  font-size: 10px; font-weight: 800; letter-spacing: .3em;
  text-transform: uppercase; color: #c9a246;
}
.tuto-texte { margin: 0; font-size: 14px; line-height: 1.55; color: var(--ink-dim); }
.tuto-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.tuto-points li { display: flex; gap: 11px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; color: var(--ink-dim); }
.tuto-points b { color: #f3e6c0; font-weight: 700; }
.tuto-point-ico {
  flex: none; width: 26px; height: 26px; margin-top: -2px;
  display: grid; place-items: center;
  border: 1px solid rgba(201, 162, 70, .45); border-radius: 50%;
  background: rgba(201, 162, 70, .08);
  color: var(--accent); font-size: 13px; line-height: 1;
}

/* ── L'ecran ─────────────────────────────────────────────────────────────── */
.tuto-ecran {
  position: fixed; inset: 0; z-index: 5500;
  display: grid; place-items: center; padding: 16px;
  background: rgba(4, 6, 11, .78);
  backdrop-filter: blur(8px);
  opacity: 0; transition: opacity .22s ease;
}
.tuto-ecran.is-on { opacity: 1; }
.tuto-ecran.tuto-confirm { z-index: 5700; }
.tuto-ecran-boite {
  position: relative;
  width: min(560px, 100%); max-height: calc(100dvh - 32px); overflow-y: auto;
  display: grid; gap: 14px;
  padding: 30px 32px 26px;
  border-radius: 6px;
  border: 1px solid rgba(201, 162, 70, .5);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(201, 162, 70, .13), transparent 60%),
    linear-gradient(180deg, rgba(26, 20, 30, .98), rgba(11, 8, 14, .98));
  box-shadow: 0 30px 80px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 232, 180, .12);
  transform: translateY(12px) scale(.98); transition: transform .3s cubic-bezier(.16, 1, .3, 1);
}
.tuto-ecran.is-on .tuto-ecran-boite { transform: none; }
.tuto-ecran-boite::before, .tuto-ecran-boite::after {
  content: ''; position: absolute; left: 14px; right: 14px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(201, 162, 70, .6), transparent);
}
.tuto-ecran-boite::before { top: 5px; }
.tuto-ecran-boite::after { bottom: 5px; }
.tuto-ecran-titre {
  margin: -4px 0 2px;
  font-family: var(--font-title); font-size: 27px; font-weight: 800; letter-spacing: .03em; line-height: 1.15;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tuto-ecran-pied { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }
.tuto-ecran-pied button { flex: 1 1 auto; min-height: 42px; }
.tuto-ecran-pied .primary { flex-grow: 2; }
/* La bienvenue : le nom du jeu, en grand, et la premiere phrase en exergue. */
.tuto-bienvenue .tuto-ecran-boite { text-align: center; justify-items: center; }
.tuto-bienvenue .tuto-ecran-titre { font-size: 34px; }
.tuto-bienvenue .tuto-texte:first-of-type { color: var(--accent-light); font-size: 15.5px; font-weight: 600; }
.tuto-bienvenue .tuto-texte:last-of-type { font-size: 12.5px; color: var(--ink-faint); }
.tuto-bienvenue .tuto-ecran-pied { width: 100%; }
.tuto-victoire .tuto-points { grid-template-columns: 1fr 1fr; gap: 10px 18px; }
.tuto-merci .tuto-ecran-boite { text-align: center; justify-items: center; }
.tuto-merci .tuto-ecran-pied { width: 100%; }

/* ── L'accueil de la premiere visite (js/accueil.js) ───────────────────────
   L'habit des ecrans du tutoriel, une seule boite dont les pages se
   remplacent. Au-dessus des fenetres globales, sous « Quitter ? ». */
.acc-ecran { z-index: 5600; }
.acc-boite { width: min(600px, 100%); }
.acc-boite[data-marche="bienvenue"],
.acc-boite[data-marche="tuto"] { text-align: center; justify-items: center; }
.acc-boite[data-marche="bienvenue"] .acc-points { text-align: left; width: 100%; margin: 4px 0; }
.acc-pied { width: 100%; }
.acc-titre-jeu { font-size: 36px; margin-top: -8px; }
.acc-exergue { color: var(--accent-light); font-size: 15.5px; font-weight: 600; }
.acc-question { color: #f3e6c0; font-weight: 600; margin-top: 2px; }
.acc-note { font-size: 12.5px; color: var(--ink-faint); }

/* Le choix de la langue : en tete de la bienvenue, et au profil. */
.acc-langue .langue-pastilles { justify-content: center; }
.acc-boite[data-marche="bienvenue"] .acc-langue { margin: -4px 0 2px; }
.acc-boite[data-marche="bienvenue"] .langue-pastilles button { min-height: 30px; padding: 4px 10px; font-size: 12.5px; }
.acc-champ-langue { display: grid; gap: 8px; }
.acc-champ-langue .acc-langue .langue-pastilles { justify-content: flex-start; }

/* Le symbole du jeu, peint au degrade d'or comme dans la barre (.brand-crest). */
.acc-blason { position: relative; width: 74px; height: 74px; margin: 2px auto -2px; }
.acc-blason-anneau {
  position: absolute; inset: 0;
  background: var(--or-metal);
  -webkit-mask: url(https://medias.kairostcg.com/logo/kairos-symbole.png) center / contain no-repeat;
  mask: url(https://medias.kairostcg.com/logo/kairos-symbole.png) center / contain no-repeat;
  filter: drop-shadow(0 0 12px rgba(245, 185, 66, .5));
  animation: acc-souffle 5s ease-in-out infinite;
}
.acc-blason-halo {
  position: absolute; inset: -18px; border-radius: 50%;
  background: radial-gradient(circle, rgba(245, 185, 66, .32) 0%, transparent 68%);
}
@keyframes acc-souffle { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05) rotate(3deg); } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .acc-blason-anneau { animation: none; } }

/* Les portefeuilles : une ligne par application, icone et nom. */
.acc-wallets { display: grid; gap: 8px; }
.acc-wallet {
  display: flex; align-items: center; gap: 12px;
  min-height: 48px; padding: 8px 14px; border-radius: 8px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid rgba(201, 162, 70, .3);
  color: #f3e6c0; font: inherit; font-size: 14px; font-weight: 600;
  text-align: left; text-decoration: none; cursor: pointer;
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}
.acc-wallet:hover:not(:disabled) { border-color: var(--accent); background: rgba(245, 185, 66, .08); transform: translateY(-1px); }
.acc-wallet:disabled { opacity: .5; cursor: default; }
.acc-wallet.en-cours { opacity: 1; border-color: var(--accent); }
.acc-wallet img, .acc-wallet-ico { width: 28px; height: 28px; border-radius: 7px; flex: none; }
.acc-wallet-ico {
  display: grid; place-items: center;
  background: rgba(201, 162, 70, .14); color: var(--accent); font-size: 13px; font-weight: 800;
}
.acc-wallet-lien { font-weight: 500; color: var(--ink-dim); }
.acc-vide { color: var(--ink-dim); }
.acc-etat { font-size: 13px; color: var(--accent-light); }
.acc-etat.est-erreur { color: #ff9a8a; }

/* Les portes du portefeuille (livraison.js) : Google ou Apple d'abord, mis en
   avant pour le nouveau venu, puis « J'ai deja un portefeuille ». Les memes
   dans la Boutique et dans l'accueil. */
.liv-portes { display: grid; gap: 16px; text-align: left; }
.liv-porte { display: grid; gap: 8px; }
.liv-titre { font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.liv-note { margin: 0; font-size: 13px; color: var(--ink-dim); }
.liv-sociale {
  padding: 12px; border-radius: 10px;
  background: rgba(245, 185, 66, .06); border: 1px solid rgba(245, 185, 66, .35);
}
.liv-social {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  width: 100%; min-height: 48px; padding: 0 16px; border-radius: 8px;
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  transition: filter .18s ease, transform .18s ease;
}
.liv-social img { width: 20px; height: 20px; flex: none; }
/* `button:hover:not(:disabled)` repeint le fond en bleu : chaque marque
   garde ses couleurs au survol, juste un ton plus marque. */
.liv-social:hover:not(:disabled):not(.est-grise) { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0, 0, 0, .45); }
.liv-google:hover:not(:disabled):not(.est-grise) { background: #f1f3f4; border-color: #5f6368; color: #1f1f1f; }
.liv-apple:hover:not(:disabled):not(.est-grise) { background: #1d1d1f; border-color: #3a3a3c; color: #fff; }
.liv-social:disabled, .liv-social.est-grise { opacity: .42; filter: grayscale(.65); cursor: not-allowed; transform: none; box-shadow: none; }
.liv-google { background: #fff; color: #1f1f1f; border: 1px solid #747775; }
.liv-apple { background: #000; color: #fff; border: 1px solid #000; }
.liv-apple img { width: 17px; height: 20px; margin-top: -2px; }
/* Le compte Discord, X et Courriel (virage web2, comptes.js). */
.liv-discord { background: #5865f2; color: #fff; border: 1px solid #5865f2; }
.liv-discord:hover, .liv-discord:hover:not(:disabled) { background: #4752c4; border-color: #4752c4; color: #fff; }
.liv-x { background: #000; color: #fff; border: 1px solid #333; }
.liv-x:hover:not(:disabled):not(.est-grise) { background: #16181c; border-color: #536471; color: #fff; }
.liv-courriel { background: rgba(255, 255, 255, .06); color: #f3e6c0; border: 1px solid rgba(201, 162, 70, .4); }
.liv-courriel:hover:not(:disabled):not(.est-grise) { background: rgba(245, 185, 66, .12); border-color: var(--accent); color: #fff; }
.liv-google.est-grise:hover { background: #fff; border-color: #747775; color: #1f1f1f; }
.liv-apple.est-grise:hover { background: #000; border-color: #000; color: #fff; }
.liv-x.est-grise:hover { background: #000; border-color: #333; color: #fff; }
.liv-courriel.est-grise:hover { background: rgba(255, 255, 255, .06); border-color: rgba(201, 162, 70, .4); color: #f3e6c0; }
.liv-courriel-form { display: grid; gap: 8px; padding: 10px; border-radius: 8px; background: rgba(0, 0, 0, .28); border: 1px solid rgba(201, 162, 70, .25); }
.liv-courriel-form[hidden] { display: none; }
.liv-champ {
  width: 100%; min-height: 40px; padding: 8px 12px; border-radius: 6px;
  background: rgba(12, 10, 18, .85); border: 1px solid rgba(201, 162, 70, .35);
  color: #f3e6c0; font: inherit; font-size: 14px; box-sizing: border-box;
}
.liv-champ:focus { outline: none; border-color: var(--accent); }
.liv-courriel-valider { width: 100%; min-height: 42px; }
.liv-attente {
  margin: 4px 0 0; padding: 10px 12px; border-radius: 8px;
  background: rgba(245, 185, 66, .1); border: 1px solid rgba(245, 185, 66, .4);
  color: #f3e6c0; font-size: 13px; line-height: 1.45; text-align: center;
}
.liv-attente[hidden] { display: none; }
a.liv-social { text-decoration: none; box-sizing: border-box; }
.liv-boite { width: min(460px, 100%); }
.wallet-creer { color: var(--accent); font-weight: 700; }
.wallet-sep { height: 1px; margin: 4px 6px; background: rgba(201, 162, 70, .25); }

/* Le guide Jupiter Mobile (livraison.js, porte 3) : quatre etapes numerotees. */
.liv-guide { display: grid; gap: 12px; }
.liv-etapes { list-style: none; counter-reset: etape; margin: 0; padding: 0; display: grid; gap: 12px; }
.liv-etapes li {
  counter-increment: etape; position: relative; display: grid; gap: 4px;
  padding: 10px 12px 10px 48px; border-radius: 8px;
  background: rgba(255, 255, 255, .035); border: 1px solid rgba(201, 162, 70, .25);
}
.liv-etapes li::before {
  content: counter(etape); position: absolute; left: 12px; top: 10px;
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  background: rgba(245, 185, 66, .16); color: var(--accent); font-weight: 800; font-size: 13px;
}
.liv-etapes b { color: #f3e6c0; font-size: 14px; }
.liv-etapes span { color: var(--ink-dim); font-size: 13px; }
.liv-lien { justify-self: start; margin-top: 4px; color: var(--accent); font-weight: 700; }
button.liv-lien { margin: 0; padding: 0; background: none; border: 0; font: inherit; font-size: 13px; cursor: pointer; }
button.liv-lien[hidden], .liv-champ[hidden] { display: none; }
.liv-ligne-adresse { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.liv-adresse {
  padding: 6px 10px; border-radius: 6px; background: rgba(0, 0, 0, .35);
  color: #f3e6c0; font-size: 13px; word-break: break-all; user-select: all;
}
.liv-copier { padding: 6px 12px; font-size: 13px; }
.liv-retour { justify-self: start; }
.liv-fait { justify-self: start; margin-top: 6px; }
.liv-astuce { padding: 8px 10px; border-radius: 6px; background: rgba(255, 255, 255, .035); font-size: 12.5px; }
.liv-alerte {
  display: flex; align-items: baseline; gap: 8px; margin: 8px 0 0; padding: 8px 10px; border-radius: 6px;
  background: rgba(255, 120, 100, .1); border: 1px solid rgba(255, 120, 100, .45);
  color: #ffd2c8; font-size: 13px;
}
.liv-alerte b { color: #fff; }
.liv-alerte-ico {
  flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%;
  background: #ff7a64; color: #120d0a; font-size: 12px; font-weight: 800; transform: translateY(3px);
}

/* L'assistant de creation (livraison.js, guideCreation, 16/10/2026) : une
   question, puis un ecran par etape, et la maquette de l'ecran Jupiter avec
   le bon bouton surligne. */
.liv-assistant { gap: 14px; }
.liv-question { margin: 2px 0 0; font-size: 18px; font-weight: 700; color: #f3e6c0; }
.liv-choix { display: grid; gap: 8px; }
.liv-option {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border-radius: 10px;
  background: rgba(255, 255, 255, .04); border: 1px solid rgba(201, 162, 70, .3);
  color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.liv-option:hover:not(:disabled) { background: rgba(245, 185, 66, .09); border-color: var(--accent); color: inherit; transform: translateY(-1px); }
.liv-option:first-child { border-color: rgba(245, 185, 66, .6); }
.liv-option-ico { flex: none; font-size: 24px; line-height: 1; }
.liv-option-txt { flex: 1; display: grid; gap: 2px; }
.liv-option-txt b { color: #f3e6c0; font-size: 15px; }
.liv-option-txt span { color: var(--ink-dim); font-size: 13px; }
.liv-option-fleche { flex: none; color: var(--accent); font-size: 22px; }

.liv-assistant-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.liv-points { display: flex; gap: 6px; }
.liv-points span { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, .18); transition: width .2s ease; }
.liv-points .est-fait { background: rgba(245, 185, 66, .55); }
.liv-points .est-ici { width: 22px; border-radius: 4px; background: var(--accent); }
.liv-etape { display: grid; gap: 10px; }
.liv-etape-titre { display: flex; align-items: center; gap: 10px; }
.liv-etape-titre b { color: #f3e6c0; font-size: 17px; }
.liv-etape-num {
  flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
  background: var(--accent); color: #1a1206; font-weight: 800; font-size: 14px;
}
.liv-etape-texte { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink); }
.liv-action { justify-self: start; display: inline-block; text-decoration: none; }
.liv-grosse { justify-self: start; font-size: 17px; padding: 8px 14px; }
.liv-pied { display: flex; justify-content: space-between; gap: 8px; padding-top: 4px; border-top: 1px solid rgba(201, 162, 70, .2); }
.liv-pied > :only-child { margin-right: auto; }
.liv-chemin { display: flex; flex-wrap: wrap; gap: 4px 6px; margin: 0; padding: 0; list-style: none; }
.liv-chemin li { padding: 3px 9px; border-radius: 6px; background: #2c2c30; color: #fff; font-size: 13px; font-weight: 600; }
.liv-chemin li + li::before { content: '→ '; color: #c7f284; }

/* La maquette Jupiter : ses couleurs a lui (gris anthracite, vert citron). */
.jm {
  position: relative; display: grid; gap: 6px; padding: 12px; border-radius: 12px;
  background: #1d1d21; border: 1px solid #333338; color: #fff;
  font-family: Inter, system-ui, sans-serif; font-size: 12px;
}
.jm-tete { display: flex; align-items: center; gap: 10px; padding: 0 2px 4px; font-size: 14px; font-weight: 700; }
.jm-fleche { color: #8a8a90; }
.jm-ligne {
  position: relative; display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 9px;
  background: #2c2c30; opacity: .55;
}
.jm-ico {
  flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
  background: #3b4033; color: #c7f284; font-size: 14px;
}
.jm-ico img { width: 16px; height: 16px; }
.jm-txt { flex: 1; display: grid; gap: 1px; min-width: 0; }
.jm-txt b { font-size: 13px; }
.jm-txt small { color: #a6a6ac; font-weight: 400; font-size: 11px; }
.jm-txt > span { color: #a6a6ac; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jm-badge {
  position: absolute; top: 0; right: 0; padding: 2px 8px; border-radius: 0 9px 0 8px;
  background: #3b4033; color: #c7f284; font-size: 10px; font-weight: 700;
}
.jm-cible {
  opacity: 1; background: #34352f;
  box-shadow: 0 0 0 2px #c7f284, 0 0 18px rgba(199, 242, 132, .35);
  animation: jm-pulse 1.6s ease-in-out infinite;
}
@keyframes jm-pulse {
  50% { box-shadow: 0 0 0 2px #c7f284, 0 0 4px rgba(199, 242, 132, .15); }
}
/* La fleche de souris posee sur la bonne ligne (pas un badge : il se lisait
   comme un bouton de notre fenetre). */
.jm-curseur {
  position: absolute; right: 14%; bottom: -8px; z-index: 1; line-height: 0;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .6));
  animation: jm-pointe 1.6s ease-in-out infinite;
}
@keyframes jm-pointe { 50% { transform: translate(-3px, -3px); } }
.jm-pilule { position: relative; }
.jm-pilule .jm-curseur { right: -6px; bottom: -12px; }

/* L'APERCU : une fausse fenetre (ou un faux telephone) qui encadre la
   maquette, legende dessous. Inerte et visiblement « ailleurs ». */
.jm-apercu { margin: 2px 0 0; display: grid; gap: 6px; pointer-events: none; user-select: none; }
.jm-cadre {
  border-radius: 10px; overflow: hidden; background: #0e0f12;
  border: 1px solid #3a3b42; box-shadow: 0 10px 26px rgba(0, 0, 0, .55);
}
.jm-cadre-haut {
  display: flex; align-items: center; gap: 10px; padding: 6px 10px;
  background: #24252b; border-bottom: 1px solid #34353c;
}
.jm-feux { width: 34px; height: 8px; flex: none;
  background: radial-gradient(circle at 4px 4px, #ff5f57 3.5px, transparent 4px),
              radial-gradient(circle at 17px 4px, #febc2e 3.5px, transparent 4px),
              radial-gradient(circle at 30px 4px, #28c840 3.5px, transparent 4px); }
.jm-barre {
  flex: 1; padding: 3px 10px; border-radius: 999px; background: #15161a;
  color: #9a9ba3; font: 11px Inter, system-ui, sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.jm-cadre > .jm { margin: 10px; }
.jm-apercu-telephone .jm-cadre { justify-self: center; width: min(300px, 100%); border-radius: 18px; border-width: 3px; }
.jm-apercu-telephone .jm-cadre-haut { justify-content: center; }
.jm-apercu-telephone .jm-barre { flex: none; background: none; }
.jm-apercu-telephone .liv-chemin { padding: 12px; }
.jm-legende-apercu { text-align: center; font-size: 11.5px; font-style: italic; color: var(--ink-dim); }

/* « Je le cree, pas a pas » : le bouton du nouveau venu, dore et en tete
   quand le navigateur n'a aucun portefeuille. */
.liv-cta {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 50px; padding: 0 16px; border-radius: 10px; font-size: 15.5px; cursor: pointer;
}
.liv-cta img { width: 24px; height: 24px; border-radius: 6px; }

/* « Comment ca va se passer » : quatre lignes avant la premiere etape. */
.liv-deroule { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.liv-deroule li {
  display: flex; gap: 12px; align-items: flex-start; padding: 10px 12px; border-radius: 8px;
  background: rgba(255, 255, 255, .035); border: 1px solid rgba(201, 162, 70, .22);
  font-size: 14px; line-height: 1.45; color: var(--ink);
}
.liv-deroule-ico { flex: none; width: 22px; text-align: center; font-size: 17px; color: var(--accent); }

/* Le lien d'action habille en bouton dore (Ouvrir jup.ag/wallet...). */
a.liv-action {
  display: inline-block; padding: 10px 18px; border-radius: 8px; border: 1px solid;
  text-decoration: none; font-size: 14px;
}
/* La fenetre flottante (Document Picture-in-Picture) : le guide seul,
   au-dessus de Jupiter. Dans la page, une place qui dit ou il est parti. */
/* Le fond sur html, pas sur body : un body plus court que la fenetre
   repetait son degrade en bandes sous le guide. */
html:has(> body.liv-pip) {
  min-height: 100%;
  background: var(--bg-deep) radial-gradient(120% 70% at 50% 0%, #2a1d0c 0%, var(--bg-deep) 75%) no-repeat;
}
body.liv-pip { min-height: 0; padding: 16px; overflow-y: auto; background: none; }
body.liv-pip .liv-assistant { text-align: left; }
.liv-flotte { padding: 12px; border-radius: 10px; border: 1px dashed rgba(245, 185, 66, .45); background: rgba(245, 185, 66, .05); }
.liv-flotte .ghost { justify-self: start; }

/* Ou ca se passe : la pastille en tete d'etape. */
.liv-lieu {
  justify-self: start; display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px 3px 8px;
  border-radius: 999px; font-size: 12px; font-weight: 700;
  background: rgba(199, 242, 132, .1); border: 1px solid rgba(199, 242, 132, .45); color: #d9f5b0;
}
.liv-lieu-kairos { background: rgba(245, 185, 66, .12); border-color: rgba(245, 185, 66, .5); color: var(--accent); }
.liv-lieu-ico { font-size: 13px; }
.jm-boutique { gap: 10px; }
.jm-legende { color: #a6a6ac; font-size: 12px; }
.jm-pilules { display: flex; flex-wrap: wrap; gap: 8px; }
.jm-pilule {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px;
  background: #22283a; border: 1px solid #333a50; font-size: 14px; font-weight: 700; opacity: .55;
}
.jm-pilule.jm-cible { background: #23301f; border-color: #c7f284; }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .jm-cible, :where(html:not(.mouvement-plein)) .jm-curseur { animation: none; } }
/* Jupiter ID : les cinq comptes allumes, aucun impose. */
.jm-toutes .jm-ligne { opacity: 1; box-shadow: 0 0 0 1px rgba(199, 242, 132, .45); }

/* Le banc des portefeuilles (banc_portefeuille.js, `?banc-portefeuille`). */
.banc-essais { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 8px; text-align: left; }
.banc-essai {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 10px 12px; border-radius: 8px;
  background: rgba(255, 255, 255, .035); border: 1px solid rgba(201, 162, 70, .25);
}
.banc-essai b { display: block; font-size: 14px; color: #f3e6c0; }
.banc-marque {
  flex: none; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  font-weight: 800; background: rgba(255, 255, 255, .08); color: var(--ink-dim);
}
.banc-essai.est-ok { border-color: rgba(110, 200, 130, .45); }
.banc-essai.est-ok .banc-marque { background: rgba(110, 200, 130, .2); color: #8be0a0; }
.banc-essai.est-echec { border-color: rgba(255, 120, 100, .5); }
.banc-essai.est-echec .banc-marque { background: rgba(255, 120, 100, .2); color: #ff9a8a; }
.banc-detail { font-size: 12px; color: var(--ink-dim); word-break: break-word; }
.banc-verdict { margin: 12px 0 0; font-weight: 700; }
.banc-verdict.est-ok { color: #8be0a0; }
.banc-verdict.est-echec { color: #ff9a8a; }

/* L'invite est prevenu : un encadre qu'on ne peut pas ne pas lire. */
.acc-alerte {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 13px 15px; border-radius: 8px;
  background: rgba(220, 90, 60, .1);
  border: 1px solid rgba(235, 120, 90, .5);
}
.acc-alerte-ico {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(235, 120, 90, .2); color: #ffb09c; font-weight: 900;
}
.acc-alerte b { display: block; color: #ffc9b8; font-size: 14.5px; margin-bottom: 4px; }
.acc-alerte p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-dim); }

/* Le profil : le visage choisi a cote du nom, puis la galerie. */
.acc-tete { display: flex; align-items: center; gap: 16px; }
.acc-apercu {
  flex: none; width: 76px; height: 76px; border-radius: 50%; padding: 3px;
  background: var(--gold-grad);
  box-shadow: 0 0 22px rgba(245, 185, 66, .3);
}
.acc-apercu .dl-rond { background: radial-gradient(circle at 30% 25%, rgba(245, 185, 66, .14), rgba(12, 16, 26, .95)); }
.acc-apercu-grand { width: 96px; height: 96px; margin: 0 auto; }
.acc-champ { flex: 1; min-width: 0; }
.acc-persos-titre {
  font-family: var(--font-title); font-size: 11px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-dim);
}
.acc-persos .pm-carte { width: 104px; }

/* ── La bulle ────────────────────────────────────────────────────────────── */
.tuto-bulle {
  position: fixed; z-index: 390;
  left: 16px; top: 64px;
  width: min(340px, calc(100vw - 32px));
  display: grid; gap: 9px;
  padding: 16px 18px 16px;
  border-radius: 6px;
  border: 1px solid rgba(201, 162, 70, .55);
  background:
    radial-gradient(130% 110% at 0% 0%, rgba(201, 162, 70, .14), transparent 58%),
    linear-gradient(180deg, rgba(26, 20, 30, .97), rgba(11, 8, 14, .97));
  box-shadow: 0 18px 50px rgba(0, 0, 0, .66), 0 0 0 1px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 232, 180, .12);
}
.tuto-bulle.est-masquee { display: none; }
.tuto-bulle.entre { animation: tuto-entre .32s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes tuto-entre {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
.tuto-bulle-tete { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.tuto-bulle-titre {
  margin: 0; font-family: var(--font-title); font-size: 18px; font-weight: 800; letter-spacing: .02em;
  color: #f3e6c0; text-shadow: 0 0 18px rgba(201, 162, 70, .28); line-height: 1.2;
}
.tuto-bulle .tuto-texte { font-size: 13px; line-height: 1.5; }
.tuto-bulle .tuto-points li { font-size: 12.5px; }
.tuto-bulle-pied { display: flex; justify-content: flex-end; margin-top: 2px; }
.tuto-suite { min-width: 120px; }
.tuto-rappel {
  margin: 0; padding: 7px 10px; border-radius: 4px;
  background: rgba(248, 113, 113, .12); border: 1px solid rgba(248, 113, 113, .35);
  color: #ffc9c3; font-size: 12.5px; line-height: 1.4;
}
.tuto-rappel.secoue { animation: tuto-secoue .42s ease; }
@keyframes tuto-secoue {
  0%, 100% { transform: none; }
  20% { transform: translateX(-5px); } 40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); } 80% { transform: translateX(3px); }
}
/* Le voile : pendant que le guide parle, la table ne prend pas de clic. */
.tuto-voile { position: fixed; inset: 0; z-index: 380; background: rgba(3, 4, 8, .28); }
.tuto-voile[hidden] { display: none; }

/* Ce que le guide designe : un anneau d'or qui respire. */
/* Sans `position` : la cible peut etre un bouton pose en absolu (la languette
   du Pouvoir), qu'un `relative` aurait fait sauter hors de sa place. */
.tuto-cible {
  outline: 2px solid var(--accent) !important; outline-offset: 3px;
  animation: tuto-respire 1.4s ease-in-out infinite;
}
.mc-carte.tuto-cible { z-index: 2; outline-width: 3px !important; }
/* Dans la loupe, qui defile, un cadre pose a l'exterieur etait rogne au
   bord gauche de la colonne : il se dessine en dedans. */
.loupe .tuto-cible, #loupe .tuto-cible { outline-offset: -2px; }
/* UNE SEULE CARTE S'ANNONCE. Pendant une consigne, les halos « jouable » du
   jeu se taisent : trois cartes qui respirent ensemble ne disent pas
   laquelle prendre. */
body.tuto-guide .mc-carte.jouable:not(.tuto-cible) {
  animation: none; filter: saturate(.8) brightness(.82); outline-color: transparent;
}
body.tuto-guide .mc-carte.jouable:not(.tuto-cible)::after { display: none; }

/* LA FLECHE : posee au-dessus de la cible par js/tuto.js (`pointer`), elle
   pointe vers le bas ; `.dessous` quand la cible touche le haut de l'ecran.
   Elle ne prend jamais le doigt. */
.tuto-doigt {
  position: fixed; z-index: 5550; left: 0; top: 0;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  pointer-events: none;
  transform: translate(-50%, -100%);
  animation: tuto-doigt 1s ease-in-out infinite;
}
.tuto-doigt[hidden] { display: none; }
.tuto-doigt-fleche {
  width: 0; height: 0;
  border-left: 13px solid transparent; border-right: 13px solid transparent;
  border-top: 20px solid var(--accent);
  filter: drop-shadow(0 0 6px rgba(245, 185, 66, .9)) drop-shadow(0 2px 2px rgba(0, 0, 0, .8));
}
.tuto-doigt-nom {
  padding: 2px 9px; border-radius: 999px;
  background: rgba(12, 9, 15, .92); border: 1px solid var(--accent);
  color: #f3e6c0; font: 700 11px/1.35 var(--font-title); letter-spacing: .05em;
  white-space: nowrap; box-shadow: 0 2px 8px rgba(0, 0, 0, .6);
}
.tuto-doigt-nom[hidden] { display: none; }
.tuto-doigt.dessous { flex-direction: column-reverse; transform: translate(-50%, 0); animation-name: tuto-doigt-bas; }
.tuto-doigt.dessous .tuto-doigt-fleche { border-top: 0; border-bottom: 20px solid var(--accent); }
/* A droite d'une carte de la main : pointee vers la gauche, le nom apres. */
.tuto-doigt.a-droite { flex-direction: row-reverse;transform: translate(0, -50%); animation-name: tuto-doigt-gauche; }
.tuto-doigt.a-droite .tuto-doigt-fleche {
  border: 0; border-top: 13px solid transparent; border-bottom: 13px solid transparent;
  border-right: 20px solid var(--accent);
}
@keyframes tuto-doigt-gauche {
  0%, 100% { transform: translate(0, -50%); }
  50%      { transform: translate(9px, -50%); }
}
@keyframes tuto-doigt {
  0%, 100% { transform: translate(-50%, -100%); }
  50%      { transform: translate(-50%, calc(-100% - 9px)); }
}
@keyframes tuto-doigt-bas {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 9px); }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .tuto-doigt { animation: none; } }

/* Sous l'invitation au Pouvoir, la bulle se tait : la fenetre parle seule. */
.tuto-bulle.sous-fenetre, .tuto-quitter.sous-fenetre { visibility: hidden; }
/* UNE CARTE OUVERTE, AU TELEPHONE : la bulle se range au bas de l'ecran, et
   la fenetre de la carte lui laisse la place (`--tuto-quai`, mobile.css). */
.tuto-bulle.a-quai {
  left: 0; right: 0; top: auto; bottom: 0; width: auto;
  max-height: 60vh; max-height: 60dvh; overflow-y: auto;
  border-radius: 12px 12px 0 0; border-bottom: 0;
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
}
.tuto-bulle.a-quai.entre { animation: none; }
/* LE BOUTON RESTE EN VUE. Plafonnee (ecran court, place laissee a la cible),
   la bulle fait defiler son texte, jamais son bouton : il colle au bas. */
.tuto-bulle { overflow-y: auto; overscroll-behavior: contain; }
.tuto-bulle-pied {
  position: sticky; bottom: -16px; margin: 0 -18px -16px; padding: 8px 18px 14px;
  background: linear-gradient(180deg, rgba(11, 8, 14, 0), rgba(11, 8, 14, .97) 35%);
}
.tuto-bulle.en-portrait .tuto-bulle-pied { bottom: -12px; margin: 0 -13px -12px; padding: 6px 13px 10px; }
.tuto-bulle.a-quai .tuto-bulle-pied {
  bottom: calc(-12px - env(safe-area-inset-bottom, 0px));
  margin-bottom: calc(-12px - env(safe-area-inset-bottom, 0px));
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
}
/* Compact : la carte ouverte au-dessus a besoin de chaque pixel. */
.tuto-bulle.a-quai { gap: 5px; padding-top: 10px; }
.tuto-bulle.a-quai .tuto-bulle-titre { font-size: 14.5px; }
.tuto-bulle.a-quai .tuto-texte { font-size: 12px; line-height: 1.4; }
.tuto-bulle.a-quai .tuto-points { gap: 4px; }
.tuto-bulle.a-quai .tuto-points li { font-size: 11.5px; }
.tuto-bulle.a-quai .tuto-suite { padding: 6px 16px; min-width: 0; }
@keyframes tuto-respire {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 185, 66, .55); }
  50%      { box-shadow: 0 0 0 7px rgba(245, 185, 66, 0); }
}

/* ── Quitter ─────────────────────────────────────────────────────────────── */
/* Hors du duel, en haut a gauche (la ceremonie du deck a sa croix a droite) ;
   sur la table, js/tuto.js le centre au-dessus de la bulle. */
.tuto-quitter {
  position: fixed; z-index: 5600; top: 12px; left: 16px;
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid rgba(201, 162, 70, .45);
  background: rgba(12, 9, 15, .88); color: var(--accent-light);
  font-family: var(--font-title); font-size: 11px; font-weight: 700; letter-spacing: .08em;
  cursor: pointer;
}
/* Le bouton ne bouge pas au survol : la regle universelle des boutons
   (`button:hover:not(:disabled)`, translateY) ecrasait le centrage. */
button.tuto-quitter:hover:not(:disabled), button.tuto-quitter:active:not(:disabled) {
  background: rgba(12, 9, 15, .88); transform: none;
  border-color: var(--accent); box-shadow: 0 0 14px var(--gold-glow);
}
.tuto-quitter[hidden] { display: none; }
.tuto-quitter.sur-table,
button.tuto-quitter.sur-table:hover:not(:disabled),
button.tuto-quitter.sur-table:active:not(:disabled) { transform: translateX(-50%); }

/* Le bouton des Parametres est un <button> habille en lien. */
button.parametres-lien {
  width: 100%; font: inherit; font-size: 13px; text-align: left; cursor: pointer;
  background: none; border: 0; border-top: 1px solid rgba(245, 185, 66, .25);
  border-radius: 0; padding: 12px 0 0; box-shadow: none; color: var(--accent-light);
}

/*  LA COLONNE DU KIT SUR UN ECRAN COURT (27/09/2026). Sous 860 px de haut
 *  (tablette couchee, petit portable), les trois tuiles -- boite, plateau,
 *  des -- et leurs hauteurs minimales (340 px) ne tenaient plus dans la place
 *  que leur laissait la colonne : elles debordaient PAR-DESSUS l'etui des
 *  jauges. La colonne defile, chaque tuile garde sa hauteur, rien ne se
 *  chevauche. */
/*  Le seuil de hauteur ne suffisait pas : a 900 px, une fois l'identite du
 *  deck et l'etui des jauges poses, la vitrine se tassait encore sous ses
 *  340 px et les Des passaient sous l'etui. C'est la VITRINE qui defile, pas
 *  la colonne : la colonne doit rester `overflow: visible`, sinon elle coupe
 *  la liste « Mes decks » (340 px, plus large qu'elle). */
@media (min-width: 501px) {
  #view-atelier .kit { overflow: visible; }
  #view-atelier .kit .vitrine {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
  }
  #view-atelier .kit .vitrine > .vt-tuile { flex-shrink: 0; }
}

/*  L'atelier garde son score en haut, sans une seconde boite : la sienne est
    deja dans le kit. La boite 3D, elle, se montre au multijoueur et au salon. */
.score-haut .cof-force {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  margin: 0 0 10px; padding: 0; border: 0; background: none;
}
.multi-scores {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 36px; margin: 0 0 8px; background: none; border: 0;
}
.deck-nu {
  display: flex; align-items: center; gap: 8px;
  background: none; border: 0; box-shadow: none;
}
.deck-nu-boite { width: 180px; height: 180px; flex: none; }
.deck-nu .bib-scene { width: 180px; height: 180px; }
.deck-nu .bib-scene .cof3d-plan { transform: scale(.18); }
.deck-nu .cof-force {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  margin: 0; padding: 0; border: 0; background: none; box-shadow: none;
}
.cof-force-nom {
  font-family: var(--font-title), serif; font-size: 15px; font-weight: 800;
  color: #fff3d6; max-width: 180px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.score-haut .cof-force-n,
.deck-nu .cof-force-n { font-size: 32px; line-height: 1; }
.score-haut .cof-force-barre { flex: 1 1 120px; grid-column: auto; height: 6px; min-width: 72px; }
.score-haut .cof-force-suite { grid-column: auto; }
.deck-nu .cof-force-barre { width: 120px; grid-column: auto; height: 5px; }
.deck-nu .cof-force-suite { grid-column: auto; }
.deck-nu-alerte {
  align-self: center; font-size: 10px; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: #fca5a5;
}
@media (min-width: 501px) {
  #view-atelier .score-haut { grid-column: 1 / -1; grid-row: 1; justify-content: flex-start; }
  #view-atelier .deck-rail .filtres-haut { grid-row: 2; }
  #view-atelier .dk-actions { grid-row: 2; }
}
@media (min-width: 501px) and (max-width: 1100px) {
  #view-atelier .deck-rail .filtres-haut { grid-row: 2; }
  #view-atelier .dk-actions { grid-row: 3; }
}

/* ══ LE CLASSEMENT DE LA SEMAINE (js/classement_vue.js) ═══════════════════ */
#view-classement.is-on { display: flex; flex-direction: column; min-height: calc(100dvh - var(--topbar-h)); }
.cl-moi-titre { margin: 0 0 8px; font-size: 15px; color: var(--ink-bright); }
.cl-conditions { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.cl-conditions li { display: flex; gap: 8px; align-items: baseline; color: var(--ink-dim); }
.cl-coche { flex: none; width: 18px; text-align: center; font-weight: 800; }
.cl-conditions .is-ok .cl-coche { color: var(--ok); }
.cl-conditions .is-non .cl-coche { color: var(--bad); }
.cl-note, .cl-vide { margin: 10px 0 0; font-size: 12.5px; color: var(--ink-faint); line-height: 1.45; }
.cl-vide { padding: 24px 8px; text-align: center; }
.cl-alerte { margin: 8px 0 0; font-size: 13px; color: var(--bad); }
/* L'accord signe, avant d'entrer au classement. */
.cl-accord {
  max-width: 640px; margin: 24px auto 40px; padding: 22px clamp(16px, 4vw, 30px);
  border-radius: 16px; background: rgba(12, 10, 18, .82); border: 1px solid var(--line-gold);
  box-shadow: 0 0 40px rgba(245, 185, 66, .08);
  display: flex; flex-direction: column; gap: 12px;
}
.cl-accord h2 { margin: 0; font-family: var(--font-title); font-size: 20px; letter-spacing: .05em; color: var(--accent-light); }
.cl-accord-chapeau { margin: 0; font-size: 14px; color: var(--ink); line-height: 1.5; }
.cl-accord-liste { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; color: var(--ink-dim); line-height: 1.45; }
.cl-accord-triche {
  padding: 12px 14px; border-radius: 12px;
  background: rgba(255, 90, 80, .07); border: 1px solid rgba(255, 110, 100, .35);
}
.cl-accord-triche strong { display: block; color: #ff8a80; font-size: 14.5px; margin-bottom: 4px; }
.cl-accord-triche p { margin: 4px 0 0; font-size: 13px; color: var(--ink); line-height: 1.45; }
.cl-accord button { align-self: center; min-width: 220px; margin-top: 4px; }
.cl-accord-note { margin: 0; text-align: center; font-size: 12px; color: var(--ink-faint); }
/* Chaque regle de l'accord se coche « bien compris ». */
.cl-accord-liste { padding-left: 0; }
.cl-accord-case {
  display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
  font-size: 13.5px; color: var(--ink); line-height: 1.45;
}
.cl-accord-case + .cl-accord-case { margin-top: 8px; }
.cl-accord-case input { flex: none; width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--accent); cursor: pointer; }
.cl-accord-triche .cl-accord-case { margin-top: 8px; }
.cl-accord-triche .cl-accord-case input { accent-color: #ff8a80; }
.cl-accord button:disabled { opacity: .45; cursor: not-allowed; }

/* Jouer une partie classee, depuis la page. */
.cl-jouer {
  padding: 14px; border-radius: 14px;
  background: rgba(12, 10, 18, .72); border: 1px solid var(--line-gold);
  box-shadow: 0 0 24px rgba(245, 185, 66, .06);
}
.cl-jouer .cl-note:first-of-type { margin-top: 0; }
.cl-jouer-boutons { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.cl-jouer-boutons button { flex: 1 1 140px; min-height: 40px; }

/* Le salon du multijoueur, en classe. */
.salon-classe-bandeau {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  margin: 12px clamp(12px, 2vw, 28px) 0; padding: 10px 14px; border-radius: 12px;
  background: rgba(245, 185, 66, .08); border: 1px solid var(--line-gold);
  font-size: 13px; color: var(--ink);
}
.salon-classe-bandeau strong { color: var(--accent-light); letter-spacing: .06em; text-transform: uppercase; font-size: 12.5px; }
.salon-classe-bandeau span { flex: 1 1 260px; color: var(--ink-dim); }

/* La recherche d'un adversaire. */
.recherche-classee {
  position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center; padding: 16px;
  background: rgba(2, 4, 8, .72); backdrop-filter: blur(3px);
}
.recherche-classee[hidden] { display: none; }
.recherche-panneau {
  width: min(380px, 100%); padding: 24px 22px 20px; border-radius: 16px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: rgba(10, 12, 20, .96); border: 1px solid var(--line-gold);
  box-shadow: 0 0 40px rgba(245, 185, 66, .12);
}
.recherche-sigle { font-size: 30px; color: var(--accent); animation: recherchePouls 1.6s ease-in-out infinite; }
.recherche-titre { font-family: var(--font-title); font-size: 18px; letter-spacing: .06em; color: var(--accent-light); }
.recherche-texte { margin: 0; font-size: 14px; color: var(--ink); min-height: 2.9em; }
.recherche-temps { font-family: var(--font-num); font-size: 13px; color: var(--ink-faint); }
.recherche-panneau button { margin-top: 6px; min-width: 140px; }
@keyframes recherchePouls { 0%, 100% { transform: scale(1); opacity: .8; } 50% { transform: scale(1.15); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .recherche-sigle { animation: none; } }

.cl-ok { margin: 8px 0 0; font-size: 13px; color: var(--ok); }
.cl-monprix {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 0; border-top: 1px solid var(--line); font-size: 13px; color: var(--ink-dim);
}
.cl-monprix:first-of-type { border-top: 0; }
.cl-etat { font-size: 12px; color: var(--ink-faint); text-align: right; }
.cl-etat.is-reclame { color: var(--ok); }
.cl-etat.is-annule { color: var(--bad); }
/*  Le compteur des 7 jours, a cote de « Reclamer mon prix » ; rouge le dernier jour. */
.cl-monprix { flex-wrap: wrap; }
.cl-monprix > span:first-child { flex: 1 1 auto; }
.cl-reste { font-size: 12px; color: var(--ink-faint); white-space: nowrap; }
.cl-reste.is-urgent { color: var(--bad); font-weight: 700; }
.cl-regles summary { cursor: pointer; font-size: 13.5px; color: var(--ink); }
.cl-regles ul { margin: 10px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--ink-dim); line-height: 1.45; }


/* ══ LE CLASSEMENT EN PLEINE PAGE (Alexandre, 13/10/2026) ═════════════════
   « Qu'il prenne la page au complet » : un bandeau (titre, compte a rebours,
   semaine), puis trois colonnes -- TOI | LE TABLEAU (podium, lignes) | LES
   PRIX. Sur ordinateur la page tient dans l'ecran et seul l'interieur des
   colonnes defile ; en dessous, tout s'empile. Les trois metaux du podium
   sont des variables : la ligne, la marche et le barreau des prix lisent
   les memes. */
#view-classement {
  --cl-or: #f5b942; --cl-or-clair: #ffe39a;
  --cl-argent: #cfd9ea; --cl-argent-clair: #f3f7ff;
  --cl-bronze: #d98e52; --cl-bronze-clair: #f6c79c;
}
/*  14/10 : « que la section prenne toute la place » -- le plafond de 1720 px
    de `main` (et 1880 px de la page) laissait deux grands vides sur les
    ecrans larges ; on le leve comme pour la Saison et le Marche. */
body:has(#view-classement.is-on .cl-page) main { max-width: none; }
.cl-page {
  width: 100%; margin: 0 auto; padding: 0 clamp(12px, 2vw, 28px) 20px;
  display: flex; flex-direction: column; gap: 16px;
}
#view-classement.is-lecture .cl-grille { opacity: .45; pointer-events: none; transition: opacity .2s; }

/* Le bandeau. */
.cl-hero {
  position: relative; display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: 14px 24px; padding: 18px 4px 16px;
}
.cl-hero::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(245, 185, 66, .55) 20%, rgba(245, 185, 66, .55) 80%, transparent);
}
.cl-hero-titre { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.cl-hero-sur {
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: .32em; text-transform: uppercase; color: var(--accent);
}
.cl-hero h1 {
  margin: 0; font-family: var(--font-title); font-weight: 700; line-height: 1.05;
  font-size: clamp(26px, 3.2vw, 44px); letter-spacing: .04em;
  background: linear-gradient(180deg, #fff6d6 0%, #f5c55e 55%, #b98322 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 14px rgba(245, 185, 66, .22));
}
.cl-dates { margin: 2px 0 0; font-size: 13.5px; color: var(--ink-dim); }
/*  LE BLOC DE DROITE NE BOUGE PAS D'UNE VUE A L'AUTRE (Alexandre, 01/11/2026 :
 *  « l'affichage des éléments change entre cette semaine et semaine dernière »).
 *  La semaine en cours porte un compte a rebours large (trois cases + « avant
 *  la fin »), la semaine passee une simple pastille : le groupe changeait de
 *  largeur, passait a la ligne dans un cas et pas dans l'autre, et le
 *  commutateur sautait du bas-gauche au haut-droite. `margin-left: auto` le
 *  colle a droite quoi qu'il arrive, et `min-height` donne aux deux etats la
 *  meme hauteur : seul le contenu change, jamais la mise en page. */
.cl-hero-droite {
  display: flex; align-items: center; flex-wrap: wrap; gap: 14px 22px;
  flex: 0 0 auto; margin-left: auto; justify-content: flex-end;
}

.cl-compte { display: flex; align-items: center; gap: 8px; min-height: 52px; }
.cl-compte-case {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 58px; padding: 7px 8px 6px; border-radius: 12px;
  background: linear-gradient(180deg, rgba(30, 36, 54, .9), rgba(12, 15, 24, .95));
  border: 1px solid rgba(245, 185, 66, .28);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 6px 18px rgba(0, 0, 0, .35);
}
.cl-compte-case b {
  font-family: var(--font-title); font-size: 24px; line-height: 1; color: var(--ink-bright);
  font-variant-numeric: tabular-nums;
}
.cl-compte-case small {
  margin-top: 4px; font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
}
.cl-compte-lib { margin-left: 4px; font-size: 12.5px; color: var(--ink-dim); max-width: 7em; line-height: 1.2; }
.cl-compte.is-urgent .cl-compte-case { border-color: rgba(248, 113, 113, .5); }
.cl-compte.is-urgent .cl-compte-case b { color: #ffb4ad; }
.cl-compte.is-fini .cl-compte-lib {
  max-width: none; margin: 0; padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(12, 15, 24, .8); color: var(--ink-dim);
}

/* Le choix de la semaine, en commutateur. */
.cl-semaines {
  display: flex; gap: 2px; margin: 0; padding: 3px; border-radius: 999px;
  background: rgba(8, 10, 18, .8); border: 1px solid var(--line);
}
.cl-semaine {
  padding: 7px 14px; border: 0; border-radius: 999px; background: none;
  font-size: 12.5px; font-weight: 600; color: var(--ink-dim); cursor: pointer;
  transition: color .15s, background .15s;
}
/*  `button:hover:not(:disabled)` (0,2,1) repeignait le fond en bleu nuit sous
    l'encre sombre du bouton dore : illisible au survol. Meme poids + une
    classe pour gagner. */
.cl-semaine:hover:not(:disabled) {
  color: var(--ink-bright, #fff); background: rgba(255, 255, 255, .06);
  border: 0; box-shadow: none; transform: none;
}
.cl-semaine.is-on, .cl-semaine.is-on:hover:not(:disabled) {
  color: #1b1408; background: linear-gradient(180deg, #ffe39a, #f5b942 60%, #d79a2b);
  box-shadow: 0 2px 10px rgba(245, 185, 66, .3); transform: none;
}
.cl-semaine.is-on:hover:not(:disabled) { filter: brightness(1.06); }

/* Les trois colonnes. */
.cl-grille {
  display: grid; gap: 16px; align-items: stretch;
  /*  Les colonnes de cote grandissent avec l'ecran large (17 / 15 vw) au lieu
      de laisser tout le surplus au tableau du milieu. */
  grid-template-columns: minmax(290px, max(350px, 17vw)) minmax(0, 1fr) minmax(250px, max(310px, 15vw));
}
.cl-panneau {
  display: flex; flex-direction: column; gap: 14px; min-width: 0; min-height: 0;
  padding: 16px 18px 18px; border-radius: 18px;
  background: linear-gradient(165deg, rgba(22, 30, 48, .9) 0%, rgba(11, 14, 23, .96) 100%);
  border: 1px solid var(--line);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .42);
}
.cl-toi { border-color: rgba(245, 185, 66, .4); }
.cl-lbl {
  padding-bottom: 12px; border-bottom: 1px solid rgba(201, 162, 70, .18);
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: .3em; text-transform: uppercase; text-align: center; color: var(--accent);
}
.cl-panneau .cl-moi, .cl-panneau .cl-prix, .cl-panneau .cl-mesprix,
.cl-panneau .cl-table-boite, .cl-panneau .cl-regles {
  padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none;
}
.cl-panneau h3 { margin: 0 0 8px; font-family: var(--font-title); font-size: 13px; letter-spacing: .06em; color: var(--ink); }

/* Les ronds de joueur : le personnage, sinon l'initiale. */
.cl-avatar, .cl-moi-rond, .cl-pod-rond {
  flex: none; display: grid; place-items: center; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 35%, #2a3550, #121826);
}
.cl-avatar img, .cl-moi-rond img, .cl-pod-rond img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cl-initiale { font-family: var(--font-title); font-weight: 700; color: var(--ink-dim); }
.cl-adr { font-size: 11px; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cl-toi-pastille {
  flex: none; padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; color: #1b1408; background: var(--accent);
}

/* ── TOI ── */
.cl-moi-fiche { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }
.cl-moi-rond {
  width: 56px; height: 56px; border: 2px solid rgba(245, 185, 66, .55);
  box-shadow: 0 0 0 3px rgba(245, 185, 66, .1), 0 0 18px rgba(245, 185, 66, .2);
}
.cl-moi-rond .cl-initiale { font-size: 22px; }
.cl-moi-qui { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cl-moi-nom { font-family: var(--font-title); font-size: 15px; font-weight: 700; color: var(--ink-bright); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-moi-fiche .cl-moi-titre { margin: 0; font-size: 13px; color: var(--ink-dim); line-height: 1.35; }
.cl-moi-rang {
  display: flex; flex-direction: column; align-items: center; min-width: 58px; padding: 6px 8px;
  border-radius: 12px; border: 1px solid rgba(245, 185, 66, .3); background: rgba(245, 185, 66, .06);
}
.cl-moi-rang small { font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); }
.cl-moi-rang b { font-family: var(--font-title); font-size: 26px; line-height: 1.1; color: var(--ink-dim); }
.cl-moi-fiche.is-classe .cl-moi-rang b { color: var(--accent-light); }
.cl-moi-chiffres {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 12px;
}
.cl-moi-chiffres span {
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 4px;
  border-radius: 10px; background: rgba(255, 255, 255, .03); border: 1px solid rgba(120, 145, 190, .12);
}
.cl-moi-chiffres b { font-size: 15px; color: var(--ink-bright); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cl-moi-chiffres small { font-size: 10px; color: var(--ink-faint); letter-spacing: .06em; }
.cl-toi .cl-conditions { margin-top: 12px; }
.cl-toi .cl-mesprix { padding-top: 12px; border-top: 1px solid rgba(201, 162, 70, .14); }

/* Jouer : la couronne, puis les deux facons de lancer. */
.cl-panneau .cl-jouer {
  display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 14px;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(245, 185, 66, .14), transparent 60%),
    rgba(10, 12, 20, .6);
  border: 1px solid rgba(245, 185, 66, .38);
  box-shadow: inset 0 1px 0 rgba(255, 230, 160, .08), 0 0 26px rgba(245, 185, 66, .07);
}
.cl-jouer-tete { display: flex; align-items: center; justify-content: center; gap: 10px; }
.cl-couronne {
  display: block; width: 40px; height: 35px;
  background: center / contain no-repeat;   /* la couronne peinte : arene.css */
  filter: drop-shadow(0 0 8px rgba(245, 185, 66, .5));
}
.cl-jouer-tete b {
  font-family: var(--font-title); font-size: 12px; font-weight: 800;
  letter-spacing: .26em; text-transform: uppercase; color: var(--accent);
}
.cl-panneau .cl-jouer-boutons { display: flex; flex-direction: column; gap: 8px; margin: 0; }
.cl-panneau .cl-jouer-boutons button { flex: none; width: 100%; min-height: 46px; font-size: 15px; }
.cl-panneau .cl-jouer .cl-note, .cl-panneau .cl-jouer .cl-alerte { margin: 0; text-align: center; font-size: 11.5px; }

.cl-toi .cl-decks { margin: 0; padding-top: 12px; border-top: 1px solid rgba(201, 162, 70, .14); }
.cl-toi .cl-decks .cdk-titre { text-align: left; margin-bottom: 8px; }
.cl-toi .cl-decks .cdk-boutons button { flex: 1 1 auto; }

/* ── LE TABLEAU ── */
.cl-table-boite { display: flex; flex-direction: column; gap: 14px; min-height: 0; }

/* Le podium : 2 | 1 | 3, le 1er plus haut. */
.cl-podium {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end;
  gap: clamp(8px, 1.4vw, 18px); width: 100%; max-width: 780px; margin: 0 auto; padding-top: 6px;
}
.cl-pod { --m: var(--cl-or); --mc: var(--cl-or-clair); display: flex; flex-direction: column; align-items: center; min-width: 0; }
.cl-pod.r2 { --m: var(--cl-argent); --mc: var(--cl-argent-clair); }
.cl-pod.r3 { --m: var(--cl-bronze); --mc: var(--cl-bronze-clair); }
.cl-pod-haut {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  width: 100%; padding: 0 4px 10px; text-align: center; min-width: 0;
}
.cl-pod-couronne {
  display: block; width: 38px; height: 33px; margin-bottom: 2px;
  background: center / contain no-repeat;   /* la couronne peinte : arene.css */
  filter: drop-shadow(0 0 10px rgba(245, 185, 66, .6));
  animation: clCouronne 3.2s ease-in-out infinite;
}
@keyframes clCouronne { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
.cl-pod-anneau {
  position: relative; padding: 3px; border-radius: 50%; margin-bottom: 15px;
  background: conic-gradient(from 210deg, var(--mc), var(--m), color-mix(in srgb, var(--m) 45%, #000), var(--m), var(--mc));
  box-shadow: 0 0 22px color-mix(in srgb, var(--m) 40%, transparent);
}
.cl-pod-rond { width: 64px; height: 64px; border: 2px solid #0d1119; }
.cl-pod.r1 .cl-pod-rond { width: 84px; height: 84px; }
.cl-pod-rond .cl-initiale { font-size: 24px; }
.cl-pod-medaille {
  position: absolute; left: 50%; bottom: -15px; transform: translateX(-50%);
  display: grid; place-items: center; width: 38px; height: 33px; padding-bottom: 1px; box-sizing: border-box;
  font-size: 13px; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .6));
  background: center / contain no-repeat;   /* le medaillon au laurier du rang : arene.css */
}
.cl-pod-nom {
  max-width: 100%; font-family: var(--font-title); font-size: 15px; font-weight: 700; color: var(--ink-bright);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cl-pod.r1 .cl-pod-nom { font-size: 17px; }
.cl-pod-haut .cl-toi-pastille { margin-top: 3px; }
.cl-pod-socle {
  width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 4px;
  padding: 12px 8px 10px; border-radius: 14px 14px 6px 6px;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--m) 22%, transparent), color-mix(in srgb, var(--m) 4%, transparent) 70%),
    rgba(10, 13, 22, .7);
  border: 1px solid color-mix(in srgb, var(--m) 45%, transparent); border-bottom-color: transparent;
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--mc) 50%, transparent);
  min-height: 84px;
}
.cl-pod.r1 .cl-pod-socle { min-height: 112px; }
.cl-pod.r3 .cl-pod-socle { min-height: 70px; }
.cl-pod-xp { display: flex; align-items: baseline; gap: 4px; }
.cl-pod-xp b { font-family: var(--font-title); font-size: 24px; line-height: 1; color: var(--mc); font-variant-numeric: tabular-nums; }
.cl-pod.r1 .cl-pod-xp b { font-size: 30px; }
.cl-pod-xp small { font-size: 11px; color: var(--ink-faint); }
.cl-pod-vd { font-size: 12px; color: var(--ink-dim); white-space: nowrap; }
.cl-pod.is-vide .cl-pod-anneau { opacity: .35; }
.cl-pod.is-vide .cl-pod-nom { color: var(--ink-faint); font-weight: 400; font-size: 13px; }
.cl-pod.is-moi .cl-pod-socle { box-shadow: inset 0 1px 0 var(--mc), 0 0 0 1px var(--accent), 0 0 24px rgba(245, 185, 66, .2); }

/* Les lignes. */
.cl-table { display: flex; flex-direction: column; gap: 4px; min-height: 0; font-size: 13.5px; }
.cl-ligne {
  --cols: 44px minmax(0, 1.6fr) minmax(120px, 1.2fr) 52px 52px 70px 70px;
  display: grid; grid-template-columns: var(--cols); align-items: center; gap: 10px;
  padding: 7px 12px; border-radius: 12px;
  background: rgba(255, 255, 255, .025); border: 1px solid transparent;
  transition: background .15s, border-color .15s;
}
.cl-ligne:not(.cl-entete):hover { background: rgba(120, 145, 190, .08); border-color: rgba(120, 145, 190, .16); }
.cl-entete {
  position: sticky; top: 0; z-index: 3; padding-top: 6px; padding-bottom: 8px;
  background: #121828; border-radius: 0; border-bottom: 1px solid var(--line);
  font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
}
.cl-ligne > span { min-width: 0; font-variant-numeric: tabular-nums; }
.cl-ligne .cl-c-rang, .cl-ligne .cl-c-v, .cl-ligne .cl-c-d,
.cl-ligne .cl-c-temps, .cl-ligne .cl-c-prix { text-align: right; white-space: nowrap; }
.cl-ligne .cl-c-xp { text-align: right; }
.cl-ligne:not(.cl-entete) .cl-c-rang {
  justify-self: start; min-width: 30px; padding: 4px 6px; border-radius: 8px; text-align: center;
  font-weight: 700; color: var(--ink-dim); background: rgba(255, 255, 255, .04);
}
.cl-c-joueur { display: flex; align-items: center; gap: 10px; }
.cl-ligne .cl-avatar { width: 34px; height: 34px; border: 1px solid rgba(120, 145, 190, .3); }
.cl-avatar .cl-initiale { font-size: 14px; }
.cl-noms { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.cl-nom { color: var(--ink); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-ligne:not(.cl-entete) .cl-c-xp { display: flex; align-items: center; gap: 10px; }
.cl-barre {
  flex: 1 1 auto; height: 6px; border-radius: 99px; overflow: hidden; background: rgba(255, 255, 255, .06);
  position: relative;
}
.cl-barre::after {
  content: ''; position: absolute; inset: 0 auto 0 0; width: calc(var(--part, 0) * 100%); border-radius: inherit;
  background: linear-gradient(90deg, rgba(184, 127, 22, .7), var(--accent));
}
.cl-c-xp b { min-width: 3.2em; text-align: right; color: var(--ink-bright); font-weight: 700; }
.cl-ligne .cl-c-v { color: #8fe3bd; }
.cl-ligne .cl-c-d { color: #e7a3a0; }
.cl-entete .cl-c-v, .cl-entete .cl-c-d { color: var(--ink-faint); }
.cl-ligne .cl-c-temps { color: var(--ink-dim); }
.cl-rien { color: var(--ink-faint); }
.cl-paquets { display: inline-flex; align-items: center; gap: 4px; color: var(--accent-light); font-weight: 700; }
.cl-paquets img { width: 18px; height: 18px; object-fit: contain; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .6)); }
/* Ma ligne : doree, et collee en haut ou en bas quand elle sort de la vue. */
.cl-ligne.is-moi {
  position: sticky; top: 34px; bottom: 0; z-index: 2;
  background: linear-gradient(90deg, #2c2414, #1a1d27 70%); border-color: rgba(245, 185, 66, .45);
  box-shadow: 0 0 0 1px rgba(245, 185, 66, .12), 0 8px 20px rgba(0, 0, 0, .45);
}
.cl-ligne.is-moi .cl-c-rang { color: #1b1408; background: var(--accent); }
.cl-ellipse { text-align: center; color: var(--ink-faint); letter-spacing: .3em; line-height: 1; padding: 2px 0; }

/* ── LES PRIX ── */
.cl-echelle { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.cl-barreau {
  --m: rgba(120, 145, 190, .5);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 12px 9px 14px; border-radius: 12px; position: relative; overflow: hidden;
  background: rgba(255, 255, 255, .03); border: 1px solid rgba(120, 145, 190, .14);
}
.cl-barreau::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--m); }
.cl-barreau.r1 { --m: var(--cl-or); }
.cl-barreau.r2 { --m: var(--cl-argent); }
.cl-barreau.r3 { --m: var(--cl-bronze); }
.cl-barreau.is-podium {
  background: linear-gradient(90deg, color-mix(in srgb, var(--m) 16%, transparent), rgba(255, 255, 255, .02) 75%);
  border-color: color-mix(in srgb, var(--m) 35%, transparent);
}
.cl-barreau-rang { font-family: var(--font-title); font-size: 14px; font-weight: 700; color: var(--ink-dim); white-space: nowrap; }
.cl-barreau.is-podium .cl-barreau-rang { color: var(--m); font-size: 16px; }
.cl-barreau-prix { display: flex; align-items: baseline; gap: 6px; }
.cl-barreau-prix small { font-size: 11px; color: var(--ink-faint); }
.cl-paquets.is-grand { align-self: center; }
.cl-paquets.is-grand b { font-size: 16px; }
.cl-barreau.r1 .cl-paquets.is-grand b { font-size: 20px; }
.cl-barreau.r1 .cl-paquets.is-grand img { width: 26px; height: 26px; }
/* Le prix en images (25/10/2026) : boosters, passe, cristaux d'ame et d'arcane. */
.cl-lot { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; flex-wrap: wrap; }
.cl-lot.is-grand { gap: 8px; }
.cl-passe {
  font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
  color: #1b1408; background: linear-gradient(180deg, #ffd98a, var(--accent)); padding: 2px 7px; border-radius: 999px;
}
.cl-lot.is-grand .cl-passe { font-size: 10.5px; padding: 3px 8px; }
.cl-cristaux { display: inline-flex; align-items: center; gap: 3px; color: var(--ink); font-weight: 700; white-space: nowrap; }
.cl-cristaux b { margin-right: 3px; }
.cl-cristaux b:last-child { margin-right: 0; }
.cl-cristal { width: 16px; height: 16px; object-fit: contain; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); }
.cl-lot.is-grand .cl-cristal { width: 20px; height: 20px; }
.cl-cristal-paire { display: inline-flex; }
.cl-cristal-paire .cl-cristal + .cl-cristal { margin-left: -7px; }
.cl-barreau-rang small { display: block; font-family: var(--font-body, inherit); font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); }
.cl-barreau.is-participation { border-style: dashed; }
.cl-rail .cl-prix .cl-note { margin-top: 10px; font-size: 11.5px; }
.cl-rail .cl-saison { margin-top: 0; flex-direction: column; align-items: stretch; text-align: left; }
.cl-rail .cl-saison p { flex: none; }
.cl-rail .cl-saison-btn { justify-self: stretch; }
.cl-rail .cl-regles { padding-top: 12px; border-top: 1px solid rgba(201, 162, 70, .14); }

.cl-panneau ::-webkit-scrollbar { width: 6px; }
.cl-panneau ::-webkit-scrollbar-thumb { background: rgba(201, 162, 70, .35); border-radius: 6px; }

/* Ordinateur : la page tient dans l'ecran, les colonnes defilent seules. */
@media (min-width: 1200px) and (min-height: 680px) {
  body:has(#view-classement.is-on .cl-page) { overflow: hidden; }
  body:has(#view-classement.is-on .cl-page) main { padding-top: 6px; padding-bottom: 12px; }
  #view-classement.is-on:has(.cl-page) { height: calc(100dvh - var(--topbar-h) - 18px); min-height: 0; }
  #view-classement .cl-page { height: 100%; padding-bottom: 0; }
  .cl-grille { flex: 1 1 auto; min-height: 0; }
  .cl-panneau { overflow: hidden; }
  /*  Le podium defile avec les lignes : sur un ecran bas, il cede la
      place au tableau au lieu de l'ecraser. L'en-tete reste colle. */
  .cl-toi, .cl-rail, .cl-table-boite {
    overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(201, 162, 70, .4) transparent;
  }
  .cl-table-boite { flex: 1 1 auto; padding-right: 4px; }
}
/* Ecran bas (portable 768) : bandeau et podium tasses. */
/*  Au large, le bandeau tient sur une seule ligne : le titre a gauche, le
 *  compte a rebours et le commutateur a droite, a la meme place les deux
 *  semaines. */
@media (min-width: 900px) {
  .cl-hero { flex-wrap: nowrap; }
  .cl-compte { min-height: 60px; }
}
@media (min-width: 900px) and (max-height: 900px) {
  .cl-hero { padding: 8px 4px 10px; }
  .cl-hero h1 { font-size: clamp(24px, 2.4vw, 34px); }
  .cl-compte-case { min-width: 50px; padding: 5px 6px 4px; }
  .cl-compte-case b { font-size: 20px; }
  .cl-page { gap: 12px; }
  .cl-pod-couronne { width: 32px; height: 28px; }
  .cl-pod-rond { width: 50px; height: 50px; }
  .cl-pod.r1 .cl-pod-rond { width: 64px; height: 64px; }
  .cl-pod-haut { padding-bottom: 6px; }
  .cl-pod-socle { min-height: 62px; padding: 8px 8px 6px; }
  .cl-pod.r1 .cl-pod-socle { min-height: 80px; }
  .cl-pod.r3 .cl-pod-socle { min-height: 50px; }
  .cl-pod-xp b { font-size: 20px; }
  .cl-pod.r1 .cl-pod-xp b { font-size: 24px; }
}
/* Petit ordinateur, tablette couchee : TOI et LES PRIX a gauche, le tableau a droite. */
@media (min-width: 900px) and (max-width: 1199px) {
  .cl-grille { grid-template-columns: minmax(280px, 330px) minmax(0, 1fr); grid-template-areas: 'toi tab' 'rail tab'; align-items: start; }
  .cl-toi { grid-area: toi; }
  .cl-tableau-p { grid-area: tab; }
  .cl-rail { grid-area: rail; }
  .cl-ligne { --cols: 40px minmax(0, 1.5fr) minmax(100px, 1fr) 44px 44px 64px 60px; }
}
@media (min-width: 1200px) and (max-width: 1499px) {
  .cl-grille { grid-template-columns: minmax(280px, 320px) minmax(0, 1fr) minmax(230px, 270px); }
  .cl-ligne { --cols: 40px minmax(0, 1.5fr) minmax(90px, 1fr) 44px 44px 64px 60px; gap: 8px; }
}
/* Tablette debout, telephone : tout l'un sous l'autre, le geste d'abord. */
@media (max-width: 899px) {
  .cl-grille { grid-template-columns: minmax(0, 1fr); }
  .cl-hero { padding-top: 12px; }
  .cl-hero-droite { width: 100%; justify-content: space-between; }
}
@media (max-width: 700px) {
  .cl-page { padding: 0 10px 90px; gap: 12px; }
  .cl-panneau { padding: 14px 12px 16px; }
  .cl-compte-case { min-width: 48px; padding: 6px 6px 5px; }
  .cl-compte-case b { font-size: 20px; }
  .cl-compte-lib { display: none; }
  .cl-pod-rond { width: 52px; height: 52px; }
  .cl-pod.r1 .cl-pod-rond { width: 66px; height: 66px; }
  .cl-pod-nom, .cl-pod.r1 .cl-pod-nom { font-size: 13px; }
  .cl-pod-haut .cl-adr { display: none; }
  .cl-pod-xp b { font-size: 19px; }
  .cl-pod.r1 .cl-pod-xp b { font-size: 23px; }
  .cl-tableau-p { padding-left: 8px; padding-right: 8px; }
  .cl-ligne { --cols: 28px minmax(0, 1fr) 48px 30px 46px; gap: 6px; padding: 7px 8px; }
  .cl-ligne .cl-c-temps, .cl-ligne .cl-c-d { display: none; }
  .cl-entete { font-size: 9.5px; letter-spacing: .08em; }
  .cl-c-joueur { gap: 8px; }
  .cl-ligne .cl-barre { display: none; }
  .cl-ligne .cl-avatar { width: 28px; height: 28px; }
  .cl-ligne .cl-adr { display: none; }
  .cl-ligne .cl-cristal { width: 13px; height: 13px; }
  .cl-ligne .cl-cristal-paire .cl-cristal + .cl-cristal { margin-left: -6px; }
  .cl-ligne .cl-cristaux { font-size: 12px; gap: 2px; }
  .cl-ligne.is-moi { top: 30px; }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .cl-pod-couronne { animation: none; } }


/* ══ LE CHOIX DU DECK AVANT UNE PARTIE (main.js, choixDuDeck) ═══════════════
   Solo, En ligne, Classement : une tuile par deck -- boite, nom, force, et le
   plateau et le de qu'on emporte a table avec lui. */
body.play-on .no-match {
  width: min(1080px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100% - 32px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(201, 162, 70, .45) transparent;
  padding: 28px 24px 24px;
}
.no-match h1 { margin: 8px 0 6px; }
.no-match > p { margin: 0 0 18px; }
.cdk { text-align: center; }
.cdk-grille {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, 220px);
  justify-content: center;
  margin: 0 auto 16px; max-width: 1040px;
}
.cdk-deck {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 10px 12px; border-radius: 14px; cursor: pointer;
  font: inherit; color: inherit; text-align: center;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .08);
  transition: transform .16s, border-color .16s, background .16s, box-shadow .16s;
}
.cdk-deck:hover:not(:disabled) { transform: translateY(-3px); border-color: #c9a246; background: rgba(245, 185, 66, .07); }
.cdk-deck:focus-visible { outline: 2px solid #e8c25a; outline-offset: 3px; }
.cdk-deck.is-on {
  border-color: #e8c25a; background: rgba(245, 185, 66, .09);
  box-shadow: inset 0 0 0 1px rgba(232, 194, 90, .55), 0 0 22px rgba(232, 194, 90, .18);
}
.cdk-deck:disabled { cursor: not-allowed; opacity: .45; }
.cdk-deck.is-on:disabled { opacity: 1; cursor: default; }
.cdk-boite { position: relative; width: 150px; height: 150px; display: grid; place-items: center; }
.cdk-offert {
  position: absolute; top: 0; right: 0;
  font: 800 9.5px/1 var(--font-num, sans-serif); letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 999px;
  background: rgba(120, 190, 140, .9); color: #0c1a10;
}
.cdk-nom {
  max-width: 100%; font-family: var(--font-title); font-size: 15px; color: #fff3d6;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cdk-force { display: flex; align-items: baseline; gap: 6px; font-size: 12px; color: var(--ink-dim, #b9b2a4); }
.cdk-force small { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: #c9a246; }
.cdk-force b { font: 800 17px/1 var(--font-num, sans-serif); color: #ffe3a0; }
.cdk-force i { font-style: normal; font-size: 11px; }
.cdk-kit {
  display: grid; grid-template-columns: minmax(0, 1fr) 64px; gap: 8px; align-items: center;
  width: 100%; margin-top: 2px; padding-top: 8px;
  border-top: 1px solid rgba(201, 162, 70, .16);
}
.cdk-plateau, .cdk-de { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 0; }
.cdk-kit small {
  max-width: 100%; font-size: 10.5px; color: var(--ink-faint, #8b8577);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cdk-plateau-vue {
  display: block; width: 100%; aspect-ratio: 16 / 10; border-radius: 6px;
  background: #0a0708 center / cover no-repeat;
  border: 1px solid rgba(255, 255, 255, .08);
}
.cdk-de img { display: block; width: 46px; height: 46px; object-fit: contain; }
.cdk-neuf { justify-content: center; border-style: dashed; min-height: 200px; }
.cdk-neuf-plus {
  display: grid; place-items: center; width: 54px; height: 54px; border-radius: 50%;
  font-size: 30px; line-height: 1; color: #e8c25a;
  border: 1px solid rgba(232, 194, 90, .45);
}
.cdk-neuf-txt { font-size: 11.5px; color: var(--ink-faint, #8b8577); }
.cdk-pied { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cdk-raison { margin: 0; font-size: 13px; color: #e6a070; }
.cdk-boutons { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
#multi-decks { margin: 0 auto 18px; max-width: 1040px; }
.cl-decks { margin: 10px 0 14px; }
@media (max-width: 700px) {
  .cdk-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .cdk-boite { width: 120px; height: 120px; }
  .cdk-boite .bib-scene { width: 120px; height: 120px; }
  .cdk-boite .bib-scene .cof3d-plan { transform: scale(.12); }
  .cdk-de img { width: 36px; height: 36px; }
  body.play-on .no-match { padding: 20px 12px 16px; }
}
/*  Le titre du choix, au salon : « Ton deck » avant, « Changer de deck » dedans. */
.cdk-titre {
  margin: 0 0 10px;
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: .28em; text-transform: uppercase; color: #c9a246;
}
/*  LA VARIANTE COMPACTE : la colonne du Classement n'a pas la place d'une
    tuile. Boite, nom et force, puis plateau et de en miniature. */
.cdk-compact .cdk-grille { grid-template-columns: 1fr; gap: 8px; margin-bottom: 12px; }
.cdk-compact .cdk-deck {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto;
  grid-template-rows: auto auto; column-gap: 10px; row-gap: 2px;
  align-items: center; padding: 8px 10px; text-align: left;
}
.cdk-compact .cdk-deck:hover:not(:disabled) { transform: none; }
.cdk-compact .cdk-boite {
  grid-row: 1 / 3; width: 64px; height: 64px; overflow: hidden; display: block;
}
.cdk-compact .cdk-boite .bib-scene {
  position: absolute; left: 0; top: 0;
  transform: scale(.4267); transform-origin: 0 0;
}
.cdk-compact .cdk-boite .bib-actif,
.cdk-compact .cdk-boite .bib-els { display: none; }
.cdk-compact .cdk-boite .bib-incomplet,
.cdk-compact .cdk-offert { font-size: 7.5px; padding: 2px 5px; }
.cdk-compact .cdk-nom { align-self: end; font-size: 14px; }
.cdk-compact .cdk-force { align-self: start; }
.cdk-compact .cdk-kit {
  grid-column: 3; grid-row: 1 / 3;
  display: flex; gap: 6px; width: auto; margin: 0; padding: 0; border: 0;
}
.cdk-compact .cdk-kit small { display: none; }
.cdk-compact .cdk-plateau-vue { width: 52px; }
.cdk-compact .cdk-de img { width: 30px; height: 30px; }
.cdk-compact .cdk-neuf {
  display: flex; flex-direction: row; justify-content: flex-start; gap: 10px;
  min-height: 0; padding: 8px 10px;
}
.cdk-compact .cdk-neuf-plus { width: 34px; height: 34px; font-size: 20px; }
.cdk-compact .cdk-neuf-txt { display: none; }
.cdk-compact .cdk-pied { align-items: stretch; }
.cdk-compact .cdk-boutons button { flex: 1 1 auto; }
.cdk-compact .cdk-neuf .cdk-nom { align-self: center; }

/* ══ LE MULTIJOUEUR : UNE SCENE, TROIS COLONNES (Alexandre, 04/10/2026) ════
   TOI | VS | TON ADVERSAIRE. Deux panneaux qui se font face, et entre eux le
   geste commun. Les fiches et la porte n'ont plus de cadre a elles : le
   panneau en est un, deux cadres l'un dans l'autre ne font que du bruit. */
#view-multi .multi {
  max-width: 1240px; margin: 0 auto; padding: 0 0 20px;
  display: flex; flex-direction: column; gap: 14px;
}
#view-multi .multi-head { gap: 2px; }
#view-multi .multi-title { font-size: clamp(24px, 3vw, 32px); }
.mp-scene {
  display: grid; align-items: stretch;
  grid-template-columns: minmax(0, 1fr) 168px minmax(0, 1fr); gap: 0 18px;
}
.mp-panneau {
  display: flex; flex-direction: column; gap: 14px; min-width: 0; min-height: 0;
  padding: 16px 20px 20px; border-radius: 18px;
  background: linear-gradient(165deg, rgba(22, 30, 48, .9) 0%, rgba(11, 14, 23, .96) 100%);
  border: 1px solid var(--line);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .42);
}
.mp-toi { border-color: rgba(245, 185, 66, .4); }
.mp-lbl {
  padding-bottom: 12px; border-bottom: 1px solid rgba(201, 162, 70, .18);
  font-family: var(--font-title); font-size: 11px; font-weight: 800;
  letter-spacing: .3em; text-transform: uppercase; text-align: center; color: var(--accent);
}
.mp-panneau .multi-profil { align-items: stretch; }
.mp-panneau .dl-carte,
.mp-panneau .multi-profil .dl-carte {
  width: auto; padding: 0; border: 0; background: none; box-shadow: none;
}
.mp-panneau .dl-carte.attend { min-height: 150px; border: 1px dashed var(--line); border-radius: 14px; padding: 16px; }
.mp-panneau #multi-decks { margin: 0; max-width: none; }
.mp-panneau #multi-decks .cdk-titre { text-align: left; margin-bottom: 8px; }

/* Le centre : le VS, et ce qui se decide a deux. */
.mp-centre {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; min-width: 0;
}
.mp-centre .salon-versus span { width: 76px; height: 76px; font-size: 26px; }
.mp-centre #salon-pret { width: 100%; padding-left: 8px; padding-right: 8px; }
.mp-centre .salon-message { max-width: 168px; font-size: 12px; line-height: 1.45; }

/* La porte : ouvrir, un filet, rejoindre. */
.mp-duel .salon-porte {
  display: flex; flex-direction: column; justify-content: center; gap: 0; flex: 1 1 auto;
}
.mp-duel .porte-carte {
  padding: 16px 8px; background: none; border: 0; box-shadow: none;
}
.mp-duel .porte-ou { flex-direction: row; padding: 4px 0; }
.mp-duel .porte-ou::before, .mp-duel .porte-ou::after {
  width: auto; height: 1px; min-height: 0; flex: 1 1 auto;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}
.mp-note { margin: 10px 0 0; font-size: 11px; color: var(--ink-faint); text-align: center; }

/* Le salon : le code, l'autre, son deck, puis la discussion. */
.mp-duel .salon-etat {
  display: flex; flex-direction: column; align-items: stretch; gap: 14px;
  flex: 1 1 auto; min-height: 0;
}
.mp-duel .salon-etat[hidden] { display: none; }
.mp-salon-tete { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.mp-salon-tete .salon-code-vitre { flex-direction: row; align-items: center; gap: 12px; padding: 8px 12px 8px 16px; }
.mp-salon-tete .salon-code-vitre b { font-size: 24px; }
.mp-salon-tete .salon-copier { position: static; transform: none; }
.mp-son-deck { display: flex; justify-content: center; }
.mp-son-deck[hidden] { display: none; }
.mp-son-deck .deck-nu-boite, .mp-son-deck .bib-scene { width: 120px; height: 120px; }
.mp-son-deck .bib-scene .cof3d-plan { transform: scale(.12); }
.mp-duel .salon-chat { flex: 1 1 auto; min-height: 150px; padding: 12px; }
.mp-duel .chat-fil { flex: 1 1 auto; height: auto; min-height: 70px; }

/* Ordinateur : rien ne defile, la liste des decks et la discussion
   prennent la hauteur qui reste. */
@media (min-width: 900px) and (min-height: 640px) {
  body.multi-on { overflow: hidden; }
  body.multi-on main { padding-top: 12px; padding-bottom: 12px; }
  body.multi-on #view-multi.is-on { height: calc(100dvh - var(--topbar-h) - 24px); }
  #view-multi .multi { height: 100%; padding: 0; }
  .mp-scene { flex: 1 1 auto; min-height: 0; }
  .mp-panneau { overflow: hidden; }
  .mp-panneau #multi-decks {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 4px;
    scrollbar-width: thin; scrollbar-color: rgba(201, 162, 70, .4) transparent;
  }
}

/* Tablette debout, telephone : les trois l'un sous l'autre, le VS en bande. */
@media (max-width: 899px) {
  .mp-scene { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .mp-centre { flex-direction: row; flex-wrap: wrap; padding: 12px 0; }
  .mp-centre .salon-versus span { width: 48px; height: 48px; font-size: 17px; }
  .mp-centre #salon-pret { width: auto; flex: 1 1 160px; }
  .mp-centre .salon-message { max-width: none; flex: 1 1 100%; }
  .mp-panneau { padding: 14px 14px 16px; }
}
.mp-salon-tete .salon-code-lbl { white-space: nowrap; }

/*  La ligne de force ne passe pas sous le plateau : elle se coupe. */
.cdk-compact .cdk-force { min-width: 0; white-space: nowrap; overflow: hidden; }
.cdk-compact .cdk-force i { overflow: hidden; text-overflow: ellipsis; }
/* ── LE RETOUR DE PAY STATION (main.js accueillirRetourAchat) ─────────────
   A la place de la page blanche d'Xsolla : le grimoire respire dans son aura
   pendant que les trois temps se cochent, puis la fete d'achat prend le
   relais. */
.achat-retour {
  position: fixed; inset: 0; z-index: 139; display: grid; place-items: center; padding: 16px;
}
.ar-voile {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 30%, rgba(255, 194, 74, .16), rgba(3, 4, 10, .94) 62%);
  backdrop-filter: blur(10px);
  animation: af-fondu .8s ease both;
}
.ar-carte {
  position: relative; width: min(420px, 100%); padding: 28px 24px 22px; text-align: center;
  border: 1px solid var(--line-gold, rgba(255, 194, 74, .35)); border-radius: 18px;
  background: linear-gradient(180deg, rgba(28, 24, 18, .92), rgba(10, 11, 18, .96));
  box-shadow: 0 20px 60px rgba(0, 0, 0, .55), 0 0 60px rgba(255, 194, 74, .12);
  animation: ar-monte .7s cubic-bezier(.22, .8, .24, 1) both;
}
@keyframes ar-monte { from { opacity: 0; transform: translateY(18px) scale(.97); } }
.ar-grimoire {
  width: 128px; height: 128px; object-fit: contain; margin: -4px auto 6px; display: block;
  filter: drop-shadow(0 0 22px rgba(255, 194, 74, .55));
  animation: ar-respire 2.4s ease-in-out infinite;
}
@keyframes ar-respire {
  50% { transform: translateY(-5px) scale(1.03); filter: drop-shadow(0 0 34px rgba(255, 194, 74, .8)); }
}
.ar-titre {
  font-family: 'Cinzel', serif; font-weight: 700; font-size: 26px; margin: 0 0 16px;
  color: #ffc24a; letter-spacing: .02em;
}
.ar-etapes { list-style: none; margin: 0 auto 14px; padding: 0; display: grid; gap: 10px; text-align: left; width: fit-content; }
.ar-etapes li {
  position: relative; padding-left: 30px; font-size: 15px; color: var(--ink-dim, #a9adbd);
  transition: color .4s ease;
}
.ar-etapes li::before {
  content: ''; position: absolute; left: 0; top: 50%; width: 18px; height: 18px; margin-top: -9px;
  border-radius: 50%; border: 2px solid rgba(255, 255, 255, .18); box-sizing: border-box;
}
.ar-etapes li.is-cours { color: var(--ink-bright, #fff); }
.ar-etapes li.is-cours::before {
  border-color: rgba(255, 194, 74, .25); border-top-color: #ffc24a;
  animation: ar-tourne .9s linear infinite;
}
@keyframes ar-tourne { to { transform: rotate(360deg); } }
.ar-etapes li.is-fait { color: var(--ink-bright, #fff); }
.ar-etapes li.is-fait::before { border-color: #3ddc97; background: #3ddc97; }
.ar-etapes li.is-fait::after {
  content: ''; position: absolute; left: 6px; top: 50%; width: 5px; height: 9px; margin-top: -6px;
  border: solid #0b0d14; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.ar-note { font-size: 13px; color: var(--ink-faint, #7d8194); margin: 0 0 14px; line-height: 1.45; }
.ar-fermer { min-width: 120px; }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .ar-grimoire, :where(html:not(.mouvement-plein)) .ar-etapes li.is-cours::before, :where(html:not(.mouvement-plein)) .ar-carte { animation: none; }
}

/* ── SUPPRIMER SON PROFIL (fenetre du profil) : discret, sous les boutons ── */
.pm-supprimer-bloc { margin-top: 18px; padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, .08); text-align: center; }
.pm-supprimer {
  background: none; border: 0; padding: 4px 8px; cursor: pointer;
  font-size: 12.5px; color: var(--ink-faint, #7d8194); text-decoration: underline; text-underline-offset: 3px;
}
.pm-supprimer:hover, .pm-supprimer:focus-visible { color: #ff7a7a; }

/* ── LE PRIX EN USDC (Marche, 05/10/2026) ──────────────────────────────────
   Le champ de mise en vente n'a AUCUN exemple de prix : le suffixe dit la
   monnaie, la ligne d'aide dit que le prix est libre, et elle ne parle de
   minimum que si la saisie le franchit. */
.ma-prix-champ {
  display: flex; align-items: stretch;
  border: 1px solid rgba(245, 185, 66, .35); border-radius: 10px; overflow: hidden;
  background: rgba(0, 0, 0, .25);
}
.ma-prix-champ:focus-within { border-color: #f5b942; box-shadow: 0 0 0 3px rgba(245, 185, 66, .18); }
.ma-prix-lab .ma-prix-champ input {
  flex: 1; min-width: 0; border: 0; border-radius: 0; background: transparent; outline: none;
  font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0;
}
.ma-prix-devise {
  display: grid; place-items: center; padding: 0 14px;
  font-size: 13px; font-weight: 700; letter-spacing: .08em; color: #f5b942;
  background: rgba(245, 185, 66, .08); border-left: 1px solid rgba(245, 185, 66, .25);
}
.ma-prix-aide { margin: 6px 0 0; font-size: 12.5px; color: var(--ink-faint, #8d86a0); }
.ma-prix-aide.est-erreur { color: #ff8a7a; }
.ma-prix-ancien { font-size: 12px; font-weight: 600; color: #ff8a7a; }

/*  Le deck offert pas encore reclame : le bouton du pied, aux couleurs de la
    pastille « Offert ». */
.cdk-boutons .cdk-cadeau { border-color: rgba(120, 190, 140, .7); background: rgba(40, 90, 55, .55); color: #d6f5df; }
.cdk-boutons .cdk-cadeau:hover:not(:disabled) { border-color: rgba(150, 220, 170, .95); }

/* ══ L'ACCUEIL QUI VEND (07/10/2026) ═══════════════════════════════════════
   Tuile 1 : une promesse, une porte gratuite, une porte d'achat, et une vraie
   partie qui tourne a cote. Tuile 2 : la BOUTIQUE, nommee, avec ses prix et
   le ×2 du premier Legend en tete -- c'est l'argument du modele. En fin de
   feuille pour primer sur les couches precedentes ; le telephone est dans
   mobile.css. */
.hero-title { font-size: clamp(30px, 3.2vw, 42px); letter-spacing: .04em; margin-top: 2px; }
.hero-promesse {
  margin: 10px 0 0; max-width: 560px;
  font-family: var(--font-title); font-weight: 900; line-height: 1.12;
  font-size: clamp(28px, 3vw, 44px); color: #fff4d6;
  text-shadow: 0 4px 24px rgba(0, 0, 0, .6);
}
.hero-promesse em {
  font-style: normal;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.home-tag { margin: 14px 0 22px; font-size: 16px; max-width: 520px; }

/* La porte d'achat : vive, mais un cran sous la porte gratuite. */
.btn-hero-boutique {
  color: #fff; border: 0;
  background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 60%, #ffb44a 100%);
  box-shadow: 0 8px 24px rgba(255, 80, 90, .35), inset 0 1px 0 rgba(255, 255, 255, .35);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}
.btn-hero-boutique:hover:not(:disabled) {
  background: linear-gradient(135deg, #ff3d6e 0%, #ff7a3d 60%, #ffb44a 100%);
  transform: translateY(-2px); box-shadow: 0 12px 30px rgba(255, 80, 90, .5), inset 0 1px 0 rgba(255, 255, 255, .35);
}
.hero-tuto {
  display: block; margin-top: 8px; padding: 0; border: 0; background: none;
  font: inherit; font-size: 13px; font-weight: 700; color: var(--accent-light, #ffe08a);
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(245, 185, 66, .45);
}
.hero-tuto:hover { color: #fff; text-decoration-color: currentColor; }

/* ── La partie qui tourne, et les six Anomalies devant ── */
.hero-cards-stage { align-items: center; }
.hero-jeu {
  position: relative; width: min(100%, 500px); aspect-ratio: 1; border-radius: 18px; overflow: hidden;
  background: #170807 url("https://medias.kairostcg.com/fonds/jeu_partie_v2.webp") center / cover no-repeat;
  border: 1px solid var(--line-gold);
  box-shadow: 0 22px 60px rgba(0, 0, 0, .75), 0 0 40px rgba(245, 185, 66, .12), inset 0 0 0 1px rgba(255, 240, 180, .08);
}
.hero-jeu video { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ── LA BOUTIQUE ── */
.home-booster-altar .altar-appel { max-width: 940px; gap: 14px; }
/* « Acheter des paquets » amene ici : le haut de la tuile sous la barre. */
#home-booster-altar { scroll-margin-top: calc(var(--topbar-h, 72px) + 12px); }
.home-booster-altar .appel-titre { font-size: clamp(30px, 3vw, 40px); }

.boutique-paiement { margin: 0; max-width: 620px; font-size: 12px; color: var(--ink-dim); opacity: .85; }

.vitrine-titre {
  margin-top: 10px; font-family: var(--font-title); font-size: 11px; font-weight: 900;
  letter-spacing: .22em; text-transform: uppercase; color: var(--accent);
}
.home-booster-altar .vitrine-raretes { margin-top: 0; }

/* L'onglet de la boutique : en or, pour se distinguer du Marche. */
.tabs .tab-boutique .tab-text { color: #ffd36b; }
/* Son icone : sans elle, le masque des onglets (tablette) peignait un carre plein. */
.tabs .tab-boutique { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8h14l-1 12H6z'/%3E%3Cpath d='M9 8V6a3 3 0 0 1 6 0v2'/%3E%3C/svg%3E"); color: #ffd36b; }


/*  La boutique est une COLONNE : le titre, le ×2, les trois prix, puis la
    vitrine. La grille « livre a gauche, accroche a droite » du 26/09 (plus
    haut) servait l'ancien autel ; elle est levee ici. */
@media (min-width: 701px) {
  .home-booster-altar {
    display: flex; flex-direction: column; align-items: center; text-align: center;
  }
  .home-booster-altar .altar-appel {
    display: flex; flex-direction: column; align-items: center; width: 100%;
  }
  .home-booster-altar .appel-ligne { max-width: 640px; }
  .home-booster-altar .appel-kicker { align-self: center; }
  .home-booster-altar .altar-invite { display: inline; }
}

/* ══ LA BOUTIQUE, TROIS OFFRES, TROIS PILES (08/10/2026) ═══════════════════
   Le grimoire dit la quantite : 1, 3, une pile. Le Legend au centre, plus
   grand, seul a porter le ×2. Les cartes ont la meme hauteur, le bouton en
   bas de chacune. */
.boutique-offres {
  width: 100%; max-width: 920px; margin-top: 18px; display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 16px; align-items: stretch;
}
.bo-offre {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 22px 16px 18px; border-radius: 18px; text-align: center; overflow: visible;
  /* Un projecteur fixe, teinte du rang, tombe sur le livre ; le reste est sombre. */
  background:
    radial-gradient(ellipse 75% 42% at 50% 24%, color-mix(in srgb, var(--aura) 20%, transparent), transparent 72%),
    linear-gradient(180deg, color-mix(in srgb, var(--aura) 9%, #15121c), #0c0a10 70%);
  border: 1px solid color-mix(in srgb, var(--aura) 45%, rgba(255, 255, 255, .08));
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--aura) 35%, transparent), 0 14px 32px rgba(0, 0, 0, .5);
  transition: transform .3s cubic-bezier(.16, 1, .3, 1), box-shadow .3s;
}
.bo-offre:hover {
  transform: translateY(-4px);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--aura) 50%, transparent), 0 18px 40px rgba(0, 0, 0, .6),
    0 0 28px color-mix(in srgb, var(--aura) 22%, transparent);
}
.bo-offre.is-legend {
  padding-top: 28px; margin: -10px 0; border: 2px solid transparent;
  background:
    radial-gradient(ellipse 80% 45% at 50% 24%, rgba(255, 178, 80, .26), transparent 72%) padding-box,
    linear-gradient(175deg, #241a0d, #0f0b07) padding-box,
    linear-gradient(135deg, #ffe699, #c8871e 45%, #ff7a5c 75%, #ffe699) border-box;
  box-shadow: 0 0 46px rgba(245, 185, 66, .25), 0 18px 40px rgba(0, 0, 0, .55);
}
.bo-offre.is-legend:hover { box-shadow: 0 0 56px rgba(245, 185, 66, .35), 0 22px 44px rgba(0, 0, 0, .6); }
.bo-ruban {
  position: absolute; top: -13px; left: 50%; transform: translateX(-50%); white-space: nowrap; z-index: 3;
  padding: 5px 14px; border-radius: 99px; font-size: 11px; font-weight: 900; letter-spacing: .14em;
  background: linear-gradient(135deg, #ffe08a, #ff8a5c); color: #1a0d05;
  box-shadow: 0 4px 14px rgba(255, 110, 80, .45);
}

/* UN GRIMOIRE PAR OFFRE (08/10/2026) : la taille et la couleur disent le
   rang. Starter bleu et petit, Adept violet, Legend or et le plus grand.
   L'aura (--aura, posee par main.js depuis FORFAITS) teinte le socle et
   l'ombre du livre.
   LA LUMIERE NE BOUGE PLUS (08/10/2026) : le halo flou qui pulsait derriere
   chaque livre faisait trois taches baveuses qui respiraient. Le livre est
   pose sur un socle de lumiere fixe. La zone du livre a la MEME hauteur
   dans les trois offres : les noms, les quantites et les prix s'alignent. */
.bo-pile {
  --w: 104px; --h: 176px; position: relative; width: 100%; height: var(--h);
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 12px;
}
.bo-adept .bo-pile { --w: 122px; }
.bo-offre.is-legend .bo-pile { --w: 150px; --h: 196px; }
.bo-pile::before {
  content: ""; position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%);
  width: calc(var(--w) * 1.35); height: 26px; border-radius: 50%;
  background: radial-gradient(ellipse at center, color-mix(in srgb, var(--aura) 70%, transparent), color-mix(in srgb, var(--aura) 18%, transparent) 45%, transparent 72%);
}
.bo-pile img {
  position: relative; width: var(--w); height: calc(var(--w) * 1.1); object-fit: contain;
  filter: drop-shadow(0 10px 10px rgba(0, 0, 0, .7)) drop-shadow(0 0 10px color-mix(in srgb, var(--aura) 45%, transparent));
  transition: transform .35s cubic-bezier(.16, 1, .3, 1);
}
.bo-offre:hover .bo-pile img { transform: translateY(-6px) scale(1.04); }
.bo-sceau {
  position: absolute; right: calc(50% - var(--w) * .78); top: calc(var(--h) - 18px - var(--w) * 1.1); z-index: 2; width: 62px; height: 62px; border-radius: 50%;
  display: grid; place-items: center; transform: rotate(10deg);
  font-family: var(--font-title); font-size: 25px; font-weight: 900; color: #1a0d05;
  background: radial-gradient(circle at 35% 30%, #fff1c2, #ffc371 45%, #ff5f6d 100%);
  box-shadow: 0 0 0 3px rgba(255, 230, 160, .35), 0 6px 22px rgba(255, 95, 109, .65);
  animation: bx2-pouls 2.4s ease-in-out infinite;
}
@keyframes bx2-pouls { 50% { transform: rotate(10deg) scale(1.08); } }

.bo-corps { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; flex: 1; }
.bo-nom { font-family: var(--font-title); font-size: 19px; font-weight: 900; letter-spacing: .03em; color: var(--ink); }
.bo-offre.is-legend .bo-nom {
  font-size: 24px; background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.bo-qte { display: flex; align-items: baseline; justify-content: center; gap: 8px; color: var(--ink-dim); font-size: 13px; }
.bo-qte b { font-size: 20px; font-weight: 900; color: #fff; }
.bo-offre.is-legend .bo-qte b { font-size: 28px; }
.bo-double { font-size: 13px; font-weight: 700; color: #ffb27a; line-height: 1.35; max-width: 260px; }
.bo-prix { display: flex; flex-direction: column; align-items: center; gap: 2px; padding-top: 10px; margin-top: 4px; width: 70%; border-top: 1px solid color-mix(in srgb, var(--aura) 25%, transparent); }
.bo-prix b { font-size: 28px; font-weight: 900; color: #fff; line-height: 1; }
.bo-offre.is-legend .bo-prix b { font-size: 34px; }
.bo-prix span { font-size: 12px; color: var(--ink-dim); }
.bo-acheter { width: 100%; margin-top: auto; padding: 11px 12px; font-weight: 900; }
.bo-offre.is-legend .bo-acheter { padding: 13px 14px; font-size: 16px; }
.bo-reserve {
  font-size: 11.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: #ffb27a;
}
.bo-qte-avant {
  font-size: 15px; font-weight: 700; color: var(--ink-dim); margin-bottom: -6px;
  text-decoration-thickness: 2px; text-decoration-color: rgba(255, 120, 90, .85);
}
/* Le bouton du Starter et de l'Adept prend la couleur de son rang. */
.bo-offre:not(.is-legend) .bo-acheter {
  background: linear-gradient(180deg, color-mix(in srgb, var(--aura) 34%, #1a1624), color-mix(in srgb, var(--aura) 16%, #100d16));
  border: 1px solid color-mix(in srgb, var(--aura) 60%, transparent); color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14);
}
.bo-offre:not(.is-legend) .bo-acheter:hover {
  background: linear-gradient(180deg, color-mix(in srgb, var(--aura) 50%, #1a1624), color-mix(in srgb, var(--aura) 26%, #100d16));
}
.bo-offre:not(.is-legend) .bo-nom { color: color-mix(in srgb, var(--aura) 35%, #fff); }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .bo-sceau { animation: none; } :where(html:not(.mouvement-plein)) .bo-offre, :where(html:not(.mouvement-plein)) .bo-pile img { transition: none; } }
/*  ECRAN BAS (22/10/2026, une tele 4K a 300 % : 1280 x 595 CSS). Les trois
 *  offres faisaient 520 px de haut sous 200 px d'en-tete : les boutons
 *  « Acheter » tombaient sous le bord. Sur PC tout tient sans defiler
 *  jusqu'au bouton -- les chances, plus bas, se lisent en defilant. */
@media (min-width: 901px) and (max-height: 760px) {
  body:has(#view-boutique.is-on) main { padding-top: 10px; }
  #view-boutique .boutique-page { margin-top: 0; }
  #view-boutique .home-booster-altar { padding-top: 14px; padding-bottom: 14px; }
  .home-booster-altar .altar-appel { gap: 6px; }
  .home-booster-altar .appel-titre { font-size: 24px; }
  .home-booster-altar .appel-ligne { font-size: 13px; line-height: 1.4; max-width: 880px; }
  .boutique-offres { margin-top: 12px; gap: 14px; }
  .bo-offre { gap: 4px; padding: 14px 14px 12px; }
  .bo-offre.is-legend { padding-top: 18px; margin: -6px 0; }
  .bo-pile { --w: 62px; --h: 96px; padding-bottom: 8px; }
  .bo-adept .bo-pile { --w: 78px; }
  .bo-offre.is-legend .bo-pile { --w: 80px; --h: 92px; }
  .bo-sceau { width: 46px; height: 46px; font-size: 19px; }
  .bo-nom { font-size: 17px; }
  .bo-offre.is-legend .bo-nom { font-size: 20px; }
  .bo-qte b { font-size: 18px; }
  .bo-offre.is-legend .bo-qte b { font-size: 23px; }
  .bo-double { font-size: 12px; }
  .bo-prix { padding-top: 6px; margin-top: 2px; }
  .bo-prix b { font-size: 24px; }
  .bo-offre.is-legend .bo-prix b { font-size: 26px; }
  .bo-acheter { padding: 9px 12px; }
  .bo-offre.is-legend .bo-acheter { padding: 10px 14px; font-size: 15px; }
}
@media (max-width: 900px) and (min-width: 701px) {
  .boutique-offres { grid-template-columns: 1fr 1fr; }
  .bo-offre.is-legend { grid-column: 1 / -1; order: -1; margin: 0; }
}

.boutique-anomalies { width: 100%; max-width: 700px; margin-top: 4px; }
.boutique-anomalies .hero-cards-fan { --carte-w: clamp(84px, 8vw, 122px); height: calc(var(--carte-h) * 1.18); }
.boutique-anomalies-legende {
  position: relative; z-index: 7; margin: 22px 0 0; font-family: var(--font-title); font-size: 13px; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent);
}
.boutique-anomalies-legende b { color: #81fe97; }
.boutique-chances {
  list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center;
  align-items: stretch; gap: 12px;
}
/*  Deux groupes : la composition garantie, puis les chances des raretes hautes. */
.bc-groupe {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 10px 14px 12px; border-radius: 14px;
  background: rgba(0, 0, 0, .28); border: 1px solid rgba(255, 255, 255, .08);
}
.bc-garantie { border-color: rgba(245, 185, 66, .35); background: linear-gradient(180deg, rgba(245, 185, 66, .08), rgba(0, 0, 0, .28)); }
.bc-titre {
  font-family: var(--font-title); font-size: 10.5px; font-weight: 900; letter-spacing: .2em;
  text-transform: uppercase; color: var(--accent);
}
.bc-pills { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.bc-hautes { justify-content: center; }
/*  Une colonne par rarete haute : la carte, droite, puis sa chance. */
.bc-cartes-hautes { gap: 14px; align-items: flex-end; padding-top: 2px; }
.bc-col { display: flex; flex-direction: column; align-items: center; gap: 9px; }
.bc-cartes-hautes .bc-carte { --rot: 0deg; margin: 0; }
.bc-cartes-hautes .bc-carte img { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--rc) 70%, transparent)) drop-shadow(0 5px 8px rgba(0, 0, 0, .65)); }
.bc-carte.is-anomalie img { filter: drop-shadow(0 0 10px var(--rc)) drop-shadow(0 5px 8px rgba(0, 0, 0, .65)); }
.bc-col .bc-pill { flex-direction: column; align-items: center; gap: 1px; padding: 4px 10px; border-radius: 10px; line-height: 1.15; }
.bc-pill {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 5px 12px; border-radius: 99px;
  font-size: 12.5px; background: rgba(0, 0, 0, .3);
  border: 1px solid color-mix(in srgb, var(--rc) 55%, transparent);
}
.bc-pill .bc-nom { color: var(--rc); font-weight: 800; }
.bc-pill b { color: #fff; }
.bc-pill.is-mythique { box-shadow: 0 0 14px color-mix(in srgb, var(--rc) 45%, transparent); }
/*  Le paquet minimal en vraies cartes : cinq cartes qui se chevauchent un
    peu, comme posees a l'ouverture ; la Peu commune au bout, un cran plus
    haut et cernee de sa couleur. Un clic ouvre la fiche. */
.bc-cartes { display: flex; justify-content: center; align-items: flex-end; padding: 4px 6px 2px; }
.bc-carte {
  --cw: 78px; flex: none; width: var(--cw); aspect-ratio: 320 / 503; padding: 0; margin: 0 -5px;
  border: 0; background: none; cursor: pointer; position: relative;
  transform: rotate(var(--rot, 0deg)); transition: transform .25s cubic-bezier(.16, 1, .3, 1);
}
.bc-garantie .bc-carte:nth-child(1) { --rot: -7deg; }
.bc-garantie .bc-carte:nth-child(2) { --rot: -3deg; }
.bc-garantie .bc-carte:nth-child(3) { --rot: 0deg; }
.bc-garantie .bc-carte:nth-child(4) { --rot: 3deg; }
.bc-carte.is-peu { --rot: 7deg; transform: rotate(var(--rot)) translateY(-6px); z-index: 1; }
/* Le booster de huit cartes (virage web2) : l'eventail se resserre, dans
   l'ordre de l'ouverture -- quatre Communes, trois soutiens, la vedette. */
.bc-huit .bc-carte { --cw: 58px; margin: 0 -9px; }
.bc-huit .bc-carte:nth-child(1) { --rot: -10deg; }
.bc-huit .bc-carte:nth-child(2) { --rot: -7deg; }
.bc-huit .bc-carte:nth-child(3) { --rot: -4deg; }
.bc-huit .bc-carte:nth-child(4) { --rot: -1deg; }
.bc-huit .bc-carte:nth-child(5) { --rot: 2deg; }
.bc-huit .bc-carte:nth-child(6) { --rot: 5deg; }
.bc-huit .bc-carte:nth-child(7) { --rot: 8deg; }
.bc-huit .bc-carte:nth-child(8) { --rot: 11deg; }
.bc-carte img {
  width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 4px;
  clip-path: inset(1.4% 1.3% round 5% / 3.2%);
  filter: drop-shadow(0 5px 8px rgba(0, 0, 0, .65));
}
.bc-carte.is-peu img { filter: drop-shadow(0 0 7px var(--rc)) drop-shadow(0 5px 8px rgba(0, 0, 0, .65)); }
.bc-carte:hover { transform: rotate(var(--rot)) translateY(-8px) scale(1.08); z-index: 2; }
.bc-carte:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.home-booster-altar .appel-ligne { text-align: center; }

/* ══ LE COMPTE DES KPACK SUR LE GRIMOIRE DE LA BARRE (08/10/2026) ═══════════
   Une pastille doree accrochee au livre, lisible a toute largeur : le texte
   du bouton se tasse avec la barre, la pastille reste. */
.cta-booster { overflow: visible; }
.cta-booster-lustre { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.cta-booster-livre { position: relative; flex: none; display: grid; place-items: center; }
.cta-booster-pastille {
  position: absolute; right: -9px; bottom: -5px; z-index: 2;
  min-width: 18px; height: 17px; padding: 0 5px; border-radius: 99px; box-sizing: border-box;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 900; line-height: 1; color: #1a1202; font-variant-numeric: tabular-nums;
  background: var(--gold-grad, #f5b942); box-shadow: 0 2px 8px rgba(0, 0, 0, .6), 0 0 10px rgba(245, 185, 66, .5);
}
.cta-booster-pastille[hidden] { display: none; }
.cta-booster-txt i { display: none; }

/* ══ LA ROUE, TUILE QUI VIT (08/10/2026) ═══════════════════════════════════
   La tuile prend la couleur de l'element allume -- comme la table en jeu,
   ou le fond change a chaque cran. `--el-actif` est pose par main.js
   (`monterRoueAccueil`) ; enregistre comme couleur, il se fond d'un cran a
   l'autre au lieu de sauter. La Roue grandit, la fiche du Pouvoir montre
   l'Anomalie de l'element. */
@property --el-actif { syntax: '<color>'; inherits: true; initial-value: #f5b942; }
#home-roue {
  position: relative; overflow: hidden; isolation: isolate;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  transition: --el-actif 1.1s ease;
  border-color: color-mix(in srgb, var(--el-actif) 45%, var(--line-gold));
}
#home-roue::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(ellipse 60% 75% at 74% 48%, color-mix(in srgb, var(--el-actif) 34%, transparent), transparent 72%),
    radial-gradient(ellipse 50% 60% at 10% 100%, color-mix(in srgb, var(--el-actif) 14%, transparent), transparent 70%);
}
#home-roue .sect-title { font-size: clamp(24px, 2.4vw, 34px); line-height: 1.15; }
#home-roue .roue-lois li { font-size: 14px; }
#home-roue .loi-num {
  color: var(--el-actif); border-color: color-mix(in srgb, var(--el-actif) 55%, transparent);
  background: color-mix(in srgb, var(--el-actif) 12%, transparent);
}
.roue-liens { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin-top: 22px; }
.roue-liens .roue-lien-regles { margin: 0; }
.roue-tuto { padding: 10px 16px; font-size: 13.5px; font-weight: 800; }

#home-roue .roue-cadran { width: min(420px, 80vw); }
#home-roue .roue-anneau {
  border-color: color-mix(in srgb, var(--el-actif) 60%, rgba(245, 185, 66, .45));
  box-shadow:
    0 0 60px color-mix(in srgb, var(--el-actif) 35%, transparent),
    inset 0 2px 10px rgba(255, 255, 255, .14),
    inset 0 -4px 18px rgba(0, 0, 0, .9);
}
#home-roue .roue-coeur { border-color: color-mix(in srgb, var(--el-actif) 55%, transparent); }
#home-roue .roue-coeur-el { font-size: 24px; }

#home-roue .roue-pouvoir {
  width: min(440px, 86vw); min-height: 112px; box-sizing: border-box;
  flex-direction: row; align-items: center; gap: 14px; padding: 12px 16px; text-align: left;
  border-color: color-mix(in srgb, var(--el-actif) 45%, var(--line));
  background: linear-gradient(170deg, color-mix(in srgb, var(--el-actif) 10%, rgba(255, 255, 255, .04)), rgba(0, 0, 0, .3));
}
.rp-anomalie {
  flex: none; width: 62px; aspect-ratio: 320 / 503; object-fit: cover; border-radius: 5px; cursor: pointer;
  clip-path: inset(1.4% 1.3% round 5% / 3.2%);
  filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .7));
  transition: transform .3s cubic-bezier(.16, 1, .3, 1);
}
.rp-anomalie:hover { transform: translateY(-3px) scale(1.06); }
.rp-anomalie:not([src]) { visibility: hidden; }
.rp-texte { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
#home-roue .rp-nom { font-size: 20px; }
#home-roue .rp-ligne { font-size: 13px; }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) #home-roue { transition: none; } }
/*  LA ROUE NE SE COUPE PLUS A LA TABLETTE (08/10/2026). Les deux colonnes
    egales ci-dessus pesaient plus (un id) que la colonne unique de « la
    fenetre etroite » : sous 1100 px, le cadran de 420 px debordait d'une
    colonne de 330 et la tuile le coupait. Une colonne, et le cadran comme
    le Pouvoir ne depassent jamais leur colonne. */
#home-roue .roue-cadran { max-width: 100%; }
#home-roue .roue-pouvoir { max-width: 100%; }
@media (max-width: 1100px) {
  #home-roue { grid-template-columns: minmax(0, 1fr); }
  #home-roue .roue-intro { text-align: center; }
  #home-roue .roue-lois { max-width: 520px; margin-inline: auto; text-align: left; }
  #home-roue .roue-liens { justify-content: center; }
}

/* ══ LA RARETE, UNE VRAIE TUILE (08/10/2026) ═══════════════════════════════
   Le titre flottait sur le mur, les trois blocs bleu nuit juraient avec le
   brun et l'or des autres tuiles. Meme panneau que la Roue et la Boutique,
   chiffres en grand, une icone par promesse. */
.home-edition {
  position: relative; gap: 22px; align-items: center; text-align: center;
  padding: 36px 40px 34px; border-radius: 24px;
  background:
    radial-gradient(ellipse 60% 70% at 50% 0%, rgba(245, 185, 66, .12), transparent 70%),
    linear-gradient(172deg, rgba(16, 13, 10, .62) 0%, rgba(7, 6, 5, .86) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 240, 180, .18);
  backdrop-filter: blur(3px) saturate(.92);
}
.he-tete { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.he-tete .sect-title { font-size: clamp(26px, 2.6vw, 36px); }
.he-accroche { margin: 2px 0 0; max-width: 560px; color: var(--ink-dim); font-size: 15px; line-height: 1.55; }
.home-edition .he-grid { width: 100%; max-width: 940px; }
.home-edition .he-carte {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 22px 18px 20px; border-radius: 18px;
  background: linear-gradient(175deg, rgba(255, 220, 150, .06), rgba(0, 0, 0, .28));
  border: 1px solid rgba(245, 185, 66, .28);
  box-shadow: inset 0 1px 0 rgba(255, 240, 180, .1);
}
.he-ico {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; margin-bottom: 4px;
  color: #ffd36b; background: rgba(245, 185, 66, .1); border: 1px solid rgba(245, 185, 66, .4);
  box-shadow: 0 0 18px rgba(245, 185, 66, .18);
}
.he-ico svg { width: 24px; height: 24px; }
.home-edition .he-chiffre {
  font-family: var(--font-title); font-size: clamp(32px, 3.2vw, 44px); font-weight: 900; line-height: 1.05;
  background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 3px 14px rgba(245, 185, 66, .3));
}
.home-edition .he-carte b { font-size: 15.5px; color: #fff; }
.home-edition .he-carte p { font-size: 13.5px; line-height: 1.55; max-width: 280px; }
.home-edition .he-liens { margin-top: 2px; }
.home-edition .he-liens .btn-arcane { padding: 11px 18px; font-size: 13.5px; font-weight: 800; }
/* Le lien du Livre blanc porte la meme robe que le bouton voisin (au
   telephone, les liens se soulignaient et perdaient leurs coins). */
.home-edition .he-liens a.btn-arcane,
.home-forge .he-liens a.btn-arcane {
  display: inline-flex; align-items: center; justify-content: center; text-decoration: none;
  border-radius: 8px; border: 1px solid rgba(168, 85, 247, .4); color: rgb(233, 213, 255);
  background: linear-gradient(rgb(38, 31, 61) 0%, rgb(23, 19, 38) 100%);
}

/* ══ LE PIED DE PAGE (08/10/2026) ══════════════════════════════════════════
   La marque et sa promesse, trois colonnes de portes, la ligne qui protege.
   Meme panneau que les tuiles, en plus sobre : c'est la fin de la visite. */
.home-footer {
  display: flex; flex-direction: column; align-items: stretch; gap: 22px;
  padding: 30px 36px 18px; border-radius: 22px; border-top: 0;
  background: linear-gradient(172deg, rgba(14, 11, 8, .72) 0%, rgba(5, 4, 3, .9) 100%);
  border: 1px solid rgba(245, 185, 66, .22);
  backdrop-filter: blur(3px);
  font-size: 13px; color: var(--ink-dim);
}
.hf-haut {
  display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr)); gap: 24px;
}
.hf-marque { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.hf-logo { display: flex; align-items: center; gap: 10px; }
.hf-logo .brand-crest { width: 34px; height: 34px; flex: none; }
.hf-logo b {
  font-family: 'Cinzel Decorative', var(--font-title); font-size: 24px; font-weight: 700; letter-spacing: .06em;
  background: var(--or-metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hf-marque p { margin: 0; font-family: var(--font-title); font-size: 15px; color: #f3e6c8; }
.hf-marque p em {
  font-style: normal; background: var(--gold-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hf-discord {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 4px;
  padding: 8px 14px; border-radius: 10px; text-decoration: none;
  font-size: 13px; font-weight: 800; color: #fff; background: #5865f2;
  box-shadow: 0 6px 18px rgba(88, 101, 242, .35);
  transition: transform .2s ease, box-shadow .2s ease;
}
.hf-discord:hover { transform: translateY(-1px); box-shadow: 0 8px 22px rgba(88, 101, 242, .55); }
.hf-col { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
.hf-col b {
  margin-bottom: 4px; font-family: var(--font-title); font-size: 11px; font-weight: 900;
  letter-spacing: .2em; text-transform: uppercase; color: var(--accent);
}
.hf-col a, .hf-col button {
  padding: 0; border: 0; background: none; box-shadow: none; cursor: pointer; text-align: left;
  font: inherit; font-size: 13.5px; color: var(--ink-dim); text-decoration: none;
  transition: color .15s ease;
}
.hf-col a:hover, .hf-col button:hover:not(:disabled) { color: #fff; background: none; transform: none; }
.hf-bas {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 20px;
  padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, .08); font-size: 12px; color: var(--ink-faint, rgba(226, 214, 190, .6));
}
.hf-securite b { color: #ffd36b; font-weight: 800; }
@media (max-width: 900px) and (min-width: 701px) {
  .hf-haut { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hf-marque { grid-column: 1 / -1; }
}
.hf-legal a { color: inherit; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .25); text-underline-offset: 3px; }
.hf-legal a:hover { color: #fff; }

/* ══ L'ACCUEIL QUI VANTE LE PROJET (08/10/2026) ═══════════════════════════
   La Boutique a sa page ; l'accueil dit ce que KAIROS a d'unique : on entre
   dans le web3 sans rien connaitre a la crypto, la Forge (filmee) fait la
   rarete, et Solana garantit le reste. Les panneaux portent la meme gaze
   chaude que la tuile de l'edition. */
.home-web3, .home-forge {
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  padding: 36px 40px 34px; border-radius: 24px;
  background:
    radial-gradient(ellipse 60% 70% at 50% 0%, rgba(245, 185, 66, .12), transparent 70%),
    linear-gradient(172deg, rgba(16, 13, 10, .62) 0%, rgba(7, 6, 5, .86) 100%);
  border: 1px solid var(--line-gold);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 240, 180, .18);
  backdrop-filter: blur(3px) saturate(.92);
}
.hw-tete, .hf-tete-forge { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.hw-tete .sect-title, .hf-tete-forge .sect-title { font-size: clamp(24px, 2.5vw, 34px); max-width: 820px; }
.hw-accroche { margin: 4px 0 0; max-width: 640px; color: var(--ink-dim); font-size: 15px; line-height: 1.6; }
.hw-accroche b { color: var(--accent-light); }

/* Le chemin : deux pas connus, un pas qui change tout. */
.hw-chemin {
  list-style: none; margin: 0; padding: 0; width: 100%; max-width: 1000px;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 34px; position: relative;
}
.hw-pas {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
  padding: 20px 18px 22px; border-radius: 18px;
  background: linear-gradient(175deg, rgba(255, 255, 255, .04), rgba(0, 0, 0, .28));
  border: 1px solid rgba(255, 255, 255, .12);
}
.hw-pas + .hw-pas::before {
  content: ''; position: absolute; left: -30px; top: 50%; width: 26px; height: 2px;
  background: linear-gradient(90deg, rgba(245, 185, 66, .2), rgba(245, 185, 66, .9));
}
.hw-pas + .hw-pas::after {
  content: ''; position: absolute; left: -9px; top: calc(50% - 4px);
  border: 5px solid transparent; border-left: 7px solid rgba(245, 185, 66, .9); border-right: 0;
}
.hw-monde {
  font-family: var(--font-title); font-size: 9.5px; font-weight: 800; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-faint);
}
.hw-ico {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  color: #cfd6e4; background: rgba(255, 255, 255, .06); border: 1px solid rgba(255, 255, 255, .2);
}
.hw-ico svg { width: 24px; height: 24px; }
.hw-pas b { color: #fff; font-size: 15.5px; line-height: 1.35; }
.hw-pas p { margin: 0; color: var(--ink-dim); font-size: 13.5px; line-height: 1.55; max-width: 290px; }
.hw-web3 {
  border-color: rgba(245, 185, 66, .55);
  background: linear-gradient(175deg, rgba(245, 185, 66, .12), rgba(0, 0, 0, .3));
  box-shadow: 0 0 34px rgba(245, 185, 66, .14), inset 0 1px 0 rgba(255, 240, 180, .16);
}
.hw-web3 .hw-monde { color: var(--accent); }
.hw-web3 .hw-ico { color: #ffd36b; background: rgba(245, 185, 66, .12); border-color: rgba(245, 185, 66, .5); box-shadow: 0 0 18px rgba(245, 185, 66, .25); }

/* Le film du web2 au web3 : en grand, au-dessus du chemin. */
.hw-film {
  position: relative; width: 100%; max-width: 980px; aspect-ratio: 16 / 9; border-radius: 16px; overflow: hidden;
  border: 1px solid rgba(245, 185, 66, .45); background: #070605;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .6), 0 0 30px rgba(245, 185, 66, .1);
}
.hw-film video { display: block; width: 100%; height: 100%; object-fit: cover; }
.hw-film .hf-pause .hf-ico-lire, .hw-film.est-arrete .hf-pause .hf-ico-pause { display: none; }
.hw-film.est-arrete .hf-pause .hf-ico-lire { display: block; }
/* La legende : sur le film au bureau, sous le film au telephone. */
.hw-legende {
  position: absolute; left: 50%; bottom: 4.5%; transform: translate(-50%, 6px); margin: 0;
  width: max-content; max-width: 86%; padding: 10px 22px 11px; border-radius: 14px; text-align: center;
  background: rgba(8, 6, 4, .8); border: 1px solid rgba(245, 185, 66, .28); backdrop-filter: blur(4px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .5); opacity: 0; transition: opacity .35s ease, transform .35s ease;
  pointer-events: none;
}
.hw-legende.est-visible { opacity: 1; transform: translate(-50%, 0); }
.hw-leg-phrase { display: block; font-size: clamp(14px, 1.5vw, 18px); font-weight: 600; line-height: 1.35; color: #fff; }
@media (max-width: 700px) {
  .hw-film { border-radius: 10px; overflow: visible; margin-bottom: 64px; }
  .hw-film video { border-radius: 10px; }
  .hw-legende { top: calc(100% + 8px); bottom: auto; max-width: 100%; width: 100%; padding: 8px 12px; border-radius: 10px; }
  .hw-leg-phrase { font-size: 13px; }
}

.hf-pause {
  position: absolute; right: 10px; bottom: 10px; width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center; padding: 0; cursor: pointer;
  color: #fff; background: rgba(0, 0, 0, .55); border: 1px solid rgba(255, 255, 255, .25);
  backdrop-filter: blur(4px); opacity: .75; transition: opacity .2s;
}
.hf-pause:hover, .hf-pause:focus-visible { opacity: 1; }
.hf-pause svg { width: 16px; height: 16px; }
.home-forge .he-liens .btn-arcane { padding: 11px 18px; font-size: 13.5px; font-weight: 800; }

/* La tuile Solana passe a quatre promesses, deux par deux : sur quatre
   colonnes, « 11 400 000 » debordait de la sienne. */
.home-edition .he-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 820px; }
.home-edition .he-carte p { max-width: 320px; }

/* La page Boutique : la tuile de l'accueil, seule, avec de l'air. */
.boutique-page { max-width: 1280px; margin: 20px auto 60px; }
body:has(#view-boutique.is-on) .home-booster-altar {
  background-image:
    radial-gradient(ellipse 70% 60% at 14% 22%, rgba(245, 185, 66, .10), transparent 70%),
    linear-gradient(172deg, rgba(16, 13, 10, .60) 0%, rgba(7, 6, 5, .82) 100%);
  backdrop-filter: blur(3px) saturate(.92);
}

@media (max-width: 900px) {
  .hw-chemin { grid-template-columns: 1fr; gap: 26px; max-width: 460px; }
  .hw-pas + .hw-pas::before { left: 50%; top: -22px; width: 2px; height: 18px;
    background: linear-gradient(180deg, rgba(245, 185, 66, .2), rgba(245, 185, 66, .9)); }
  .hw-pas + .hw-pas::after { left: calc(50% - 5px); top: -6px; border: 5px solid transparent;
    border-top: 7px solid rgba(245, 185, 66, .9); border-bottom: 0; }
}
@media (max-width: 700px) {
  .home-web3, .home-forge, .home-edition { display: flex; padding: 20px 12px 18px; border-radius: 14px; gap: 16px; }
  .hw-tete .sect-title, .hf-tete-forge .sect-title, .he-tete .sect-title { font-size: 20px; }
  .hw-accroche, .he-accroche { font-size: 13px; }
  .hw-pas { padding: 14px 14px 16px; }
  .hw-pas b { font-size: 14px; }
  .hw-pas p { font-size: 12.5px; }
  .home-edition .he-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .home-edition .he-carte { padding: 14px 10px; }
  .home-edition .he-chiffre { font-size: 24px; }
  .home-edition .he-carte p { font-size: 11.5px; }
  .he-liens .btn-arcane { font-size: 12.5px; }
  .boutique-page { margin: 8px auto 20px; }
}

/* ── LA SAISON (js/saison_vue.js, 12/10/2026) ─────────────────────────────
   Une scene « a la Fortnite » : la recompense en grand au milieu, son nom a
   gauche, ce qu'il faut pour l'avoir a droite, la bande des recompenses en
   bas. Le fond reprend la couleur de la recompense (--ambiance). */
#view-saison.is-on { display: block; }
/* PLEINE PAGE (Alexandre, 13/10/2026 : « prend toute la page, pas de
   coupure ») : ni les marges ni la largeur maximale de <main>. Sur grand
   ecran la scene fait exactement la hauteur de la fenetre : la recompense
   prend ce qui reste au-dessus de la piste, qui se voit toujours en entier. */
body:has(#view-saison.is-on) main { padding: 0; max-width: none; margin: 0; }
@media (min-width: 901px) {
  #view-saison .sz-scene {
    height: calc(100dvh - var(--topbar-h)); min-height: 600px;
    grid-template-rows: minmax(0, 1fr) auto;
  }
  #view-saison .sz-presente { min-height: 0; }
  #view-saison .sz-presente > .sz-toile { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; }
  /*  La boite, en absolu dans sa case : dans la grille, le « 100 % de
      hauteur » ne se lisait pas et elle sortait a 1024 px (« mega gros »). */
  #view-saison .sz-presente > .sz-objet {
    position: absolute; inset: 0; margin: auto; width: auto; height: auto;
    max-width: 100%; max-height: 88%;
  }
  #view-saison .sz-carte { height: min(40vh, calc(100dvh - var(--topbar-h) - 420px)); }
  /*  LE PLATEAU QUI TOURNE NE SE COUPE PLUS au bord de sa colonne (« une
      section coupee, un overlay devant », 13/10/2026) : sa toile prend toute
      la largeur de la scene, DERRIERE le nom et le cartouche. */
  #view-saison .sz-presente.is-plateau { grid-area: 1 / 1 / 2 / -1; pointer-events: none; }
  #view-saison .sz-info, #view-saison .sz-statut { position: relative; z-index: 2; }
}
/* Ecran bas (portable, fenetre reduite) : on resserre la piste et les
   cartouches pour que rien ne chevauche le bandeau. */
@media (min-width: 901px) and (max-height: 860px) {
  #view-saison .sz-scene { padding-top: 14px; }
  #view-saison .sz-info, #view-saison .sz-statut { padding-top: 0; }
  #view-saison .sz-info h1 { font-size: clamp(28px, 3.4vw, 44px); margin: 4px 0 6px; }
  #view-saison .sz-requis { padding: 11px 14px; gap: 6px; }
  #view-saison .sz-requis p { display: none; }
  #view-saison .sz-bande { padding-top: 10px; gap: 2px; }
  #view-saison .sz-niv { width: 68px; height: 60px; }
  #view-saison .sz-niv b { font-size: 20px; }
  #view-saison .sz-niv small { font-size: 7.5px; }
  #view-saison .sz-tete-txt { gap: 3px; }
  #view-saison .sz-tete-txt b { font-size: 16px; }
  #view-saison .sz-paliers { padding-top: 16px; }
  #view-saison .sz-palier { width: 136px; }
  #view-saison .sz-palier.is-vide { width: 40px; }
  #view-saison .sz-palier.is-final { width: 160px; }
  #view-saison .sz-carte-palier { width: 124px; height: 164px; }
  #view-saison .sz-carte-palier .sz-vue { height: 108px; }
  #view-saison .sz-palier.is-final .sz-carte-palier { width: 148px; height: 186px; }
  #view-saison .sz-palier.is-final .sz-vue { height: 128px; }
}
.sz-scene {
  --ambiance: #2a1a3a;
  position: relative; overflow: hidden;
  min-height: calc(100dvh - var(--topbar-h));
  display: grid;
  grid-template-columns: minmax(240px, 1fr) minmax(320px, 1.6fr) minmax(240px, 1fr);
  grid-template-rows: 1fr auto;
  grid-template-areas: "info scene statut" "bande bande bande";
  gap: 6px 20px; padding: 22px clamp(16px, 3vw, 40px) 18px;
  background:
    radial-gradient(ellipse 60% 55% at 50% 48%, color-mix(in srgb, var(--ambiance) 85%, #fff 15%) 0%, transparent 70%),
    radial-gradient(ellipse 120% 90% at 50% 120%, color-mix(in srgb, var(--ambiance) 60%, #000) 0%, #07080d 75%);
  transition: --ambiance .7s ease;
}
/* LA TRANSITION D'UNE RECOMPENSE A L'AUTRE (saison_vue.js, choisir) : la
   couleur du fond glisse d'une teinte a l'autre (--ambiance est une couleur
   animable) ; l'ancienne recompense sort du cote d'ou l'on vient, la
   nouvelle entre de l'autre (--sens : 1 en montant, -1 en reculant). */
@property --ambiance { syntax: '<color>'; inherits: true; initial-value: #2a1a3a; }
.sz-scene .is-sortant { animation: sz-sort .2s ease-in forwards; pointer-events: none; }
.sz-scene .is-entrant { animation: sz-entre .5s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes sz-sort { to { opacity: 0; transform: translateX(calc(var(--sens, 1) * -56px)) scale(.95); filter: blur(6px); } }
@keyframes sz-entre {
  from { opacity: 0; transform: translateX(calc(var(--sens, 1) * 72px)) scale(.96); filter: blur(10px); }
  to { opacity: 1; transform: none; filter: none; }
}
/* LE REFLET, SUR TOUTE LA SCENE (Alexandre, 13/10/2026) : une bande de
   lumiere doree qui traverse le fond d'un bord a l'autre, dans le sens du
   changement. Sur la case seule, on voyait son rectangle. Derriere le texte
   et la recompense (z-index 0), sans bord : un voile qui passe. */
.sz-reflet {
  position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
}
.sz-reflet::before {
  content: ''; position: absolute; top: -20%; bottom: -20%; left: 0; width: 70%;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 220, 150, .08) 30%, rgba(255, 232, 178, .26) 50%, rgba(255, 220, 150, .08) 70%, transparent 100%);
  filter: blur(18px);
  transform: translateX(-110%) skewX(-12deg);
  /* Vitesse CONSTANTE, 1 s : saison_vue.js y cale l'echange des elements. */
  animation: sz-balaie 1s linear forwards;
}
/* En reculant (--sens -1), le reflet part de la droite. */
.sz-reflet.is-recul::before { left: auto; right: 0; transform: translateX(110%) skewX(12deg); animation-name: sz-balaie-recul; }
@keyframes sz-balaie { to { transform: translateX(190%) skewX(-12deg); } }
@keyframes sz-balaie-recul { to { transform: translateX(-190%) skewX(12deg); } }
.sz-scene > .sz-info, .sz-scene > .sz-statut, .sz-scene > .sz-presente, .sz-scene > .sz-bande { z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .sz-scene .is-sortant { animation: none; opacity: 0; }
  :where(html:not(.mouvement-plein)) .sz-reflet { display: none; }
  :where(html:not(.mouvement-plein)) .sz-scene .is-entrant { animation: none; }
}
.sz-info { grid-area: info; align-self: start; padding-top: 4vh; }
.sz-kicker { color: var(--accent); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; }
.sz-info h1 {
  margin: 6px 0 10px; font-size: clamp(30px, 4.2vw, 56px); line-height: 1; color: #fff;
  text-transform: uppercase; letter-spacing: .01em; text-shadow: 0 4px 24px rgba(0, 0, 0, .5);
}
.sz-dit { margin: 0; max-width: 34ch; color: var(--ink); line-height: 1.45; }

.sz-statut { grid-area: statut; align-self: start; display: flex; flex-direction: column; align-items: flex-end; gap: 14px; padding-top: 4vh; }
.sz-badge {
  display: grid; place-items: center; width: 64px; height: 64px; border-radius: 14px;
  background: rgba(0, 0, 0, .45); border: 1px solid rgba(201, 162, 70, .6);
}
.sz-badge small { font-size: 10px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .1em; }
.sz-badge b { font-size: 26px; line-height: 1; color: #fff; }
.sz-requis {
  width: min(300px, 100%); display: flex; flex-direction: column; gap: 8px; padding: 14px 16px;
  border-radius: 14px; background: rgba(6, 8, 14, .72); border: 1px solid rgba(255, 255, 255, .12);
  backdrop-filter: blur(6px);
}
.sz-requis b { color: #fff; font-size: 15px; }
.sz-requis.is-acquis { border-color: rgba(201, 162, 70, .7); }
.sz-requis.is-acquis b { color: var(--accent); }
.sz-requis p { margin: 0; font-size: 12.5px; color: var(--ink-faint); line-height: 1.4; }
.sz-requis small { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.sz-jauge { height: 8px; border-radius: 4px; background: rgba(255, 255, 255, .1); overflow: hidden; }
.sz-jauge i { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.sz-jouer { padding: 11px 18px; font-size: 15px; }
/*  Campagne et classe cote a cote : les deux montent la saison (30/10/2026). */
.sz-jouers { display: flex; gap: 8px; }
.sz-jouers .sz-jouer { flex: 1 1 0; min-width: 0; }

/* La recompense, au milieu. */
.sz-presente {
  grid-area: scene; position: relative; display: grid; place-items: center;
  min-height: clamp(240px, 40vh, 560px); perspective: 1200px;
}
.sz-sol {
  position: absolute; left: 15%; right: 15%; bottom: 4%; height: 14%; z-index: 0;
  border-radius: 50%; background: radial-gradient(ellipse at center, rgba(0, 0, 0, .55), transparent 70%);
}
.sz-presente > :not(.sz-sol) { position: relative; z-index: 1; }
.sz-toile { width: 100%; height: 100%; min-height: clamp(240px, 40vh, 560px); display: block; }
.sz-objet {
  max-height: 44vh; max-width: 100%; object-fit: contain;
  filter: drop-shadow(0 24px 30px rgba(0, 0, 0, .55));
  animation: sz-flotte 6s ease-in-out infinite;
}
.sz-planche {
  width: min(420px, 80%); aspect-ratio: 16 / 10; border-radius: 14px;
  background: center / cover no-repeat; border: 3px solid #b8913c;
  box-shadow: 0 0 0 2px #3a2a10, 0 40px 60px rgba(0, 0, 0, .6);
  transform: rotateX(52deg) rotateZ(-18deg);
  animation: sz-planche 14s ease-in-out infinite;
}
.sz-carte {
  position: relative; height: 40vh; aspect-ratio: 1024 / 1610; transform-style: preserve-3d;
  animation: sz-tourne 9s linear infinite;
}
.sz-carte-face { position: absolute; inset: 0; backface-visibility: hidden; filter: drop-shadow(0 18px 24px rgba(0, 0, 0, .5)); }
.sz-carte-face.is-arriere { transform: rotateY(180deg); }
.sz-carte-face img { width: 100%; height: 100%; object-fit: contain; }
@keyframes sz-flotte { 0%, 100% { transform: translateY(0) rotateY(-8deg); } 50% { transform: translateY(-12px) rotateY(8deg); } }
@keyframes sz-planche { 0%, 100% { transform: rotateX(52deg) rotateZ(-18deg); } 50% { transform: rotateX(52deg) rotateZ(18deg); } }
@keyframes sz-tourne { from { transform: rotateY(0); } to { transform: rotateY(360deg); } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .sz-objet, :where(html:not(.mouvement-plein)) .sz-planche, :where(html:not(.mouvement-plein)) .sz-carte { animation: none; } }

/* La piste des 30 niveaux, en bas, sur toute la largeur (13/10/2026) : le
   rail se remplit jusqu'au niveau du joueur, chaque recompense est une carte
   posee sur son niveau ; on la fait defiler de cote. */
@property --sz-tour { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.sz-bande {
  grid-area: bande; position: relative; display: flex; flex-direction: column; gap: 6px; min-width: 0;
  margin: 0 calc(-1 * clamp(16px, 3vw, 40px)) -18px; padding: 16px 0 6px;
  background: linear-gradient(180deg, rgba(5, 6, 10, 0), rgba(5, 6, 10, .78) 22%, rgba(5, 6, 10, .94));
  border-top: 1px solid rgba(245, 185, 66, .22);
}
.sz-bande::before {
  content: ''; position: absolute; left: 10%; right: 10%; top: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, #f5b942, transparent); opacity: .8;
}
.sz-tete { display: flex; align-items: center; gap: 18px; padding: 0 clamp(16px, 3vw, 40px); }
/* LES BADGES DE NIVEAU PEINTS (Alexandre, 28/10/2026 : les hexagones en
   clip-path « font tres prototype »). Le badge est une image peinte par
   outils/interface/badges.py -- le medaillon au laurier pour la Saison, l'hexagone
   a feuilles pour les cartes -- et le chiffre, du texte d'or pose sur son coeur
   d'onyx. Le chiffre est un enfant : le fond de l'element porte l'image. */
:is(.mjp-hex, .sz-niv, .sz-noeud, .ex-badge, .rc-badge, .clj-medaille, .cl-pod-medaille, .eh-medaille) :is(b, small) {
  font-family: var(--font-title); font-weight: 900; line-height: 1; text-shadow: none;
  background: linear-gradient(180deg, #fff7dc 0%, #f6dc93 40%, #d39a3a 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .95)) drop-shadow(0 0 3px rgba(0, 0, 0, .8));
}
/* Le rang 2 et le rang 3 du podium : le chiffre dans l'encre de leur metal. */
:is(.clj-place.r2 .clj-medaille, .cl-pod.r2 .cl-pod-medaille, .eh-r2 .eh-medaille) b { background-image: linear-gradient(180deg, #ffffff, #dfe6ee 50%, #9aa6b4); }
:is(.clj-place.r3 .clj-medaille, .cl-pod.r3 .cl-pod-medaille, .eh-r3 .eh-medaille) b { background-image: linear-gradient(180deg, #ffe8cf, #e5a97a 50%, #a8653a); }
.sz-niv {
  flex: none; display: grid; place-items: center; align-content: center; width: 92px; height: 80px; padding-bottom: 3px;
  box-sizing: border-box; background: center / contain no-repeat;   /* l'image : arene.css */
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .65));
}
.sz-niv small { font-size: 9px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.sz-niv b { font-size: 26px; }
.sz-tete-txt { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.sz-tete-txt b { color: #fff; font-size: 20px; line-height: 1.1; letter-spacing: .01em; }
.sz-tete-txt small { color: var(--ink-faint); font-variant-numeric: tabular-nums; font-size: 12.5px; }
.sz-jauge-tete { width: min(440px, 100%); height: 10px; border-radius: 5px; background: rgba(255, 255, 255, .1); }
.sz-jauge-tete i, .sz-rail-plein {
  background: linear-gradient(90deg, #a8620f, #f5b942 60%, #ffe7a8);
  box-shadow: 0 0 12px rgba(245, 185, 66, .55);
}
.sz-pages { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.sz-fleche {
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer; font-size: 22px; line-height: 1;
  border: 1px solid rgba(245, 185, 66, .45); background: rgba(0, 0, 0, .45); color: #f5d38a;
  transition: background .15s ease, transform .15s ease;
}
.sz-fleche:hover { background: rgba(245, 185, 66, .18); transform: scale(1.06); }

.sz-piste {
  overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; scrollbar-color: rgba(245, 185, 66, .4) transparent;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.sz-paliers {
  list-style: none; margin: 0; padding: 24px 6vw 30px; position: relative;
  display: flex; align-items: flex-end; width: max-content;
}
.sz-palier { position: relative; flex: none; display: flex; flex-direction: column; align-items: center; gap: 14px; width: 154px; }
.sz-palier.is-vide { width: 46px; }
.sz-palier.is-final { width: 186px; }
.sz-creux { display: block; }

/* Le rail, a hauteur des noeuds (33 px de haut, 30 px sous eux pour « Tu es ici »). */
.sz-rail {
  position: absolute; bottom: 43.5px; height: 6px; border-radius: 3px; z-index: 0;
  background: rgba(255, 255, 255, .09); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .6);
}
.sz-rail-plein {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 3px;
  transition: width 1.6s cubic-bezier(.2, .7, .2, 1);
}
.sz-rail.is-pret .sz-rail-plein { width: var(--plein, 0); }
.sz-noeud {
  position: relative; z-index: 1; display: grid; place-items: center; width: 38px; height: 33px;
  font-size: 12.5px; font-variant-numeric: tabular-nums;
  transition: transform .2s ease;
}
/* Le medaillon dans un pseudo-element : a venir, il passe au fer sans eteindre le chiffre. */
.sz-noeud::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: center / contain no-repeat;   /* l'image : arene.css */
  filter: grayscale(1) brightness(.42) drop-shadow(0 2px 3px rgba(0, 0, 0, .7));
}
.sz-palier:not(.is-passe) .sz-noeud b { background: none; color: rgba(255, 255, 255, .5); }
.sz-palier.is-vide .sz-noeud { transform: scale(.78); }
.sz-palier.is-passe .sz-noeud::before { filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .7)); }
.sz-palier.is-actuel .sz-noeud { transform: scale(1.3); animation: sz-pouls 2.2s ease-in-out infinite; }
.sz-ici {
  position: absolute; bottom: -26px; left: 50%; transform: translateX(-50%); white-space: nowrap;
  font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--accent);
}
@keyframes sz-pouls {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(245, 185, 66, .55)); }
  50% { filter: drop-shadow(0 0 12px rgba(245, 185, 66, .95)); }
}

/* La vignette d'une recompense. Les images en absolu : dans la carte de la
   piste, la case n'a pas de hauteur que le pourcentage puisse lire. */
.sz-vue { position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden; background: #11141c center / cover no-repeat; }
.sz-vue img { position: absolute; inset: 0; margin: auto; width: 100%; height: 100%; object-fit: contain; }
.sz-vue.is-dos { background: radial-gradient(circle at 50% 40%, #3a3428, #07080c 85%); }
.sz-vue.is-plateau.is-photo { background-size: 150% auto; background-position: 50% 52%; background-color: #0a0708 !important; }
.sz-vue.is-dos img { top: 8%; left: 50%; right: auto; bottom: auto; margin: 0; width: auto; height: 84%; transform: translateX(-50%); }
.sz-vue.is-des, .sz-vue.is-figurine { background: radial-gradient(circle at 50% 45%, #3a2a1a, #0b0c10 80%); }
.sz-vue.is-des img { width: 74%; height: 74%; }
.sz-vue.is-figurine img { width: 94%; height: 94%; }
/* Le personnage (Alexandre, 13/10/2026) : son visage dans le rond dore, comme
   au plateau ; en grand, il passe par ses sept humeurs. */
.sz-vue.is-avatar { background: radial-gradient(circle at 50% 42%, #3a2c52, #0b0c12 80%); }
.sz-rond, .sz-portrait {
  position: relative; display: block; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 35%, #2a3550, #121826);
  border: 3px solid #d9a845;
  box-shadow: 0 0 0 2px #3a2a10, 0 0 22px rgba(245, 185, 66, .28), inset 0 0 18px rgba(0, 0, 0, .5);
}
.sz-rond { width: auto; height: 76%; aspect-ratio: 1; }
.sz-vue .sz-rond img, .sz-portrait img {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; object-fit: cover; transform-origin: center;
}
.sz-portrait {
  /*  « Trop grand » (Alexandre, 13/10/2026) : il debordait sur la bande du
      niveau. Il se mesure a la hauteur de sa scene, jamais plus de 260 px. */
  width: auto; height: min(62%, 260px); aspect-ratio: 1; border-width: 4px;
  box-shadow: 0 0 0 3px #3a2a10, 0 0 60px rgba(245, 185, 66, .25), 0 30px 50px rgba(0, 0, 0, .55), inset 0 0 30px rgba(0, 0, 0, .5);
  animation: sz-portrait 6s ease-in-out infinite;
}
.sz-portrait img { opacity: 0; transition: opacity .45s ease; }
.sz-portrait img.is-vu { opacity: 1; }
@keyframes sz-portrait { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .sz-portrait { animation: none; } }
@media (max-width: 900px) { .sz-portrait { height: auto; width: min(52vw, 200px); } }

/* LE PERSONNAGE EN CARTE (25/10/2026, js/carte_perso.js) : debout dans la
   scene, sous le meme plafond que l'ancien rond ; ses sept humeurs passent
   dans un medaillon accroche au bas de la carte. */
.sz-perso {
  position: relative; height: min(84%, 340px); aspect-ratio: 5 / 7;
  animation: sz-portrait 6s ease-in-out infinite;
}
.sz-perso > .cp { position: absolute; inset: 0; width: 100%; height: 100%; }
.sz-perso > .sz-portrait.sz-medaillon {
  position: absolute; right: -16%; bottom: 14%; z-index: 2;
  width: 40%; height: auto; border-width: 3px; animation: none;
  box-shadow: 0 0 0 2px #3a2a10, 0 0 22px rgba(245, 185, 66, .3), 0 10px 24px rgba(0, 0, 0, .6), inset 0 0 18px rgba(0, 0, 0, .5);
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .sz-perso { animation: none; } }
/* Dans la bande, la vignette le montre en pied, sans decor. */
.sz-vue.is-avatar img.sz-corps {
  position: absolute; left: 4%; right: 4%; top: auto; bottom: 3%; margin: 0;
  width: 92%; height: 92%; object-fit: contain; object-position: 50% 100%; transform: none;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .6));
}

/* La carte d'une recompense. */
.sz-carte-palier {
  position: relative; display: flex; flex-direction: column; width: 140px; height: 196px; padding: 0;
  overflow: hidden; cursor: pointer; text-align: left; color: inherit; font: inherit;
  border-radius: 14px; border: 1px solid rgba(255, 255, 255, .14);
  background: linear-gradient(180deg, #1b1e2a, #0a0c12);
  box-shadow: 0 12px 26px rgba(0, 0, 0, .5);
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.sz-carte-palier:hover { transform: translateY(-6px); border-color: rgba(245, 185, 66, .6); }
.sz-carte-palier .sz-vue { position: relative; inset: auto; flex: none; width: 100%; height: 134px; }
.sz-legende { display: flex; flex-direction: column; gap: 2px; padding: 9px 11px 0; min-width: 0; }
/* Trop long, le texte se coupe a droite par « … » : centre, il se rognait des deux cotes. */
.sz-legende { align-self: stretch; box-sizing: border-box; }
.sz-legende small, .sz-legende b { max-width: 100%; }

/* LE KIT DE DEPART EN 3D (tuile du niveau 1) : la toile couvre la vignette. */
.sz-depart .sz-vue { position: relative; overflow: hidden; }
.sz-depart .sz-depart-3d { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.sz-depart .sz-vue.est-3d { background-image: none !important; }
.sz-legende small { font-size: 9.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sz-legende b { font-size: 15px; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sz-etat {
  position: absolute; right: 8px; top: 8px; z-index: 1; display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 50%; font-size: 12px; background: rgba(0, 0, 0, .65);
}
.sz-etat.is-ok { background: linear-gradient(160deg, #ffe7a8, #f5b942); color: #2a1704; font-weight: 900; }
.sz-palier:not(.is-acquis) .sz-vue { filter: saturate(.55) brightness(.72); transition: filter .2s ease; }
.sz-palier:not(.is-acquis) .sz-carte-palier:hover .sz-vue { filter: none; }
.sz-palier.is-acquis .sz-carte-palier { border-color: rgba(245, 185, 66, .65); }
.sz-palier.is-acquis .sz-carte-palier::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px; z-index: 1;
  background: linear-gradient(90deg, #a8620f, #ffe7a8, #a8620f);
}
.sz-palier.is-choisi .sz-carte-palier {
  transform: translateY(-12px) scale(1.05); border-color: #ffe7a8;
  box-shadow: 0 0 0 2px var(--accent), 0 20px 44px rgba(245, 185, 66, .35);
}
.sz-palier.is-choisi .sz-vue { filter: none; }
/* Le trophee : plus grand, un lisere d'or qui tourne. */
.sz-palier.is-final .sz-carte-palier {
  width: 172px; height: 226px; border: 2px solid transparent;
  background:
    linear-gradient(180deg, #24160a, #0a0c12) padding-box,
    conic-gradient(from var(--sz-tour), #f5b942, #6a3409, #ffe7a8, #6a3409, #f5b942) border-box;
  animation: sz-lisere 6s linear infinite;
}
.sz-palier.is-final .sz-vue { height: 160px; }
@keyframes sz-lisere { to { --sz-tour: 360deg; } }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .sz-palier.is-actuel .sz-noeud, :where(html:not(.mouvement-plein)) .sz-palier.is-final .sz-carte-palier { animation: none; }
  :where(html:not(.mouvement-plein)) .sz-rail-plein { transition: none; }
}

@media (max-width: 900px) {
  .sz-scene {
    grid-template-columns: 1fr; grid-template-rows: auto auto auto auto;
    grid-template-areas: "info" "scene" "statut" "bande";
    min-height: 0;
  }
  .sz-info, .sz-statut { padding-top: 0; }
  .sz-info { text-align: center; }
  .sz-dit { margin: 0 auto; }
  .sz-statut { align-items: center; flex-direction: row; justify-content: center; }
  .sz-presente, .sz-toile { min-height: 34vh; }
  .sz-carte { height: 30vh; }
  .sz-objet { max-height: 32vh; }
}
@media (max-width: 700px) {
  .sz-niv { width: 68px; height: 60px; }
  .sz-niv b { font-size: 20px; }
  .sz-niv small { font-size: 7.5px; }
  .sz-tete { gap: 12px; }
  .sz-tete-txt b { font-size: 16px; }
  .sz-fleche { display: none; }
  .sz-palier { width: 118px; }
  .sz-palier.is-vide { width: 34px; }
  .sz-palier.is-final { width: 140px; }
  .sz-carte-palier { width: 108px; height: 156px; }
  .sz-carte-palier .sz-vue { height: 100px; }
  .sz-palier.is-final .sz-carte-palier { width: 130px; height: 180px; }
  .sz-palier.is-final .sz-vue { height: 122px; }
  .sz-legende b { font-size: 13px; }
}
/* Telephone couche : peu de hauteur, de la largeur. On garde les trois
   colonnes, la recompense en petit, pour que la piste tienne dans l'ecran. */
@media (max-width: 960px) and (orientation: landscape) and (max-height: 500px) {
  .sz-scene {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr); grid-template-rows: auto auto;
    grid-template-areas: "info scene statut" "bande bande bande"; padding-top: 6px; gap: 4px 14px;
  }
  .sz-info { text-align: left; }
  .sz-info h1 { font-size: 24px; margin: 2px 0 4px; }
  .sz-dit { margin: 0; font-size: 12px; }
  .sz-statut { flex-direction: column; align-items: flex-end; }
  .sz-requis { padding: 10px 12px; gap: 6px; }
  .sz-requis p { display: none; }
  .sz-presente, .sz-toile { min-height: 110px; height: 110px; }
  .sz-carte { height: 104px; }
  .sz-objet { max-height: 104px; }
  .sz-bande { padding-top: 8px; }
  .sz-niv { width: 58px; height: 51px; }
  .sz-niv b { font-size: 17px; }
  .sz-niv small { font-size: 6.5px; }
  .sz-tete-txt b { font-size: 15px; }
  .sz-tete-txt .sz-kicker, .sz-tete-txt small { display: none; }
  .sz-fleche { width: 32px; height: 32px; font-size: 18px; }
  .sz-paliers { padding-top: 12px; }
  .sz-palier { width: 104px; }
  .sz-palier.is-vide { width: 30px; }
  .sz-palier.is-final { width: 122px; }
  .sz-carte-palier { width: 96px; height: 112px; }
  .sz-carte-palier .sz-vue { height: 68px; }
  .sz-palier.is-final .sz-carte-palier { width: 114px; height: 124px; }
  .sz-palier.is-final .sz-vue { height: 80px; }
  .sz-legende { padding: 4px 8px 0; gap: 0; }
  .sz-legende small { font-size: 8.5px; }
  .sz-legende b { font-size: 12px; }
}

/* Les renvois vers la Saison : depuis le kit de l Atelier et le classement. */
.ats-voir, .cl-saison-btn {
  justify-self: start; padding: 7px 14px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--accent); background: rgba(245, 185, 66, .12); color: var(--accent); font-weight: 700;
}
.ats-voir:hover, .cl-saison-btn:hover { background: rgba(245, 185, 66, .22); }
.cl-saison {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid rgba(201, 162, 70, .4); background: rgba(201, 162, 70, .08);
}
.cl-saison p { margin: 0; flex: 1 1 220px; font-size: 13px; color: var(--ink); line-height: 1.4; }

/* La figurine de la saison, a l'atelier (js/figurines.js). */
.at-figurine-toile { width: 100%; height: 100%; display: block; }
.at-figurine-aucune { display: grid; place-items: center; width: 100%; height: 100%; font-size: 28px; color: var(--ink-faint); }

/* ── LE DEBALLAGE (js/deballage.js, 13/10/2026) ─────────────────────────────
   Trois temps : la CHARGE (anneau de lumiere, grains aspires, sceau qui
   grossit et tremble), l'ECLAT (secousse, six eclats, onde, eclair, colonne),
   la RECOMPENSE (elle monte de la colonne, reflet, nom lettre a lettre). Le
   fond prend la couleur de la recompense (--ambiance). */
.db-voile {
  --ambiance: #6a1e10;
  --charge: 2.6s;
  position: fixed; inset: 0; z-index: 9000; overflow: hidden;
  display: grid; grid-template-rows: auto 1fr auto; justify-items: center;
  padding: clamp(18px, 4vh, 44px) 16px clamp(18px, 4vh, 40px);
  /*  --cy : le centre du sceau, mesure (deballage.js). Rayons, lueur et
      eclair partent de LUI, pas d'un pourcentage de l'ecran (« pas centre »). */
  --cy: 50%;
  background:
    radial-gradient(ellipse 55% 50% at 50% var(--cy), color-mix(in srgb, var(--ambiance) 70%, #fff 12%) 0%, transparent 72%),
    radial-gradient(ellipse 120% 100% at 50% var(--cy), color-mix(in srgb, var(--ambiance) 35%, #000) 0%, #05060a 70%),
    #05060a;
  animation: db-entree .35s ease both;
}
.db-voile.is-sortie { animation: db-sortie .25s ease both; }
.db-voile.is-eclat { animation: db-secousse .42s cubic-bezier(.36, .07, .19, .97) both; }
@keyframes db-entree { from { opacity: 0; } to { opacity: 1; } }
@keyframes db-sortie { to { opacity: 0; } }
@keyframes db-secousse {
  10%, 90% { transform: translate(-2px, 1px); } 20%, 80% { transform: translate(4px, -2px); }
  30%, 50%, 70% { transform: translate(-7px, 3px); } 40%, 60% { transform: translate(7px, -3px); }
}

/* Les rayons : ils se levent pendant la charge, plus francs une fois ouverts. */
.db-rayons {
  position: absolute; left: 50%; top: var(--cy); width: 170vmax; height: 170vmax; translate: -50% -50%;
  pointer-events: none; opacity: .16;
  background: repeating-conic-gradient(from 0deg, rgba(255, 214, 140, .6) 0deg 3deg, transparent 3deg 15deg);
  -webkit-mask-image: radial-gradient(circle, #000 0%, transparent 40%);
  mask-image: radial-gradient(circle, #000 0%, transparent 40%);
  animation: db-tour 30s linear infinite, db-monte-rayons var(--charge) ease-in both;
}
.db-voile.is-ouvert .db-rayons { opacity: .42; animation: db-tour 50s linear infinite; transition: opacity .5s ease; }
@keyframes db-tour { to { rotate: 360deg; } }
@keyframes db-monte-rayons { from { opacity: .08; } to { opacity: .3; } }
.db-eclair {
  position: absolute; inset: 0; pointer-events: none; opacity: 0; z-index: 3;
  background: radial-gradient(circle at 50% var(--cy), #fffaf0, #ffe2a0 40%, rgba(255, 200, 120, 0) 80%);
}
.db-voile.is-ouvert .db-eclair { animation: db-eclair .55s ease-out; }
@keyframes db-eclair { 0% { opacity: 1; } 100% { opacity: 0; } }

/* La poussiere d'or qui monte, derriere tout. */
.db-poussiere { position: absolute; inset: 0; pointer-events: none; }
.db-poussiere i {
  position: absolute; bottom: -10px; width: 4px; height: 4px; border-radius: 50%; scale: var(--s);
  background: #ffd98a; box-shadow: 0 0 8px rgba(255, 200, 110, .9); opacity: 0;
  animation: db-poussiere var(--t) linear infinite;
}
@keyframes db-poussiere {
  0% { transform: translate(0, 0); opacity: 0; } 15% { opacity: .7; }
  100% { transform: translate(30px, -110vh); opacity: 0; }
}

.db-tete { position: relative; z-index: 2; text-align: center; }
.db-kicker { display: block; color: var(--accent); font-size: 12px; font-weight: 800; letter-spacing: .24em; text-transform: uppercase; }
.db-palier {
  margin: 6px 0 0; font-size: clamp(26px, 4.4vw, 52px); line-height: 1.05; text-transform: uppercase;
  background: linear-gradient(180deg, #fff 30%, #ffd98a 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 4px 22px rgba(245, 185, 66, .35));
  animation: db-monte .6s cubic-bezier(.2, .8, .2, 1) both .1s;
}
@keyframes db-monte { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

.db-coeur { position: relative; z-index: 1; align-self: stretch; justify-self: stretch; display: grid; place-items: center; min-height: 0; cursor: pointer; }
.db-voile.is-ouvert .db-coeur { cursor: default; }
.db-noyau { position: relative; display: grid; place-items: center; width: clamp(200px, 34vmin, 300px); aspect-ratio: 1; z-index: 2; }

/* L'anneau qui se ferme pendant la charge. */
.db-anneau { position: absolute; inset: 0; width: 100%; height: 100%; rotate: -90deg; overflow: visible; }
.db-anneau circle {
  fill: none; stroke: #ffd98a; stroke-width: 2.2; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100;
  filter: drop-shadow(0 0 4px rgba(255, 210, 120, .95)) drop-shadow(0 0 12px rgba(245, 185, 66, .7));
  animation: db-anneau var(--charge) cubic-bezier(.5, 0, .9, .6) forwards;
}
.db-voile.is-ouvert .db-anneau { animation: db-anneau-sort .35s ease-out forwards; }
@keyframes db-anneau { to { stroke-dashoffset: 0; } }
@keyframes db-anneau-sort { to { scale: 2.2; opacity: 0; } }

/* Les grains d'or aspires vers le sceau. */
.db-aspiration { position: absolute; left: 50%; top: 50%; width: 0; height: 0; }
.db-aspiration i {
  position: absolute; width: 5px; height: 5px; margin: -2.5px; border-radius: 50%;
  background: #fff0c8; box-shadow: 0 0 10px rgba(255, 205, 110, 1); opacity: 0;
  animation: db-aspire .9s cubic-bezier(.55, 0, .9, .45) infinite;
}
@keyframes db-aspire {
  0% { transform: translate(var(--x), var(--y)) scale(.6); opacity: 0; }
  25% { opacity: 1; }
  100% { transform: translate(0, 0) scale(1.4); opacity: 0; }
}

/* Le sceau : il grossit et tremble de plus en plus ; un lustre le parcourt. */
.db-sceau {
  position: relative; z-index: 1; display: grid; place-items: center; align-content: center;
  width: 62%; aspect-ratio: 1; cursor: pointer; border: 0; padding: 0; color: #1a0e02;
  clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  background:
    linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .7) 50%, transparent 65%) -200% 0 / 300% 100% no-repeat,
    linear-gradient(160deg, #fff1c4, #f5b942 40%, #8a4f10);
  animation: db-grossit var(--charge) cubic-bezier(.6, 0, .9, .5) both, db-lustre 1.3s ease-in-out infinite,
    db-vibre .09s linear infinite calc(var(--charge) * .55);
}
.db-sceau small { font-size: clamp(11px, 1.8vmin, 15px); font-weight: 900; letter-spacing: .14em; text-transform: uppercase; color: #3a2006; }
.db-sceau b { font-size: clamp(46px, 9vmin, 72px); line-height: 1; font-weight: 900; }
.db-noyau::before {
  content: ''; position: absolute; inset: -18%; border-radius: 50%; z-index: 0;
  background: radial-gradient(circle, rgba(255, 224, 150, .75), rgba(245, 185, 66, .25) 40%, transparent 68%);
  animation: db-halo var(--charge) ease-in both;
}
.db-voile.is-ouvert .db-noyau::before { animation: db-halo-eclate .6s ease-out forwards; }
@keyframes db-grossit { from { scale: .82; } to { scale: 1.12; } }
@keyframes db-lustre { from { background-position: -200% 0, 0 0; } to { background-position: 200% 0, 0 0; } }
@keyframes db-vibre { 0% { translate: 0 0; } 25% { translate: -2px 1px; } 50% { translate: 2px -1px; } 75% { translate: -1px -2px; } 100% { translate: 1px 2px; } }
@keyframes db-halo { from { opacity: .35; scale: .8; } to { opacity: 1; scale: 1.25; } }
@keyframes db-halo-eclate { to { opacity: 0; scale: 2.4; } }
.db-invite {
  position: relative; z-index: 2; margin: 0; color: var(--ink-faint); font-size: 13px; letter-spacing: .1em; text-transform: uppercase;
  animation: db-monte .5s ease both .5s, db-clignote 1.6s ease-in-out infinite 1s;
}
@keyframes db-clignote { 50% { opacity: .45; } }

/* L'eclat : six morceaux du sceau, une onde de choc, une colonne. */
.db-morceaux { position: absolute; z-index: 3; pointer-events: none; }
.db-morceaux i {
  position: absolute; inset: 0;
  background: linear-gradient(160deg, #fff1c4, #f5b942 40%, #8a4f10);
  filter: drop-shadow(0 0 6px rgba(255, 210, 120, .8));
  animation: db-morceau .9s cubic-bezier(.15, .7, .3, 1) forwards;
}
@keyframes db-morceau { to { transform: translate(var(--dx), var(--dy)) rotate(var(--r)) scale(.5); opacity: 0; } }
.db-onde {
  position: absolute; left: 50%; top: 50%; width: 60%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%;
  border: 3px solid rgba(255, 228, 160, .95); box-shadow: 0 0 30px rgba(255, 200, 110, .8), inset 0 0 20px rgba(255, 200, 110, .6);
  animation: db-onde .75s cubic-bezier(.1, .7, .3, 1) forwards; pointer-events: none;
}
.db-onde.is-seconde { animation-delay: .12s; border-width: 2px; opacity: 0; }
@keyframes db-onde { 0% { scale: .3; opacity: 1; } 100% { scale: 5; opacity: 0; } }
.db-colonne {
  position: absolute; left: 50%; bottom: 0; top: -20%; width: clamp(120px, 22vw, 260px); translate: -50% 0; z-index: 0;
  pointer-events: none; transform-origin: 50% 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 230, 170, .35) 35%, rgba(255, 245, 220, .6) 50%, rgba(255, 230, 170, .35) 65%, transparent);
  filter: blur(6px); animation: db-colonne 1.6s ease-out forwards;
}
@keyframes db-colonne { 0% { scale: .2 0; opacity: 0; } 15% { scale: 1 1; opacity: 1; } 100% { scale: 1.6 1; opacity: 0; } }

/* La recompense, qui monte de la colonne. */
.db-presente {
  /* Pas la zone « scene » de la page Saison : elle n'existe pas ici, et la
     recompense partait dans un coin, a taille nulle. */
  grid-area: auto; position: absolute; inset: 0; min-height: 0 !important; z-index: 2;
  animation: db-arrive .9s cubic-bezier(.16, 1.3, .3, 1) both .08s;
}
@keyframes db-arrive {
  0% { opacity: 0; transform: translateY(18%) scale(.35); filter: brightness(3); }
  60% { filter: brightness(1.4); }
  100% { opacity: 1; transform: none; filter: none; }
}
.db-presente > .sz-toile { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; }
.db-presente > .sz-objet { position: absolute; inset: 0; margin: auto; width: auto; height: auto; max-width: 100%; max-height: 88%; }
.db-presente .sz-carte { height: min(50vh, 440px); }
/* Un reflet balaie la boite et le dos, une fois qu'ils sont arrives. */
.db-reflet {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background: linear-gradient(110deg, transparent 40%, rgba(255, 250, 230, .55) 50%, transparent 60%) -150% 0 / 250% 100% no-repeat;
  mix-blend-mode: screen; animation: db-reflet 1.1s ease-in-out both 1s;
}
@keyframes db-reflet { to { background-position: 150% 0; } }

.db-eclats { position: absolute; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; z-index: 3; }
.db-eclats i {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  background: radial-gradient(circle, #fffaf0, #f5b942 60%, transparent 70%);
  box-shadow: 0 0 12px rgba(245, 185, 66, .95);
  animation: db-eclat 1.5s cubic-bezier(.1, .7, .3, 1) both;
}
@keyframes db-eclat {
  0% { transform: translate(0, 0) scale(1.6); opacity: 1; }
  70% { opacity: .9; }
  100% { transform: translate(var(--dx), calc(var(--dy) + 60px)) scale(.2); opacity: 0; }
}

.db-info { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.db-genre { color: var(--accent); font-size: 11.5px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; animation: db-monte .5s ease both .45s; }
.db-nom { margin: 2px 0 0; font-size: clamp(32px, 5.4vw, 64px); line-height: 1; color: #fff; text-transform: uppercase; text-shadow: 0 4px 24px rgba(0, 0, 0, .55), 0 0 30px rgba(245, 185, 66, .25); }
.db-nom span { display: inline-block; animation: db-lettre .5s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes db-lettre { from { opacity: 0; transform: translateY(.5em) scale(.6); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
.db-ajout { margin: 4px 0 12px; color: var(--ink); font-size: 14px; animation: db-monte .5s ease both 1s; }
.db-gestes { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px; animation: db-monte .5s ease both 1.15s; }
.db-equiper { padding: 12px 22px; font-size: 15px; }
.db-continuer {
  padding: 11px 20px; border-radius: 10px; cursor: pointer; font-weight: 700; font-size: 15px;
  border: 1px solid rgba(255, 255, 255, .3); background: rgba(0, 0, 0, .45); color: #fff;
}
.db-continuer:hover { background: rgba(255, 255, 255, .1); }
.db-lien { border: 0; background: none; color: var(--accent); cursor: pointer; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .db-rayons, :where(html:not(.mouvement-plein)) .db-sceau, :where(html:not(.mouvement-plein)) .db-aspiration, :where(html:not(.mouvement-plein)) .db-poussiere, :where(html:not(.mouvement-plein)) .db-voile.is-eclat { animation: none !important; }
}

/* ══ La fiche d'un autre joueur (js/fiche_joueur_vue.js) ═══════════════════
   La fenetre du profil (pm-*), et dedans : la tete, la phrase, des tuiles. */
.cl-ligne.is-cliquable, .cl-pod.is-cliquable { cursor: pointer; }
.cl-ligne.is-cliquable:focus-visible, .cl-pod.is-cliquable:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cl-pod.is-cliquable:hover .cl-pod-nom, .cl-ligne.is-cliquable:hover .cl-nom { color: var(--accent); }
.fj-panneau { width: min(440px, calc(100vw - 32px)); }
.fj-corps { display: flex; flex-direction: column; gap: 14px; }
.fj-tete { display: flex; align-items: center; gap: 16px; }
.fj-avatar {
  flex: none; width: 84px; height: 84px; border-radius: 50%; overflow: hidden;
  display: grid; place-items: center; border: 2px solid var(--line-gold);
  background: radial-gradient(circle at 50% 35%, #2a3550, #121826);
}
.fj-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fj-initiale { font-size: 32px; font-weight: 800; color: var(--ink-bright); }
.fj-ident { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fj-nom { overflow-wrap: anywhere; }
.fj-adr { font-size: 11px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.fj-niveau { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; margin-top: 2px; }
.fj-titre { font-size: 13px; font-weight: 700; color: var(--accent); }
.fj-num { font-size: 12px; color: var(--ink-dim); }
.fj-phrase {
  margin: 0; padding: 10px 14px; border-radius: 10px;
  background: rgba(255, 255, 255, .04); border-left: 2px solid var(--line-gold);
  font-size: 13px; font-style: italic; color: var(--ink); line-height: 1.45; overflow-wrap: anywhere;
}
.fj-bloc h3 {
  margin: 0 0 7px; font-size: 10px; font-weight: 800; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-dim);
}
.fj-tuiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
.fj-tuile {
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 9px 6px;
  border-radius: 10px; background: rgba(120, 145, 190, .07); border: 1px solid rgba(120, 145, 190, .14);
  text-align: center; min-width: 0;
}
.fj-tuile b { font-size: 18px; font-weight: 800; color: var(--ink-bright); font-variant-numeric: tabular-nums; white-space: nowrap; }
.fj-tuile small { font-size: 10px; color: var(--ink-dim); line-height: 1.2; }
.fj-attente { margin: 0; font-size: 12px; color: var(--ink-dim); text-align: center; }
@media (max-width: 380px) { .fj-tuile b { font-size: 16px; } .fj-avatar { width: 68px; height: 68px; } }
.fj-phrase.is-masquee { font-style: normal; color: var(--ink-faint); }
.fj-signaler { display: flex; flex-direction: column; align-items: center; gap: 8px; padding-top: 4px; border-top: 1px solid rgba(120, 145, 190, .12); }
.fj-signaler-lien {
  margin-top: 8px; padding: 4px 8px; border: 0; background: none; cursor: pointer;
  font-size: 11px; color: var(--ink-faint); text-decoration: underline; text-underline-offset: 3px;
}
.fj-signaler-lien:hover { color: #e08a7a; }
.fj-signaler-msg { margin: 8px 0 0; font-size: 12px; color: var(--ink-dim); text-align: center; }
.fj-signaler-msg.is-ok { color: #8fd19e; }
.fj-signaler-msg.is-erreur { color: #e08a7a; }
.fj-motifs { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.fj-motif, .fj-actualiser {
  padding: 6px 11px; border-radius: 999px; cursor: pointer; font-size: 12px;
  border: 1px solid rgba(224, 138, 122, .4); background: rgba(224, 138, 122, .08); color: var(--ink);
}
.fj-motif:hover:not(:disabled) { background: rgba(224, 138, 122, .18); }
.fj-motif.is-annuler { border-color: var(--line); background: none; color: var(--ink-dim); }
.fj-motif:disabled { opacity: .5; cursor: default; }
.fj-actualiser { align-self: center; border-color: var(--line-gold); background: rgba(245, 185, 66, .1); }

/* LA TABLE QUI NE S'AFFICHE PAS (tableEnPanne, main.js) : un panneau qui reste. */
.table-panne {
  position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; padding: 16px;
  background: rgba(4, 3, 6, .78);
}
.table-panne-box {
  max-width: 380px; padding: 20px 22px; border-radius: 14px; text-align: center;
  border: 1.5px solid var(--accent); background: linear-gradient(160deg, #2a1d08, #120c03);
  color: var(--ink); box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}
.table-panne-box b { display: block; font-size: 16px; color: #ffe699; margin-bottom: 8px; }
.table-panne-box p { margin: 0 0 16px; font-size: 13px; line-height: 1.45; color: var(--ink-dim); }
.table-panne-box button { width: 100%; }

/* ══ LA CAMPAGNE (22/10/2026, campagne_vue.js, docs/12-campagne.md) ═══════
 * Deux portes dans Solo, puis le parcours, l'Inventaire et le cartable de
 * campagne. Les cartes de campagne portent le sceau « Campagne » partout ou
 * elles se montrent, en partie aussi (body.en-campagne). */
.campagne { width: 100%; max-width: 1080px; margin: 0 auto; text-align: left; }
/* La tete tient sur une ligne : titre a gauche, jauges et onglets a droite. */
.cg-tete {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 8px 14px; margin-bottom: 10px;
}
.cg-tete-titre { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
.no-match .cg-tete h1 { margin: 2px 0 0; font-size: clamp(18px, 2.2vw, 26px); }
.cg-sous { color: var(--ink-dim); max-width: 620px; margin: 0 auto 12px; font-size: 14px; text-align: center; }
.cg-jauge { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-left: auto; }
.cg-pastille {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 5px 12px;
  border-radius: 999px; background: rgba(245, 185, 66, .08); border: 1px solid var(--line-gold);
}
.cg-pastille b { font-family: var(--font-num); color: var(--accent-light); font-size: 15px; }
.cg-pastille small { color: var(--ink-dim); font-size: 12px; }
.cg-pastille .cg-court { display: none; }

.cg-onglets { display: flex; gap: 6px; justify-content: center; margin: 0; flex-wrap: wrap; }
.cg-onglet {
  position: relative; padding: 7px 16px; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1px solid var(--line); color: var(--ink-dim);
  font-family: var(--font-ui); font-size: 14px;
}
.cg-onglet.est-choisi { background: rgba(245, 185, 66, .12); border-color: var(--accent); color: var(--accent-light); }
.cg-badge {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px; margin-left: 6px;
  padding: 0 5px; border-radius: 9px; background: var(--accent); color: #1a1205;
  font-size: 11px; font-weight: 800;
}

.cg-vide { text-align: center; color: var(--ink-dim); padding: 28px 12px; }
.cg-gestes { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.cg-discret { background: transparent; border: 1px solid var(--line); color: var(--ink-dim); }

/* ── Le parcours ── */
.cg-parcours { display: flex; flex-direction: column; gap: 12px; }
.cg-region {
  --el: var(--accent);
  position: relative; padding: 14px 16px; border-radius: 14px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--el) 10%, transparent), transparent 60%), var(--bg-glass);
  border: 1px solid color-mix(in srgb, var(--el) 35%, transparent);
}
.cg-region.el-feu { --el: var(--el-feu); }
.cg-region.el-air { --el: var(--el-air); }
.cg-region.el-eau { --el: #38a8e8; }
.cg-region.el-terre { --el: var(--el-terre); }
.cg-region.el-lumiere { --el: var(--el-lumiere); }
.cg-region.el-ether { --el: var(--el-ether); }
.cg-region.est-fermee { opacity: .55; }
.cg-region-tete { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.cg-region-tete h2 { margin: 0; font-family: var(--font-title); font-size: 19px; color: var(--ink); }
.cg-region-num { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--el); font-weight: 700; }
.cg-sceau { margin-left: auto; color: var(--ok); font-weight: 800; }
.cg-region-texte { color: var(--ink-dim); font-size: 14px; margin: 8px 0 0; }
.cg-combats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
.cg-combat {
  position: relative; display: flex; align-items: center; gap: 10px; min-width: 0;
  padding: 8px 10px; border-radius: 12px; cursor: pointer; text-align: left;
  background: rgba(0, 0, 0, .28); border: 1px solid var(--line); color: var(--ink);
  font-family: var(--font-ui);
  transition: border-color .18s ease, transform .18s ease;
}
.cg-combat:hover:not(:disabled) { border-color: var(--el); transform: translateY(-1px); }
.cg-combat:disabled { cursor: default; opacity: .6; }
.cg-combat.est-gardien { border-color: color-mix(in srgb, var(--el) 55%, transparent); }
.cg-combat.est-prochain { border-color: var(--accent); box-shadow: 0 0 16px var(--gold-glow); }
.cg-combat-txt { display: flex; flex-direction: column; min-width: 0; }
.cg-combat-txt b { font-family: var(--font-title); font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cg-combat-txt small { font-size: 11px; color: var(--ink-dim); }
.cg-combat.est-gardien .cg-combat-txt small { color: var(--el); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.cg-coche { margin-left: auto; color: var(--ok); font-style: normal; font-weight: 800; }
.cg-cadenas { margin-left: auto; font-style: normal; font-size: 12px; opacity: .7; }
.cg-portrait {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--el, var(--accent)) 30%, #1b2233), #0b0f18);
  border: 1.5px solid color-mix(in srgb, var(--el, var(--accent)) 55%, transparent);
  display: grid; place-items: center;
}
.cg-portrait img { width: 100%; height: 100%; object-fit: cover; }
.cg-portrait b { font-family: var(--font-title); color: var(--ink); }
.cg-combat.est-verrouille .cg-portrait img { filter: grayscale(1) brightness(.5); }
.cg-fin { --el: var(--accent); text-align: center; }
.cg-fin .cg-gestes { justify-content: center; }

/* ── L'inventaire ── */
.cg-sous-titre {
  display: flex; align-items: baseline; gap: 8px; margin: 14px 0 8px;
  font-family: var(--font-title); font-size: 15px; color: var(--ink);
}
.cg-sous-titre small { color: var(--ink-faint); font-family: var(--font-num); }
.cg-coffrets { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.cg-coffret {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 12px;
  cursor: pointer; text-align: left; font-family: var(--font-ui); color: var(--ink);
  background: var(--bg-glass); border: 1px solid var(--line);
}
.cg-coffret.est-ferme { border-color: var(--accent); box-shadow: 0 0 14px var(--gold-glow); }
.cg-boite {
  position: relative; flex: 0 0 auto; width: 54px; height: 44px; border-radius: 6px 6px 8px 8px;
  background: linear-gradient(180deg, #7a4a1e 0 38%, #3a2412 38% 44%, #6a3f18 44%);
  border: 1.5px solid #c9932f; box-shadow: inset 0 0 0 2px rgba(0, 0, 0, .25);
  display: grid; place-items: center;
}
.cg-boite::after {
  content: ''; position: absolute; left: 50%; top: 34%; width: 10px; height: 12px;
  transform: translateX(-50%); border-radius: 2px; background: var(--gold-grad);
}
.cg-boite-visage {
  position: absolute; right: -10px; bottom: -8px; width: 26px; height: 26px; border-radius: 50%;
  overflow: hidden; border: 1.5px solid var(--accent); background: #0b0f18;
}
.cg-boite-visage img { width: 100%; height: 100%; object-fit: cover; }
.cg-coffret-txt { display: flex; flex-direction: column; }
.cg-coffret-txt b { font-family: var(--font-title); font-size: 14px; }
.cg-coffret-txt small { color: var(--ink-dim); font-size: 12px; }

/* ── Les cartes de campagne ── */
.cg-cartable-note { color: var(--ink-dim); font-size: 13px; text-align: center; margin: 0 0 6px; }
.cg-grille, .cg-revele {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px;
}
.cg-carte {
  position: relative; padding: 0; border: 0; background: none; cursor: pointer;
  aspect-ratio: .637; perspective: 700px;
}
.cg-carte-face, .cg-carte-dos {
  position: absolute; inset: 0; border-radius: 6px; overflow: hidden;
  backface-visibility: hidden; transition: transform .45s cubic-bezier(.2, .8, .2, 1);
}
.cg-carte-face { background: #11161f; display: grid; place-items: center; }
.cg-carte-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cg-carte-nom { padding: 6px; font-size: 11px; color: var(--ink); text-align: center; }
.cg-carte-dos {
  background: url('https://medias.kairostcg.com/logo/dos_kairos_detoure.png') center / contain no-repeat, radial-gradient(circle, #3a2a12, #0b0f18);
  transform: rotateY(180deg);
}
.cg-carte.est-cachee .cg-carte-face { transform: rotateY(-180deg); }
.cg-carte.est-cachee .cg-carte-dos { transform: rotateY(0deg); }
.cg-carte.est-cachee:hover .cg-carte-dos { filter: brightness(1.2); }
.cg-revele .cg-carte { animation: cgArrive .4s calc(var(--i, 0) * 40ms) both; }
@keyframes cgArrive { from { opacity: 0; transform: translateY(14px) scale(.94); } }
/* LE SCEAU : un mot discret pose sur le haut du cadre, droit et centre
 * (Alexandre, 23/10 : « en haut de la carte, assez discret »), jamais sur
 * l'illustration ni sur le texte. */
/* Sur ::before et non ::after : au doigt, le halo des cartes jouables et
 * celui de la carte piochee prennent ::after -- le sceau en heritait inset
 * -2px, et s'etalait sur toute la carte en clignotant (23/10, mobile). */
.cg-stamp, body.en-campagne .mc-carte::before {
  position: absolute; top: 1px; left: 50%; translate: -50% 0; padding: 0 4px; border-radius: 0 0 3px 3px;
  pointer-events: none; opacity: .78; white-space: nowrap;
  font: 700 6px/1.45 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; font-style: normal;
  color: #f3dca0; background: rgba(20, 14, 6, .82); border: 1px solid rgba(226, 178, 74, .4);
}
body.en-campagne .mc-carte::before { content: var(--stamp-campagne, 'Campagne'); z-index: 2; }

/* ── Les fenetres ── */
.cg-voile {
  position: fixed; inset: 0; z-index: 3000; display: grid; place-items: center; padding: 16px;
  background: rgba(3, 5, 9, .78); backdrop-filter: blur(3px);
  animation: cgVoile .2s ease both;
}
@keyframes cgVoile { from { opacity: 0; } }
.cg-fenetre {
  display: flex; gap: 18px; align-items: flex-start; width: min(560px, 100%);
  padding: 20px; border-radius: 16px; background: var(--bg-2);
  border: 1.5px solid var(--line-gold); box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}
.cg-fenetre h2 { margin: 2px 0 8px; font-family: var(--font-title); }
.cg-fenetre p { color: var(--ink-dim); font-size: 14px; margin: 6px 0; }
.cg-fenetre-corps { min-width: 0; flex: 1 1 auto; }
.cg-visage {
  flex: 0 0 auto; width: 110px; height: 110px; border-radius: 50%; overflow: hidden;
  border: 2px solid var(--accent); background: radial-gradient(circle at 50% 35%, #2a3248, #0b0f18);
  display: grid; place-items: center;
}
.cg-visage img { width: 100%; height: 100%; object-fit: cover; }
.cg-citation {
  margin: 4px 0 10px; padding: 8px 12px; border-left: 3px solid var(--accent);
  background: rgba(245, 185, 66, .06); color: var(--ink); font-style: italic; font-size: 15px;
  border-radius: 0 8px 8px 0;
}
.cg-conseil { padding: 8px 10px; border-radius: 8px; background: rgba(56, 189, 248, .08); border: 1px solid rgba(56, 189, 248, .25); }
.cg-conseil b { color: var(--energy); }
.cg-ouverture-boite {
  width: min(900px, 100%); max-height: calc(100vh - 32px); overflow: auto;
  padding: 18px; border-radius: 16px; background: var(--bg-2); border: 1.5px solid var(--line-gold);
  text-align: center;
}
.cg-ouverture-boite h2 { font-family: var(--font-title); margin: 4px 0 14px; }
.cg-ouverture-boite .cg-gestes { justify-content: center; }
.cg-ouverture .cg-revele { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }

@media (max-width: 700px) {
  .cg-combats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cg-combat { flex-direction: column; gap: 6px; text-align: center; padding: 10px 6px; }
  .cg-combat-txt { align-items: center; }
  .cg-combat-txt b { white-space: normal; }
  .cg-coche, .cg-cadenas { position: absolute; top: 6px; right: 8px; margin: 0; }
  .cg-region { padding: 12px; }
  .cg-fenetre { flex-direction: column; align-items: center; text-align: center; }
  .cg-fenetre .cg-gestes { justify-content: center; }
  .cg-visage { width: 84px; height: 84px; }
  .cg-grille, .cg-revele, .cg-ouverture .cg-revele { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }
}

/* ── Le parcours sur la nappe (23/10/2026, campagne_nappe.js) : la nappe du
 * jeu en ruban, une region par ecran, les combats en flotteurs peints a sa
 * surface. Ici, le cadre, les flotteurs, la tete de region et le rail.
 *
 * LA NAPPE PREND TOUTE LA FENETRE (Alexandre : « prenons toute la fenetre »).
 * La boite de Solo s'efface : elle couvre la vue entiere, sans cadre ni fond,
 * la nappe en est le fond, et tout le reste -- les deux portes, le titre et
 * ses jauges, les onglets, le rail -- se pose par-dessus. Le cadrage de la
 * nappe se fait sur la zone que ces pieces laissent libre (campagne_nappe.js
 * les mesure). */
body.play-on .no-match:has(#campagne.est-parcours:not([hidden])) {
  inset: 0; transform: none; width: auto; max-width: none; height: auto; max-height: none;
  margin: 0; padding: 12px 20px; overflow: hidden;
  display: flex; flex-direction: column;
  background: none; border: 0; border-radius: 0; box-shadow: none;
}
#campagne.est-parcours { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; max-width: none; }
/* LE HUD (23/10) : des plaques sombres bordees d'or posees sur la nappe, la
 * meme famille que la plaque de region en bas. Titre a gauche, compteurs et
 * Cartable a droite. */
.cg-hud {
  position: relative; z-index: 4; display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px; pointer-events: none;
}
.cg-hud-plaque {
  pointer-events: auto;
  background: rgba(6, 5, 8, .86); border: 1px solid var(--line-gold); border-bottom: 2px solid var(--accent);
  border-radius: 12px; box-shadow: 0 6px 18px rgba(0, 0, 0, .5);
  padding: 6px 14px; color: var(--ink); font-family: var(--font-ui);
}
.cg-hud-titre { display: flex; flex-direction: column; line-height: 1.15; }
.cg-hud-titre small { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); font-weight: 700; }
.cg-hud-titre b { font-family: var(--font-title); font-size: 18px; color: var(--ink); white-space: nowrap; }
/*  LES COMPTEURS EN GRAND (Alexandre, 30/10/2026 : « les infos sur les
 *  cristaux, notre score, nombre d'etoiles doivent etre tres visibles ») :
 *  des plaques plus hautes et plus pleines, le signe et le chiffre en grand,
 *  ce qu'il compte en petites capitales dessous (campagne_vue.js, valeur). */
.cg-hud-droite { display: flex; align-items: stretch; gap: 10px; }
.cg-hud-droite .cg-hud-plaque {
  background: linear-gradient(180deg, rgba(30, 22, 12, .95), rgba(8, 6, 9, .95));
  border-width: 1.5px 1.5px 2px; border-radius: 14px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 224, 150, .14);
}
.cg-hud-compteur { display: flex; align-items: center; gap: 10px; padding: 8px 18px 8px 14px; white-space: nowrap; }
.cg-hud-compteur i {
  font-style: normal; color: var(--accent); font-size: 30px; line-height: 1;
  text-shadow: 0 0 14px rgba(255, 190, 60, .6), 0 2px 4px rgba(0, 0, 0, .8);
}
.cg-hud-etoiles i { color: #ffd25e; text-shadow: 0 0 16px rgba(255, 196, 64, .9), 0 2px 4px rgba(0, 0, 0, .8); }
.cg-hud-val { display: flex; flex-direction: column; justify-content: center; gap: 4px; line-height: 1; }
.cg-hud-val b {
  font-family: var(--font-num); font-size: 26px; font-variant-numeric: tabular-nums;
  color: #ffe9a8; text-shadow: 0 2px 6px rgba(0, 0, 0, .85);
}
.cg-hud-val small {
  font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-dim);
}
/*  LES CRISTAUX DU JOUEUR SUR LA CARTE (campagne_vue.js, compteurCristaux) :
 *  la ou vole ce qu'un niveau rapporte. Ils tournent sur eux-memes
 *  (envol_cristaux.js, IMG_CRISTAL), dans un halo de leur couleur. */
.cg-hud-cristaux { display: flex; align-items: center; gap: 18px; padding: 6px 18px 6px 10px; white-space: nowrap; }
.cg-cr { display: flex; align-items: center; gap: 8px; --cr: 255, 255, 255; }
.cg-cr :is(img, canvas) { height: 48px; width: auto; filter: drop-shadow(0 0 9px rgba(var(--cr), .55)) drop-shadow(0 2px 3px rgba(0, 0, 0, .7)); }
.cg-cr-ame { --cr: 255, 96, 110; }
.cg-cr-arcane { --cr: 110, 180, 255; }
.cg-cr-prisme { --cr: 206, 140, 255; }
.cg-cr-ame b { color: #ffa3a3; }
.cg-cr-arcane b { color: #a8d6ff; }
.cg-cr-prisme b { color: #e2c0ff; }
.cg-cr small { color: rgba(var(--cr), .85); }

/*  LE SCORE DU NIVEAU AU-DESSUS DE SA TUILE (campagne_vue.js,
 *  recompenseSurLaTuile) : trois etoiles qui paraissent, puis s'allument une
 *  a une ; les neuves brillent plus fort, puis s'envolent au compteur. */
.cg-score {
  position: fixed; z-index: 3150; left: 0; top: 0; display: flex; align-items: flex-end; gap: 4px;
  transform: translate(-50%, -100%); pointer-events: none;
}
.cg-score-etoile {
  font-size: 38px; line-height: 1; color: rgba(20, 16, 10, .55); -webkit-text-stroke: 1.5px rgba(255, 214, 120, .7);
  text-shadow: 0 3px 8px rgba(0, 0, 0, .7);
  animation: cg-score-entre .4s cubic-bezier(.3, 1.5, .5, 1) both; animation-delay: calc(var(--i) * 90ms);
}
.cg-score-etoile:nth-child(2) { font-size: 48px; margin-bottom: 8px; }
.cg-score-etoile.est-pleine {
  color: #ffd25e; -webkit-text-stroke: 1px #fff1c2;
  text-shadow: 0 0 12px rgba(255, 196, 64, .95), 0 0 28px rgba(255, 150, 30, .6), 0 3px 8px rgba(0, 0, 0, .6);
  animation: cg-score-plein .55s cubic-bezier(.3, 1.6, .5, 1) both;
}
.cg-score-etoile.est-neuve { color: #fff2b8; text-shadow: 0 0 16px #fff, 0 0 34px rgba(255, 200, 70, 1), 0 0 60px rgba(255, 150, 30, .8); }
@keyframes cg-score-entre { 0% { opacity: 0; transform: translateY(14px) scale(.2); } 100% { opacity: 1; transform: none; } }
@keyframes cg-score-plein { 0% { transform: scale(1); } 40% { transform: scale(1.75) rotate(-14deg); } 100% { transform: none; } }
.cg-score.est-sortie { animation: cg-score-sort .45s ease-in forwards; }
@keyframes cg-score-sort { to { opacity: 0; transform: translate(-50%, -125%) scale(.9); } }
/* La tuile qui donne s'allume le temps de la recompense. */
.cg-flot.est-recompense .cg-etape-rond { animation: cg-recompense 1.4s ease-in-out infinite alternate; }
@keyframes cg-recompense {
  from { box-shadow: 0 0 0 2px rgba(255, 214, 120, .5), 0 0 18px rgba(255, 190, 60, .45); }
  to { box-shadow: 0 0 0 3px rgba(255, 230, 160, .95), 0 0 42px rgba(255, 190, 60, .9); }
}
@media (max-width: 700px) {
  .cg-hud-cristaux { gap: 10px; padding: 4px 10px 4px 6px; }
  .cg-cr { gap: 4px; }
  .cg-cr :is(img, canvas) { height: 30px; }
  .cg-hud-val b { font-size: 17px; }
  .cg-hud-compteur i { font-size: 19px; }
  .cg-score-etoile { font-size: 30px; }
  .cg-score-etoile:nth-child(2) { font-size: 38px; margin-bottom: 6px; }
}
.cg-hud-cartable {
  display: flex; align-items: center; gap: 9px; padding: 7px 14px; cursor: pointer;
  font-family: var(--font-title); font-size: 14px; letter-spacing: .03em;
}
.cg-hud-cartable.cg-hud-cartable:hover:not(:disabled) {
  background: rgba(24, 17, 6, .94); border-color: var(--accent); transform: none;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .5), 0 0 14px var(--gold-glow);
}
/* Entre le telephone et le grand ecran, la place manque : les compteurs
 * perdent leur libelle (le titre de la plaque le dit), le chiffre reste grand. */
@media (max-width: 1180px) {
  .cg-hud-val small { display: none; }
}
@media (max-width: 960px) and (min-width: 701px) {
  .cg-hud-titre b { font-size: 15px; }
  .cg-hud-cartable span { display: none; }
}
/* Le petit classeur : un plat de cuir, son dos dore. */
.cg-hud-livre {
  width: 15px; height: 19px; border-radius: 2px 4px 4px 2px; flex: none;
  background: linear-gradient(90deg, var(--accent) 0 3px, #5a2a1c 3px);
  box-shadow: inset 0 0 0 1px rgba(255, 224, 138, .5);
}

/* LE CARTABLE DE CAMPAGNE : le vrai meuble (cartable.js), par-dessus le
 * parcours, sous la carte ouverte (.card-zoom, 3500). */
.cg-cartable-voile {
  position: fixed; inset: var(--topbar-h, 58px) 0 0 0; z-index: 2900;
  background: #07060b; animation: cgVoile .2s ease both;
}
.cg-cartable-voile > .cartable { height: 100%; }
/* Le parcours se cache sous le Cartable : quand une feuille tourne en 3D, le
 * fond du calque n'est plus peint et la nappe transparaissait. */
body.cg-cartable-ouvert #no-match { visibility: hidden; }
.cg-cartable-voile .cartable-tete { padding: 10px 18px 0; }
.cg-cartable-voile .ct-vers-etagere { margin-left: auto; }
/* Son cuir : celui du classeur des creatures, la ou la campagne commence. */
.cartable-corps[data-classeur="Campagne"] { --ct-cuir-img: url("https://medias.kairostcg.com/classeurs/cuir_Creature.webp"); --ct-cuir-fond: #3a1612; }
#campagne.est-parcours .cg-corps { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#campagne.est-parcours .cg-parcours { flex: 1 1 auto; min-height: 0; gap: 8px; display: flex; flex-direction: column; justify-content: flex-end; }
/* La zone de la nappe : toute la boite, derriere le reste. Rien entre elle et
 * la boite n'est positionne, si bien que `inset: 0` la cale sur la vue. */
.cg-nappe-zone { position: absolute; inset: 0; z-index: 0; }
/* Un voile en haut, sous les portes et le titre, pour qu'ils se lisent. */
.cg-nappe-zone::after {
  content: ''; position: absolute; inset: 0 0 auto; height: 190px; pointer-events: none; z-index: 2;
  background: linear-gradient(180deg, rgba(5, 4, 7, .86), rgba(5, 4, 7, .5) 60%, rgba(5, 4, 7, 0));
}
.cg-nappe-aide { margin: 0 0 2px; text-align: center; font-size: 12px; color: var(--ink-dim); position: relative; z-index: 4; pointer-events: none; text-shadow: 0 1px 3px #000; }
/* L'aide se range dans le coin : le milieu du bas est a la plaque de region. */
#campagne.est-parcours .cg-nappe-aide { position: absolute; left: 20px; bottom: 14px; text-align: left; max-width: calc(50% - 150px); }
#campagne.est-parcours .cg-fin { position: relative; z-index: 4; }

.cg-nappe {
  position: absolute; inset: 0; overflow: hidden;
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab;
  background: #07060a;
}
.cg-nappe.est-saisi { cursor: grabbing; }
.cg-nappe-fond, .cg-nappe-trace {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none;
}
/* Le lointain se perd dans l'ombre : la nappe fuit vers le haut. */
.cg-nappe::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 38%; pointer-events: none; z-index: 1;
  background: linear-gradient(180deg, rgba(5, 4, 7, .78), rgba(5, 4, 7, 0));
}
/* Le bord s'enfonce dans l'ombre, comme la nappe autour du plateau en partie. */
.cg-nappe::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 90px 20px rgba(4, 3, 6, .75);
}
.cg-nappe-calque { position: absolute; inset: 0; pointer-events: none; z-index: 1; }

/* UN FLOTTEUR : la peinture de l'element, le portrait pose sur son dessus.
 * Le point (x, y) est le centre du dessus ; il se balance doucement. */
.cg-flot {
  --flot-l: 112px;
  /* LE CENTRE DU DESSUS, MESURE SUR CHAQUE PEINTURE (23/10 : en Lumiere, le
   * portrait tombait sur les petales). `--haut` : la hauteur de l'image sur sa
   * largeur ; `--dessus` : ou tombe le centre du dessus, en part de la
   * hauteur. Le portrait s'y pose, et c'est ce point qui touche la nappe. */
  --haut: 0.72; --dessus: 0.38;
  --ancre: calc(var(--flot-l) * var(--haut) * var(--dessus));
  position: absolute; left: 0; top: 0; width: var(--flot-l);
  margin-left: calc(var(--flot-l) / -2); margin-top: calc(var(--ancre) * -1);
  /* L'echelle de la profondeur se prend au point pose sur la nappe. */
  transform-origin: 50% var(--ancre);
  will-change: transform;
}
.cg-flot.el-air { --haut: 0.74; --dessus: 0.39; }
.cg-flot.el-eau { --haut: 0.72; --dessus: 0.39; }
.cg-flot.el-terre { --haut: 0.75; --dessus: 0.42; }
.cg-flot.el-lumiere { --haut: 0.79; --dessus: 0.43; }
.cg-flot.el-ether { --haut: 0.79; --dessus: 0.43; }
.cg-flot.est-lieutenant { --flot-l: 128px; }
.cg-flot.est-gardien { --flot-l: 150px; }
/* CALE DANS LE LIQUIDE, ET QUI FLOTTE VRAIMENT (23/10 : « on ne sent pas
 * qu'ils sont dans un liquide, presque pas de mouvement »).
 *  - la LIGNE DE FLOTTAISON est une ellipse FIXE (le dessus du flotteur
 *    abaisse d'une demi-epaisseur : centre et rayon a 50 % / 41 %) ; le
 *    flotteur monte et descend a travers elle, et s'y enfonce ;
 *  - au-dessus : la peinture entiere (la moitie haute n'est jamais rognee :
 *    petales, cristaux et nuages depassent du dessus) ;
 *  - au-dessous : la meme peinture, sombre, delavee et tremblee -- vue a
 *    travers le liquide ;
 *  - la HOULE : soulevement, roulis et tangage, calcules a chaque image par
 *    campagne_nappe.js d'apres la place du flotteur sur la nappe (une onde la
 *    traverse) -- jamais deux fois le meme geste, partages par la peinture et
 *    le portrait. */
.cg-flot-img {
  display: block; width: 100%; height: auto; pointer-events: none;
  transform-origin: 50% 55%;
  /* La houle est calculee a chaque image (campagne_nappe.js) : --dy, --dx,
   * --rot, --sy, --enfonce. */
  transform: translate(var(--dx, 0px), var(--dy, 0px)) rotate(var(--rot, 0deg)) scaleY(var(--sy, 1));
}
.cg-flot-dessus {
  position: relative;
  -webkit-mask-image: linear-gradient(#000 0 50%, transparent 50%),
    radial-gradient(ellipse 50% 41% at 50% 50%, #000 99.4%, transparent 100%);
  mask-image: linear-gradient(#000 0 50%, transparent 50%),
    radial-gradient(ellipse 50% 41% at 50% 50%, #000 99.4%, transparent 100%);
}
.cg-flot-sous {
  position: absolute; inset: 0; pointer-events: none; opacity: .38;
  -webkit-mask-image: linear-gradient(transparent 0 50%, #000 50%),
    radial-gradient(ellipse 50% 41% at 50% 50%, transparent 99.4%, #000 100%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(transparent 0 50%, #000 50%),
    radial-gradient(ellipse 50% 41% at 50% 50%, transparent 99.4%, #000 100%);
  mask-composite: intersect;
  animation: cgRefraction 2.4s ease-in-out infinite alternate; animation-delay: var(--retard, 0s);
}
.cg-flot-sous .cg-flot-img { filter: brightness(.5) saturate(.5); }
/* L'ecume, sur la ligne de flottaison : l'arc bas de la meme ellipse. Un trait
 * net, pas une ombre floue (le cerne de la DA) ; il bat avec la houle. */
.cg-flot-ecume {
  position: absolute; left: 0; right: 0; top: 9%; height: 82%;
  border-radius: 50%; pointer-events: none;
  border: 2px solid transparent; border-bottom-color: rgba(255, 238, 205, .75);
  /* L'ecume s'elargit quand le flotteur plonge, se resserre quand il remonte. */
  transform: translateX(var(--dx, 0px)) scale(calc(.97 + .08 * var(--enfonce, .5)), calc(.96 + .1 * var(--enfonce, .5)));
  opacity: calc(.55 + .45 * var(--enfonce, .5));
}
.cg-flot-corps {
  position: absolute; inset: 0; pointer-events: none;
  transform-origin: 50% 55%;
  transform: translate(var(--dx, 0px), var(--dy, 0px)) rotate(var(--rot, 0deg)) scaleY(var(--sy, 1));
}
.cg-flot.est-verrouille .cg-flot-dessus .cg-flot-img { filter: saturate(.45) brightness(.62); }
.cg-flot.est-verrouille .cg-flot-ecume { border-bottom-color: rgba(255, 238, 205, .3); }
/* Sous la surface, l'image tremble : la refraction du liquide. */
@keyframes cgRefraction {
  from { transform: skewX(-2deg) translateX(-1px); }
  to { transform: skewX(2deg) translateX(1px); }
}

@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .cg-flot-sous { animation: none; }
}
/* Le bouton de l'etape, au centre du dessus du flotteur. Centre par `translate`
 * et non `transform` : `button:hover:not(:disabled)` (0,2,1) remplace le
 * transform par un translateY(-1px), et le portrait partait dans le vide au
 * survol (23/10, comme la piece de la Roue). Son fond de bouton aussi est
 * repris : sans quoi un rectangle bleu nuit apparaissait sous le portrait. */
.cg-nappe .cg-etape {
  position: absolute; left: 50%; top: calc(var(--dessus, 0.38) * 100%); translate: -50% -50%; transform: none;
  pointer-events: auto; z-index: 1;
}
.cg-nappe .cg-etape.cg-etape:hover:not(:disabled),
.cg-nappe .cg-etape.cg-etape:active:not(:disabled) {
  transform: none; background: none; border: 0; box-shadow: none;
}
/* LE PORTRAIT EST UNE PIECE, POSEE A PLAT (Alexandre, 23/10 : « des pastilles
 * epaisses avec un rebord dore, comme une piece »). Couchee sur le dessus du
 * flotteur, ecrasee au rapport de son ellipse (0,6, l'angle de la camera).
 *
 * UNE PIECE EST UN DISQUE PLAT, PAS UN ANNEAU (« on dirait un bagel dore ») :
 * le premier jet avait un rebord large en degrade conique, qui se lisait
 * bombe comme un tube, et une tranche haute dessous -- un tore. Ici, en
 * aplats et traits, comme la DA :
 *  - le REBORD : un anneau d'or PLAT, fin, cerne d'encre dehors ;
 *  - la TRANCHE : une bande basse d'or plus sombre (avant l'ecrasement, elle
 *    sort a 0,6 de sa hauteur), fermee par un trait d'encre ;
 *  - le FILET : un trait grave a l'interieur, et un liseré clair en haut du
 *    rebord, la lumiere qui accroche l'arete.
 * La coche et le cadenas restent debout, pour se lire. */
.cg-nappe .cg-etape-rond {
  --a-plat: 0.6;
  width: 60px; height: 60px; border: 3px solid #e2b24a;
  background: radial-gradient(circle at 50% 35%, #2a3248, #0b0f18);
  transform: scaleY(var(--a-plat));
  box-shadow:
    0 0 0 1.5px #3c2706,
    0 1px 0 1.5px rgb(196, 146, 52),
    0 2px 0 1.5px rgb(183, 135, 47),
    0 3px 0 1.5px rgb(170, 124, 42),
    0 4px 0 1.5px rgb(158, 112, 36),
    0 5px 0 1.5px rgb(145, 101, 31),
    0 6px 0 1.5px rgb(132, 90, 26),
    0 7px 0 1.5px #3c2706,
    0 9px 0 1px rgba(0, 0, 0, .4);
}
.cg-nappe .cg-etape.cg-etape .cg-etape-rond { border-color: #e2b24a; }
.cg-nappe .cg-etape-rond::before {
  content: ''; position: absolute; inset: -3px; border-radius: 50%; z-index: 1; pointer-events: none;
  border-top: 1.5px solid rgba(255, 246, 210, .85);
  box-shadow: inset 0 0 0 4.5px transparent, inset 0 0 0 5.5px rgba(60, 39, 6, .7);
}
.cg-nappe .cg-etape:not(:disabled):hover .cg-etape-rond { transform: scale(1.07, calc(var(--a-plat) * 1.07)); }
.cg-nappe .cg-etape-marque { transform: scaleY(calc(1 / var(--a-plat))); z-index: 2; }
.cg-nappe .cg-etape.cg-etape.est-lieutenant .cg-etape-rond {
  width: 68px; height: 68px; border-width: 3.5px;
  box-shadow:
    0 0 0 1.5px #3c2706,
    0 1px 0 1.5px rgb(196, 146, 52),
    0 2px 0 1.5px rgb(187, 138, 48),
    0 3px 0 1.5px rgb(178, 130, 45),
    0 4px 0 1.5px rgb(169, 122, 41),
    0 5px 0 1.5px rgb(159, 114, 37),
    0 6px 0 1.5px rgb(150, 106, 33),
    0 7px 0 1.5px rgb(141, 98, 30),
    0 8px 0 1.5px rgb(132, 90, 26),
    0 9px 0 1.5px #3c2706,
    0 11px 0 1px rgba(0, 0, 0, .4);
}
.cg-nappe .cg-etape.cg-etape.est-gardien .cg-etape-rond {
  width: 80px; height: 80px; border-width: 4px;
  box-shadow:
    0 0 0 1.5px #3c2706,
    0 1px 0 1.5px rgb(196, 146, 52),
    0 2px 0 1.5px rgb(189, 140, 49),
    0 3px 0 1.5px rgb(182, 134, 46),
    0 4px 0 1.5px rgb(175, 127, 43),
    0 5px 0 1.5px rgb(168, 121, 40),
    0 6px 0 1.5px rgb(160, 115, 38),
    0 7px 0 1.5px rgb(153, 109, 35),
    0 8px 0 1.5px rgb(146, 102, 32),
    0 9px 0 1.5px rgb(139, 96, 29),
    0 10px 0 1.5px rgb(132, 90, 26),
    0 11px 0 1.5px #3c2706,
    0 13px 0 1px rgba(0, 0, 0, .4);
}
/* Le prochain combat : la pulsation commune animait le box-shadow, elle
 * effacait la tranche. Ici, c'est un anneau a part qui bat autour de la piece. */
.cg-nappe .cg-etape.est-prochain .cg-etape-rond { animation: none; }
.cg-nappe .cg-etape.est-prochain .cg-etape-rond::after {
  content: ''; position: absolute; inset: -9px; border-radius: 50%; pointer-events: none;
  border: 2px solid rgba(255, 224, 138, .85);
  animation: cgPiece 1.6s ease-out infinite;
}
@keyframes cgPiece {
  0% { transform: scale(.92); opacity: .9; }
  100% { transform: scale(1.22); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .cg-nappe .cg-etape.est-prochain .cg-etape-rond::after { animation: none; } }
/* « Tu es ici » descend sur la medaille couchee, qui laisse un vide au-dessus. */
.cg-nappe .cg-ici { bottom: calc(100% - 9px); }
.cg-nappe .cg-etape-txt { top: calc(100% + 2px); background: rgba(6, 5, 8, .82); border: 1px solid rgba(201, 162, 70, .35); }
.cg-nappe .cg-etape-txt b { font-size: 12px; }
.cg-nappe .cg-etape-glyphe { font-size: 24px; }

/* La tete : la region regardee, entre deux fleches. */
/* En bas, sous le pouce : le haut appartient aux portes et au titre. */
.cg-nappe-tete {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 3;
  display: flex; align-items: center; gap: 8px;
}
.cg-nappe-fleche {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer; font-size: 20px; line-height: 1;
  display: grid; place-items: center; padding: 0;
  background: rgba(6, 5, 8, .82); color: var(--accent-light); border: 1px solid var(--line-gold);
}
.cg-nappe-fleche:disabled { opacity: .3; cursor: default; }
.cg-nappe-titre {
  --el: var(--accent);
  display: flex; flex-direction: column; align-items: center; min-width: 170px;
  padding: 5px 18px 6px; border-radius: 12px; line-height: 1.15; white-space: nowrap;
  background: rgba(6, 5, 8, .84); border: 1px solid var(--line-gold); border-bottom: 2px solid var(--el);
}
.cg-nappe-titre small { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--el); font-weight: 700; }
.cg-nappe-titre b { font-family: var(--font-title); font-size: 17px; color: var(--ink); }
.cg-nappe-titre span { font-family: var(--font-num); font-size: 11px; color: var(--accent-light); }
.cg-nappe-titre.el-feu { --el: var(--el-feu); }
.cg-nappe-titre.el-air { --el: var(--el-air); }
.cg-nappe-titre.el-eau { --el: #38a8e8; }
.cg-nappe-titre.el-terre { --el: var(--el-terre); }
.cg-nappe-titre.el-lumiere { --el: var(--el-lumiere); }
.cg-nappe-titre.el-ether { --el: var(--el-ether); }

@media (max-width: 700px) {
  body.play-on .no-match:has(#campagne.est-parcours:not([hidden])) { padding: 10px 10px; }
  .cg-tete { gap: 6px; justify-content: center; }
  .cg-tete-titre { align-items: center; width: 100%; }
  .cg-jauge { margin: 0; gap: 6px; }
  .cg-pastille { padding: 3px 9px; gap: 4px; white-space: nowrap; }
  .cg-pastille b { font-size: 13px; }
  .cg-pastille small { font-size: 10.5px; white-space: nowrap; }
  .cg-onglets { flex-wrap: nowrap; gap: 4px; }
  .cg-onglet { padding: 5px 10px; font-size: 12.5px; white-space: nowrap; }
  /* Au telephone : une ligne de HUD sans le titre (la plaque de region dit
   * ou l'on est) ; les compteurs sans leur libelle. */
  .cg-hud { justify-content: center; }
  .cg-hud-titre { display: none; }
  .cg-hud-droite { gap: 6px; }
  .cg-hud-compteur { gap: 6px; padding: 6px 12px 6px 10px; }
  .cg-hud-cartable { padding: 6px 12px; font-size: 13px; }
  /* Au telephone, la nappe prend toute la place : le geste se devine. */
  #campagne.est-parcours .cg-nappe-aide { display: none; }
  #campagne.est-parcours .cg-tete .no-match-kicker { display: none; }
  /* La tete en trois lignes courtes : le titre, les jauges, les onglets. */
  .no-match .cg-tete h1 { font-size: 17px; }
  .cg-jauge { flex-wrap: nowrap; }
  .cg-pastille .cg-long { display: none; }
  .cg-pastille .cg-court { display: inline; }
  .cg-flot { --flot-l: 92px; }
  .cg-flot.est-lieutenant { --flot-l: 104px; }
  .cg-flot.est-gardien { --flot-l: 120px; }
  .cg-nappe .cg-etape-rond { width: 50px; height: 50px; border-width: 2.5px; }
  .cg-nappe .cg-etape.cg-etape.est-lieutenant .cg-etape-rond { width: 56px; height: 56px; border-width: 3px; }
  .cg-nappe .cg-etape.cg-etape.est-gardien .cg-etape-rond { width: 66px; height: 66px; border-width: 3.5px; }
  .cg-nappe .cg-etape-txt { top: calc(100% + 0px); }
  .cg-nappe .cg-etape-txt b { font-size: 11px; }
  .cg-nappe-titre { min-width: 0; padding: 4px 12px; }
  .cg-nappe-titre b { font-size: 14px; }
  .cg-nappe-fleche { width: 30px; height: 30px; }
  .cg-nappe-tete { bottom: 14px; }
}


.cg-etape {
  --el: var(--accent);
  position: absolute; transform: translate(-50%, -50%); z-index: 1;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 0; border: 0; background: none; cursor: pointer; color: var(--ink);
  font-family: var(--font-ui);
}
.cg-etape:disabled, .cg-etape-fin { cursor: default; }
/* Le voile de `button:disabled` (0,45) les rendait translucides sur la peinture. */
.cg-etape:disabled { opacity: 1; }
.cg-etape-rond {
  position: relative; width: 62px; height: 62px; border-radius: 50%;
  display: grid; place-items: center;
  background: radial-gradient(circle at 50% 35%, #2a3248, #0b0f18);
  border: 2px solid rgba(160, 175, 205, .35);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .55);
  transition: transform .18s ease, border-color .18s ease;
}
.cg-etape-rond img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.cg-etape:not(:disabled):hover .cg-etape-rond { transform: scale(1.07); }
.cg-etape.est-gardien .cg-etape-rond { width: 80px; height: 80px; border-width: 3px; }
.cg-etape.est-gagne .cg-etape-rond { border-color: var(--accent); }
/* Sur un panneau peint et assombri, l'etape fermee doit rester lisible. */
.cg-etape.est-verrouille .cg-etape-rond img { filter: grayscale(1) brightness(.72); }
.cg-etape.est-verrouille .cg-etape-txt { opacity: .85; }
.cg-etape.est-prochain .cg-etape-rond {
  border-color: var(--accent-light);
  animation: cgPouls 1.6s ease-in-out infinite;
}
@keyframes cgPouls {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 185, 66, .55), 0 4px 14px rgba(0, 0, 0, .55); }
  50% { box-shadow: 0 0 0 10px rgba(245, 185, 66, 0), 0 4px 14px rgba(0, 0, 0, .55); }
}
.cg-etape-marque {
  position: absolute; right: -4px; bottom: -2px; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; font-style: normal; font-size: 11px;
  background: #11161f; border: 1.5px solid rgba(160, 175, 205, .4);
}
.cg-etape-marque.est-gagne { background: var(--accent); color: #1a1205; border-color: var(--accent-light); font-weight: 900; }
.cg-etape-glyphe { font-size: 28px; color: var(--accent-light); line-height: 1; }
.cg-etape-txt {
  /* Sous la pastille, HORS de la boite du bouton : c'est le centre du ROND
     qui se pose sur la halte peinte (translate -50 % de .cg-etape). */
  position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; line-height: 1.15;
  padding: 2px 8px; border-radius: 8px; background: rgba(6, 8, 13, .72);
}
.cg-etape-txt b { font-family: var(--font-title); font-size: 13px; white-space: nowrap; }
.cg-etape-txt small { font-size: 10px; color: var(--ink-dim); }
.cg-etape-gardien { color: var(--accent) !important; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.cg-ici {
  position: absolute; bottom: calc(100% + 2px); white-space: nowrap;
  padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--accent); color: #1a1205; box-shadow: 0 2px 10px rgba(245, 185, 66, .45);
}
.cg-etape-fin.est-verrouille .cg-etape-rond { opacity: .5; }
.cg-etape-fin.est-gagne .cg-etape-rond { border-color: var(--accent); box-shadow: 0 0 22px var(--gold-glow); }
.cg-parcours .cg-fin { max-width: 760px; margin: 12px auto 0; }

@media (max-width: 700px) {
  .cg-etape-rond { width: 52px; height: 52px; }
  .cg-etape.est-gardien .cg-etape-rond { width: 66px; height: 66px; }
}

/* ══ LA CAMPAGNE INFINIE ET LA RECOLTE (24/10/2026 ; recolte_ecran.js, campagne_vue.js) ══
   Le compteur de la partie : les cristaux d'ame et d'arcane volent du plateau
   jusqu'a lui. Puis le panneau de recolte de la fin, le prologue (element,
   classe), le calendrier. La famille des plaques du HUD de la Campagne. */
.recolte-partie {
  position: fixed; z-index: 40; right: 14px; top: calc(var(--topbar-h, 64px) + 12px);
  display: flex; flex-direction: column; align-items: stretch; gap: 6px; pointer-events: none;
  background: rgba(6, 5, 8, .82); border: 1px solid var(--line-gold); border-bottom: 2px solid var(--accent);
  border-radius: 12px; padding: 8px 12px; box-shadow: 0 6px 18px rgba(0, 0, 0, .5);
  font-family: var(--font-ui); color: var(--ink); min-width: 118px;
}
.recolte-partie .rp-titre { font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); font-weight: 700; }
.recolte-partie .rp-note { font-size: 10px; color: var(--ink-dim); max-width: 140px; line-height: 1.25; }
.recolte-partie.est-defaite .rp-plaque b { color: var(--ink-dim); }
.recolte-partie.rp-cache { visibility: hidden; }
.rp-plaque { display: flex; align-items: center; gap: 8px; --rp-teinte: 255, 255, 255; }
.rp-plaque b { font-family: var(--font-title); font-size: 20px; font-variant-numeric: tabular-nums; display: inline-block; }
.rp-ico { width: 28px; height: 28px; object-fit: contain; filter: drop-shadow(0 0 6px rgba(255, 255, 255, .15)); }
.rp-ame { --rp-teinte: 255, 96, 96; }
.rp-arcane { --rp-teinte: 110, 180, 255; }
.rp-ame b { color: #ff8a8a; }
.rp-arcane b { color: #8fc8ff; }

/*  L'ECRIN (recolte_ecran.js, plaque) : le halo respire derriere le cristal,
 *  l'ecrin flotte doucement. Rien que des transform et des opacites : la
 *  table 3D tourne a cote. Plus de reflet masque par l'image du cristal
 *  (30/10/2026) : le cristal tourne sur lui-meme, ses facettes prennent la
 *  lumiere d'elles-memes, et un masque fixe debordait de sa silhouette. */
.rp-ecrin { position: relative; display: inline-flex; flex: none; animation: rp-flotte 3.6s ease-in-out infinite; }
.rp-arcane .rp-ecrin { animation-delay: -1.8s; }
.rp-ecrin::before {
  content: ''; position: absolute; inset: -40%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(var(--rp-teinte), .42) 0%, rgba(var(--rp-teinte), .12) 42%, transparent 68%);
  animation: rp-halo 3.6s ease-in-out infinite; z-index: -1;
}
.rp-arcane .rp-ecrin::before { animation-delay: -1.8s; }
@keyframes rp-flotte { 0%, 100% { transform: translateY(1.5px); } 50% { transform: translateY(-2.5px); } }
@keyframes rp-halo { 0%, 100% { opacity: .55; transform: scale(.9); } 50% { opacity: 1; transform: scale(1.08); } }

/*  La reception : le cristal saute, une onde de sa couleur part de l'ecrin,
 *  le chiffre roule (compter) et s'allume. */
.rp-onde { position: absolute; inset: -10%; border-radius: 50%; pointer-events: none; opacity: 0;
  border: 2px solid rgba(var(--rp-teinte), .9); box-shadow: 0 0 12px rgba(var(--rp-teinte), .8), inset 0 0 8px rgba(var(--rp-teinte), .6); }
.rp-recoit .rp-onde { animation: rp-onde .6s ease-out; }
@keyframes rp-onde { 0% { opacity: 1; transform: scale(.5); } 100% { opacity: 0; transform: scale(2.3); } }
.rp-n.rp-monte { animation: rp-monte .7s ease-out; }
@keyframes rp-monte {
  0% { transform: scale(1); }
  30% { transform: scale(1.35); text-shadow: 0 0 12px rgba(var(--rp-teinte), 1), 0 0 2px #fff; color: #fff; }
  100% { transform: scale(1); }
}

/*  L'ENTREE (recolte_ecran.js, entrer) : le cadre s'ouvre depuis son milieu,
 *  le titre se resserre, puis chaque cristal tombe dans son ecrin en tournant
 *  et s'y pose dans un eclair. */
.recolte-partie.rp-entree { animation: rp-ouvre .55s cubic-bezier(.2, .8, .2, 1) both; }
.rp-entree .rp-titre { animation: rp-titre .8s .15s ease-out both; }
.rp-entree .rp-ico { animation: rp-chute .7s cubic-bezier(.3, 1.4, .5, 1) both; animation-delay: .35s; }
.rp-entree .rp-arcane .rp-ico { animation-delay: .55s; }
.rp-entree .rp-onde { animation: rp-onde .6s ease-out; animation-delay: .78s; }
.rp-entree .rp-arcane .rp-onde { animation-delay: .98s; }
.rp-entree .rp-n, .rp-entree .rp-note { animation: rp-paraitre .5s ease-out both; animation-delay: .9s; }
@keyframes rp-ouvre {
  0% { clip-path: inset(-30px 50% -30px 50%); opacity: 0; transform: translateY(8px); }
  100% { clip-path: inset(-30px -30px -30px -30px); opacity: 1; transform: none; }
}
@keyframes rp-titre { 0% { letter-spacing: .6em; opacity: 0; } 100% { letter-spacing: .16em; opacity: 1; } }
@keyframes rp-chute {
  0% { transform: translateY(-38px) rotate(-200deg) scale(.2); opacity: 0; }
  60% { opacity: 1; }
  100% { transform: none; opacity: 1; }
}
@keyframes rp-paraitre { 0% { opacity: 0; transform: translateX(-6px); } 100% { opacity: 1; transform: none; } }
/* Apres l'entree : place a la reception (meme image, regle ecrite plus bas). */
.rp-recoit .rp-ico { animation: rp-recoit .45s ease-out; }
@keyframes rp-recoit { 0% { transform: scale(1); } 40% { transform: scale(1.45); filter: drop-shadow(0 0 14px #fff); } 100% { transform: scale(1); } }
.rp-envol { position: fixed; z-index: 41; width: 30px; height: 30px; pointer-events: none; object-fit: contain;
  filter: drop-shadow(0 0 10px rgba(255, 255, 255, .55)); }

/*  LES CRISTAUX QUI VOLENT A LEUR COMPTEUR (js/envol_cristaux.js,
 *  29/10/2026) : en partie, en sortant d'un niveau, au cadeau du jour.
 *  Au-dessus de tout, fenetres comprises : ils sortent de l'une pour
 *  rejoindre l'autre. `--ec-teinte` : la couleur du cristal. */
.ec-cristal {
  position: fixed; z-index: 3200; left: 0; top: 0; height: var(--ec-h, 46px); width: auto;
  pointer-events: none; will-change: transform, opacity;
  filter: drop-shadow(0 0 7px rgba(var(--ec-teinte), .95)) drop-shadow(0 0 2px rgba(255, 255, 255, .8));
}
.ec-cristal.ec-trainee { filter: blur(2px) drop-shadow(0 0 10px rgba(var(--ec-teinte), 1)); }
.ec-glyphe { font-size: calc(var(--ec-h, 46px) * .8); line-height: 1; color: #ffd25e; text-shadow: 0 0 12px rgba(255, 190, 60, .9); }
.ec-eclat, .ec-anneau, .ec-onde {
  position: fixed; z-index: 3199; left: 0; top: 0; pointer-events: none; border-radius: 50%;
  transform: translate(-50%, -50%);
}
.ec-eclat {
  width: var(--ec-d); height: var(--ec-d); mix-blend-mode: screen;
  background: radial-gradient(circle, rgba(255, 255, 255, .95) 0%, rgba(var(--ec-teinte), .75) 20%, rgba(var(--ec-teinte), .22) 46%, transparent 70%);
  animation: ec-eclat .8s ease-out forwards;
}
@keyframes ec-eclat {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.3); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.25); }
}
.ec-anneau {
  width: var(--ec-d); height: var(--ec-d); border: 2px solid rgba(var(--ec-teinte), .9);
  box-shadow: 0 0 14px rgba(var(--ec-teinte), .8), inset 0 0 10px rgba(var(--ec-teinte), .6);
  animation: ec-anneau .75s cubic-bezier(.2, .7, .3, 1) forwards;
}
@keyframes ec-anneau {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(.15); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.1); }
}
.ec-onde {
  width: 34px; height: 34px; border: 2px solid rgba(var(--ec-teinte), .95); box-shadow: 0 0 12px rgba(var(--ec-teinte), .9);
  animation: ec-onde .6s ease-out forwards;
}
@keyframes ec-onde {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(.4); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(2.2); }
}

/*  POSE SUR LA NAPPE D'UN GRAND ECRAN (placerSurLaNappe, rp-large) : un peu
 *  plus grand, la place y est. En version jeu, le fleuron des tuiles sur le
 *  filet du bas (da_jeu.css). */
.recolte-partie.rp-large { min-width: 150px; padding: 11px 16px 14px; gap: 9px; }
.recolte-partie.rp-large .rp-titre { font-size: 10px; text-align: center; }
.recolte-partie.rp-large .rp-note { max-width: 150px; text-align: center; align-self: center; }
.recolte-partie.rp-large .rp-plaque { gap: 12px; }
.recolte-partie.rp-large .rp-ico { width: 32px; height: 46px; }
.recolte-partie.rp-large .rp-plaque b { font-size: 26px; }
html.mode-jeu .recolte-partie.rp-large::after {
  content: ''; position: absolute; left: 50%; bottom: -1px;
  width: 96px; aspect-ratio: 360 / 76; transform: translate(-50%, 50%);
  background: url(img/interface/ornement_fleuron.png?v=1) center / contain no-repeat;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .55));
}
/*  DANS LE PUPITRE DU DUEL, SOUS « LE DUEL » (logerDansLePupitre) : plus de
 *  plaque flottante, le compteur fait partie du pupitre. Les deux cristaux
 *  cote a cote, le titre au-dessus, la note dessous, puis le filet du
 *  pupitre (.module-rule) qui le separe du reste. */
.recolte-partie.rp-pupitre {
  position: relative; z-index: 1; right: auto; top: auto; flex: none;
  display: grid; grid-template-columns: 1fr 1fr; justify-items: center; align-items: center;
  gap: 6px 8px; min-width: 0; margin: 0 0 12px; padding: 0 2px 12px;
  background: none; border: 0; border-radius: 0; box-shadow: none;
}
.recolte-partie.rp-pupitre::after {
  content: ''; position: absolute; left: 5px; right: 5px; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, #74522f 20% 80%, transparent);
}
.rp-pupitre .rp-titre, .rp-pupitre .rp-note { grid-column: 1 / -1; text-align: center; }
.rp-pupitre .rp-note { max-width: none; }
.rp-pupitre .rp-plaque { gap: 9px; }
.rp-pupitre .rp-ico { width: 26px; height: 40px; }
.rp-pupitre .rp-plaque b { font-size: 24px; }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .rp-ecrin, :where(html:not(.mouvement-plein)) .rp-ecrin::before { animation: none; }
}
@media (max-width: 700px) {
  .recolte-partie { top: auto; bottom: calc(var(--main-h, 120px) + 10px); right: 8px; padding: 6px 9px; min-width: 0; }
  .recolte-partie .rp-note, .recolte-partie .rp-titre { display: none; }
  .rp-plaque b { font-size: 16px; }
  .rp-ico { width: 22px; height: 22px; }
  /*  Pose sur la nappe par recolte_ecran.js (placerSurLaNappe) : en ligne en
   *  haut, en colonne a droite. */
  .recolte-partie.rp-en-ligne { flex-direction: row; gap: 10px; padding: 3px 9px; border-radius: 999px; }
  .recolte-partie.rp-en-ligne .rp-ico { width: 18px; height: 18px; }
  .recolte-partie.rp-en-ligne .rp-plaque { gap: 5px; }
  .recolte-partie.rp-en-ligne .rp-plaque b { font-size: 14px; }
  .recolte-partie.rp-etroit { padding: 5px 3px; gap: 8px; border-radius: 10px; }
  .recolte-partie.rp-etroit .rp-plaque { flex-direction: column; gap: 1px; }
  .recolte-partie.rp-etroit .rp-plaque b { font-size: 13px; }
}

.recolte-fin { display: flex; flex-direction: column; gap: 10px; margin: 10px 0 4px; text-align: left; }
.rc-hors, .rc-deja, .rc-moitie { color: var(--ink-dim); font-size: 13px; margin: 0; }
.rc-etoiles { display: flex; justify-content: center; gap: 8px; font-size: 34px; }
.rc-etoile { color: rgba(255, 255, 255, .18); }
.rc-etoile.est-pleine { color: var(--accent); text-shadow: 0 0 14px rgba(245, 185, 66, .6); }
.rc-etoile.est-neuve { animation: rc-etoile .7s calc(var(--i) * .25s) cubic-bezier(.2, .9, .3, 1.4) both; }
@keyframes rc-etoile { 0% { transform: scale(0) rotate(-40deg); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
/*  Ce que chaque etoile demande, coche ou non (01/11/2026). */
.rc-criteres { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 0; padding: 0; list-style: none; }
.rc-critere { display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, .1); color: var(--ink-dim); font-size: 12px; }
.rc-critere.est-rempli { border-color: rgba(245, 185, 66, .5); color: var(--ink); }
.rc-critere-marque { font-style: normal; font-weight: 800; color: #e8675c; }
.rc-critere.est-rempli .rc-critere-marque { color: var(--accent); }
.rc-critere-quoi { display: flex; flex-direction: column; }
.rc-critere-quoi small { opacity: .75; }
.rc-gains { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.rc-multi { display: flex; align-items: center; gap: 4px; padding: 4px 10px; border-radius: 10px;
  border: 1px solid rgba(245, 185, 66, .6); color: var(--accent); }
.rc-multi i { font-style: normal; font-size: 11px; }
.rc-multi b { font-family: var(--font-title); font-size: 18px; }
.rc-gain { display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 10px;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .1); }
.rc-gain :is(img, canvas) { width: 26px; height: 26px; object-fit: contain; }
.rc-gain b { font-family: var(--font-title); font-size: 18px; }
.rc-gain small { color: var(--ink-dim); font-size: 11px; }
.rc-palier { display: flex; flex-direction: column; gap: 2px; padding: 8px 12px; border-radius: 10px;
  background: rgba(245, 185, 66, .1); border: 1px solid var(--line-gold); }
.rc-palier b { font-family: var(--font-title); font-size: 14px; }
.rc-palier span { font-size: 12px; color: var(--ink-dim); }
.rc-palier.est-prisme { background: linear-gradient(110deg, rgba(160, 110, 255, .2), rgba(80, 200, 255, .15), rgba(255, 140, 220, .2)); }
.rc-titre { margin: 4px 0 0; font-family: var(--font-title); font-size: 15px; }
.rc-titre small { font-family: var(--font-ui); font-size: 12px; color: var(--accent); }
.rc-tuiles { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px 10px;
  grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); }
.rc-tuile { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0;
  animation: rc-tuile .45s calc(var(--i) * 60ms) ease-out both; }
@keyframes rc-tuile { from { opacity: 0; transform: translateY(8px); } }
.rc-tuile-carte { position: relative; width: 100%; aspect-ratio: 320 / 503; border-radius: 6px; overflow: visible; }
.rc-tuile-carte img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; display: block;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .5); }
.rc-tuile.est-montee .rc-tuile-carte img { box-shadow: 0 0 0 2px var(--accent), 0 0 18px rgba(245, 185, 66, .55); }
/* Le badge de niveau : l'hexagone a feuilles peint (badges.py), le meme que
   dans la fiche (`.ex-badge`) et sur la carte en partie, dans le metal de sa
   tranche ; l'image : arene.css. Le chiffre, a la mesure du badge (cqw), sur
   son coeur d'onyx. */
.rc-badge { position: absolute; z-index: 1; left: -12%; bottom: -7%; width: 58%; aspect-ratio: 256 / 170;
  display: grid; place-items: center; container-type: inline-size;
  background: center / contain no-repeat; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .75)); }
.rc-badge b { position: relative; top: 4%; font-size: 24cqw; }
.rc-badge.est-neuf { animation: rc-badge .7s cubic-bezier(.2, .9, .3, 1.4); }
@keyframes rc-badge {
  0% { transform: scale(1); }
  40% { transform: scale(1.55); filter: brightness(1.4) drop-shadow(0 0 8px rgba(255, 206, 84, .95)); }
  100% { transform: scale(1); }
}
/* LA MONTEE DE NIVEAU (recolte_ecran.js, `eclater`) : la carte se souleve
   dans une lueur d'or et retombe ; « Niveau N » se pose. */
.rc-tuile.est-eclat .rc-tuile-carte { animation: rc-eclat .85s cubic-bezier(.2, .8, .3, 1.15); }
@keyframes rc-eclat {
  0% { transform: none; filter: none; }
  30% { transform: translateY(-9%) scale(1.14); filter: brightness(1.35) drop-shadow(0 0 16px rgba(255, 206, 84, .9)); }
  100% { transform: none; filter: none; }
}
.rc-tuile.est-eclat .rc-tuile-gain { animation: rc-niveau .55s cubic-bezier(.2, .9, .3, 1.5); }
@keyframes rc-niveau { 0% { opacity: 0; transform: scale(1.8); } 100% { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .rc-badge.est-neuf, :where(html:not(.mouvement-plein)) .rc-tuile.est-eclat .rc-tuile-carte, :where(html:not(.mouvement-plein)) .rc-tuile.est-eclat .rc-tuile-gain { animation: none; }
}
.rc-inspire { position: absolute; right: -5px; top: -5px; padding: 1px 5px; border-radius: 999px; font-size: 10px; font-weight: 800;
  background: #9fe0ff; color: #06202c; }
.rc-tuile .rc-barre { width: 100%; margin: 0; height: 4px; border-radius: 2px; overflow: hidden;
  background: rgba(255, 255, 255, .1); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .5); }
.rc-barre i { display: block; height: 100%; width: 0; border-radius: inherit;
  background: linear-gradient(90deg, #a8620f, #f5b942 60%, #ffe7a8);
  transition: width .6s cubic-bezier(.2, .7, .2, 1); }
.rc-tuile-gain { font-size: 11px; color: var(--ink-dim); white-space: nowrap; }
.rc-tuile.est-montee .rc-tuile-gain { color: var(--accent); font-weight: 700; }
.rc-plus { align-self: center; font-size: 12px; }

.cg-etape-difficile { color: #ff9a6a; }
/* Plus precis que `.cg-etape-txt small` (--ink-dim), qui les repeignait en
 * gris-bleu : les gagnees en or, celles qui manquent eteintes. */
.cg-etape-txt .cg-etape-etoiles { color: var(--accent); letter-spacing: 1px; }
.cg-etape-etoiles .est-manquante { color: rgba(255, 255, 255, .2); }

.cg-prologue { max-width: 980px; margin: 24px auto; padding: 0 16px; text-align: center; }
.cg-prologue h2 { font-family: var(--font-title); margin: 4px 0 8px; }
.cg-elements { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 18px 0; }
@media (max-width: 640px) { .cg-elements { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cg-element { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 12px; border-radius: 14px;
  background: var(--bg-2); border: 1.5px solid var(--line-gold); color: var(--ink); text-align: center; cursor: pointer; }
.cg-element:hover { border-color: var(--accent); translate: 0 -2px; }
.cg-element-ico { width: 46px; height: 46px; object-fit: contain; }
.cg-element b { font-family: var(--font-title); font-size: 18px; }
.cg-element-pouvoir { font-size: 13px; color: var(--accent); }
.cg-element-ligne { font-size: 12px; color: var(--ink-dim); line-height: 1.35; }
.cg-element-oppose { font-size: 11px; color: var(--ink-dim); border-top: 1px solid rgba(255, 255, 255, .08); padding-top: 6px; }
.cg-classes { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; margin: 18px 0; }
.cg-classe { display: flex; flex-direction: column; gap: 6px; padding: 16px; border-radius: 14px; text-align: left; cursor: pointer;
  background: var(--bg-2); border: 1.5px solid var(--line-gold); color: var(--ink); }
.cg-classe:hover { border-color: var(--accent); }
.cg-classe b { font-family: var(--font-title); font-size: 17px; }
.cg-classe span { font-size: 13px; color: var(--ink-dim); }
/*  La carte de la classe, tiree du deck de depart : en tete du bouton. */
.cg-classe:has(.cg-classe-carte) { align-items: center; text-align: center; }
.cg-classe-carte { width: min(150px, 100%); aspect-ratio: 320 / 503; object-fit: cover; border-radius: 8px; margin-bottom: 6px;
  box-shadow: 0 8px 18px rgba(0, 0, 0, .45); transition: translate .2s, box-shadow .2s; }
.cg-classe:hover .cg-classe-carte { translate: 0 -4px; box-shadow: 0 12px 24px rgba(0, 0, 0, .55); }
.cg-classe-note { font-size: 11px; color: var(--accent); margin-top: auto; padding-top: 4px; }
@media (max-width: 640px) {
  .cg-classes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cg-classe { padding: 10px; }
}
/*  CE QUE CONTIENT TON DECK (campagne_vue.js, `vueTypes`, 31/10/2026) : entre
 *  l'element et la classe, la bande des comptes puis une tuile par sorte de
 *  carte, sa carte en tete. Tout tient dans la fenetre : la carte prend la
 *  hauteur qui reste. */
.cg-prologue.cg-types { max-width: 1120px; margin: 14px auto; }
.cg-types-grille { --carte: clamp(64px, calc((100dvh - var(--topbar-h, 60px) - 420px) / 1.57), 132px);
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; margin: 14px 0 8px; }
.cg-type { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 12px 10px 14px; border-radius: 14px;
  background: var(--bg-2); border: 1.5px solid var(--line-gold); color: var(--ink); text-align: center;
  animation: cg-donne .45s cubic-bezier(.2, .8, .3, 1) both; animation-delay: calc(var(--i, 0) * 70ms); }
.cg-type.est-soutien { background: radial-gradient(120% 80% at 50% 0%, rgba(110, 180, 255, .1), transparent 60%), var(--bg-2); }
.cg-type-carte { width: var(--carte); aspect-ratio: 320 / 503; object-fit: cover; border-radius: 8px; margin-bottom: 4px;
  box-shadow: 0 8px 18px rgba(0, 0, 0, .45); }
.cg-type b { font-family: var(--font-title); font-size: 16px; }
.cg-type span { font-size: 12.5px; line-height: 1.4; color: var(--ink-dim); }
.cg-type-genre { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: #8cc4ff; }
.cg-types-note { margin: 4px 0 2px; font-size: 13px; }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .cg-type { animation: none; } }
@media (max-width: 640px) {
  .cg-types-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); --carte: 72px; }
  .cg-type { padding: 10px 8px; }
}
/*  La composition du deck de depart, avant de l'accepter : un panneau teinte
 *  de l'element, la bande des comptes, les cartes distribuees une a une.
 *  SUR PC, TOUT TIENT DANS LA FENETRE : les groupes se suivent dans un seul
 *  flux et la largeur d'une carte (--carte) se deduit de la hauteur libre. */
.cg-prologue.cg-vue-deck { max-width: none; margin: 12px auto; padding: 0 12px; }
.cg-deck-panneau { --carte: clamp(56px, calc((100dvh - var(--topbar-h, 60px) - 360px) / 3 / 1.57 - 12px), 104px);
  position: relative; display: flex; flex-direction: column; min-height: calc(100dvh - var(--topbar-h, 60px) - 24px);
  padding: 16px 28px 18px; border-radius: 20px; text-align: left; overflow: hidden;
  background: radial-gradient(120% 70% at 50% 0%, color-mix(in srgb, var(--el) 22%, transparent), transparent 62%), var(--bg-2);
  border: 1px solid var(--line-gold); box-shadow: 0 18px 50px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .06); }
.cg-deck-tete { display: flex; align-items: center; justify-content: center; gap: 14px; text-align: left; }
.cg-deck-tete h2 { margin: 0 0 2px; }
.cg-deck-tete .cg-region-texte { margin: 0; }
.cg-deck-tete .cg-el-ico { flex: none; width: 48px; height: 48px; filter: drop-shadow(0 0 14px color-mix(in srgb, var(--el) 70%, transparent)); }
.cg-deck-compte { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 4px 12px; margin: 12px auto 4px;
  padding: 6px 18px; width: fit-content; max-width: 100%; border-radius: 999px;
  background: rgba(0, 0, 0, .35); border: 1px solid rgba(255, 255, 255, .08); }
.cg-deck-stat { display: flex; align-items: baseline; gap: 6px; }
.cg-deck-stat b { font-family: var(--font-title); font-size: 20px; color: var(--ink); }
.cg-deck-stat span { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-dim); }
.cg-deck-stat.est-total b { color: var(--accent); }
.cg-deck-signe { font-style: normal; color: var(--ink-dim); font-size: 16px; }
.cg-deck-groupes { flex: 1; display: flex; flex-wrap: wrap; align-items: flex-start; align-content: center; justify-content: center; gap: 14px 30px; margin-top: 10px; }
.cg-deck-bloc { flex: 0 1 auto; min-width: 0; }
.cg-deck-bloc h3 { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; font-family: var(--font-title); font-size: 14px; color: var(--ink); white-space: nowrap; }
.cg-deck-bloc h3 small { font-family: inherit; font-size: 12px; color: var(--ink-dim); }
.cg-deck-bloc h3::after { content: ''; flex: 1; min-width: 20px; height: 1px; background: linear-gradient(90deg, var(--line-gold), transparent); }
.cg-deck-bloc.est-dominante h3 { color: var(--accent); }
.cg-deck-grille { display: flex; flex-wrap: wrap; gap: 9px; padding-top: 6px; }
/*  Pas de `transition: all` des boutons : la largeur doit se mesurer sur le champ (vueDeck). */
.cg-deck-carte { position: relative; flex: none; width: var(--carte); padding: 0; border: 0; background: none; cursor: pointer; border-radius: 6px; transition: none;
  animation: cg-donne .45s cubic-bezier(.2, .8, .3, 1) both; animation-delay: calc(var(--i, 0) * 30ms); }
.cg-deck-carte img { display: block; width: 100%; aspect-ratio: 320 / 503; object-fit: cover; border-radius: 6px;
  box-shadow: 0 5px 12px rgba(0, 0, 0, .5); transition: translate .18s, box-shadow .18s; }
.cg-deck-carte:hover img, .cg-deck-carte:focus-visible img { translate: 0 -4px;
  box-shadow: 0 10px 20px rgba(0, 0, 0, .55), 0 0 16px color-mix(in srgb, var(--el) 55%, transparent); }
.cg-deck-nb { position: absolute; right: -6px; top: -6px; min-width: 26px; padding: 3px 6px; border-radius: 999px;
  font-family: var(--font-title); font-size: 12px; line-height: 1; text-align: center; color: #1a1206;
  background: linear-gradient(180deg, #f7dd8c, #c9962f); box-shadow: 0 2px 6px rgba(0, 0, 0, .55); }
.cg-deck-nom { display: grid; place-items: center; aspect-ratio: 320 / 503; border-radius: 6px; background: var(--bg-2); font-size: 11px; }
.cg-deck-gestes { justify-content: center; margin-top: auto; padding-top: 14px; }
@keyframes cg-donne { from { opacity: 0; translate: 0 14px; rotate: -4deg; } }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .cg-deck-carte { animation: none; } }
/*  Au telephone on defile : des cartes a la largeur, quatre par rang. */
@media (max-width: 640px) {
  .cg-deck-panneau { min-height: 0; padding: 14px 12px; border-radius: 14px; }
  .cg-prologue.cg-vue-deck { padding: 0 8px; }
  .cg-deck-tete { gap: 10px; }
  .cg-deck-tete .cg-el-ico { width: 40px; height: 40px; }
  .cg-deck-compte { padding: 6px 12px; gap: 4px 8px; }
  .cg-deck-stat b { font-size: 17px; }
  .cg-deck-bloc { flex: 1 1 100%; }
  .cg-deck-bloc.est-energie, .cg-deck-bloc:has(+ .est-energie) { flex: 0 1 auto; }
  .cg-deck-grille { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; }
  .cg-deck-bloc:has(+ .est-energie) .cg-deck-grille { grid-template-columns: repeat(3, 66px); }
  .cg-deck-bloc.est-energie .cg-deck-grille { grid-template-columns: 66px; }
  .cg-deck-carte { width: auto; }
}

/* ══ TES EXEMPLAIRES, DANS LA FICHE (24/10/2026 ; exemplaires_ecran.js) ══ */
.ex-section { margin: 12px 0 4px; text-align: left; width: 100%; }
.ex-titre { font-family: var(--font-title); font-size: 15px; margin: 0 0 8px; }
.ex-attente, .ex-erreur, .ex-reussite { font-size: 13px; color: var(--ink-dim); margin: 4px 0; }
.ex-erreur { color: #ff9a8a; }
.ex-reussite { color: var(--accent); }
.ex-bandeau { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; margin: 0 0 8px;
  padding: 8px 10px; border-radius: 10px; background: rgba(245, 185, 66, .1); border: 1px solid var(--line-gold); }
.ex-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.ex-ligne { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: center;
  padding: 8px 10px; border-radius: 10px; background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .07); }
.ex-ligne.est-joue { border-color: var(--line-gold); }
.ex-ligne.est-source { background: rgba(245, 185, 66, .14); }
/* L'hexagone a feuilles peint (badges.py) : bronze 1-9, argent 10-19, or 20-29, prisme 30. */
.ex-badge { width: 74px; height: 48px; padding-top: 3px; box-sizing: border-box; display: grid; place-items: center; font-size: 14.5px;
  background: center / contain no-repeat; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .6)); }   /* l'image : arene.css */
:is(.ex-badge, .rc-badge) b { background-image: linear-gradient(180deg, #ffe8cf, #e5a97a 50%, #a8653a); }
:is(.ex-badge, .rc-badge)[data-tranche="1"] b { background-image: linear-gradient(180deg, #ffffff, #dfe6ee 50%, #9aa6b4); }
:is(.ex-badge, .rc-badge)[data-tranche="2"] b { background-image: linear-gradient(180deg, #fff7dc 0%, #f6dc93 40%, #d39a3a 100%); }
:is(.ex-badge, .rc-badge)[data-tranche="3"] b { background-image: linear-gradient(180deg, #ffffff, #e2d6ff 50%, #8fd8ff); }
.ex-milieu { min-width: 0; }
.ex-tete { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ex-tete b { font-size: 14px; }
.ex-tete small { color: #8fe08f; font-size: 11px; }
.ex-joue { font-style: normal; font-size: 11px; color: var(--accent); }
.ex-barre { height: 5px; border-radius: 3px; background: rgba(255, 255, 255, .1); overflow: hidden; margin: 4px 0 3px; }
.ex-barre i { display: block; height: 100%; background: var(--accent); }
.ex-detail { font-size: 11px; color: var(--ink-dim); }
.ex-gestes { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.ex-gestes button { font-size: 12px; padding: 5px 10px; }
.ex-confirmer { margin-top: 8px; padding: 10px; border-radius: 10px; background: rgba(0, 0, 0, .35); border: 1px solid var(--line-gold);
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ex-confirmer p { flex: 1 1 100%; margin: 0; font-size: 13px; }
.ex-auto { margin-top: 6px; font-size: 12px; }
/* « Voir les autres exemplaires » : sous le plus fort, discret, pleine largeur. */
.ex-plus { margin-top: 6px; width: 100%; font-size: 13px; }
.dl-niveaux { color: var(--accent); font-size: 10px; letter-spacing: .02em; }
@media (max-width: 560px) { .ex-ligne { grid-template-columns: auto minmax(0, 1fr); } .ex-gestes { grid-column: 1 / -1; justify-content: flex-start; } }

/* ══ LE CHOIX DE L'ELEMENT, SOIGNE (24/10/2026 ; campagne_vue.js) ══════════
   L'icone a la couleur de l'element, trois cartes en eventail, puis la vue
   d'un element ou son Pouvoir se JOUE sur deux cartes (.cg-scene). */
.cg-el-ico { display: inline-block; width: 34px; height: 34px; background: var(--el, var(--accent));
  -webkit-mask: var(--ico) center / contain no-repeat; mask: var(--ico) center / contain no-repeat;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--el, #fff) 55%, transparent)); }
.cg-el-ico.grand { width: 64px; height: 64px; }
.cg-elements .cg-element { position: relative; overflow: hidden; padding: 12px 12px 14px; gap: 5px;
  border-color: color-mix(in srgb, var(--el) 45%, var(--line-gold));
  background: radial-gradient(120% 70% at 50% 0%, color-mix(in srgb, var(--el) 20%, transparent), transparent 70%), var(--bg-2); }
.cg-elements .cg-element:hover { border-color: var(--el); box-shadow: 0 0 22px color-mix(in srgb, var(--el) 35%, transparent); }
.cg-element-tete { display: flex; align-items: center; gap: 8px; justify-content: center; }
.cg-element-tete b { font-family: var(--font-title); font-size: 19px; }
.cg-eventail { position: relative; height: 106px; width: 100%; margin: 2px 0 4px; }
.cg-eventail img { position: absolute; left: 50%; bottom: 0; width: 58px; aspect-ratio: 320 / 503; object-fit: cover; border-radius: 5px;
  translate: calc(-50% + var(--k) * 36px) 0; rotate: calc(var(--k) * 11deg); transform-origin: 50% 120%;
  box-shadow: 0 6px 14px rgba(0, 0, 0, .55); transition: translate .3s, rotate .3s; }
.cg-element:hover .cg-eventail img { translate: calc(-50% + var(--k) * 44px) -4px; rotate: calc(var(--k) * 15deg); }
.cg-eventail img:nth-child(2) { z-index: 1; width: 64px; }
.cg-eventail.grand { height: 172px; }
.cg-eventail.grand img { width: 92px; translate: calc(-50% + var(--k) * 62px) 0; }
.cg-eventail.grand img:nth-child(2) { width: 102px; }

.cg-vue-element { text-align: left; max-width: 900px; }
.cg-vue-tete { display: flex; align-items: center; gap: 16px; margin-bottom: 10px; }
.cg-vue-tete h2 { margin: 0; font-size: 30px; }
.cg-vue-corps { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 22px; align-items: center; }
.cg-vue-ligne { font-size: 17px; color: var(--ink); margin: 0 0 10px; line-height: 1.45; }
.cg-vue-oppose { display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin: 12px 0; border-radius: 12px;
  background: rgba(255, 255, 255, .04); border: 1px solid color-mix(in srgb, var(--el) 45%, transparent); font-size: 13px; }
.cg-vue-oppose .cg-el-ico { width: 28px; height: 28px; flex: none; }
.cg-vue-element .cg-gestes { justify-content: flex-start; margin-top: 18px; }
@media (max-width: 720px) { .cg-vue-corps { grid-template-columns: 1fr; } }

/* La scene : deux cartes face a face, le Pouvoir en boucle. */
.cg-scene { position: relative; height: 250px; border-radius: 16px; overflow: hidden;
  background: radial-gradient(80% 90% at 50% 100%, color-mix(in srgb, var(--el) 22%, transparent), transparent 70%), rgba(0, 0, 0, .35);
  border: 1px solid color-mix(in srgb, var(--el) 40%, transparent); }
.cg-scene-carte { position: absolute; bottom: 24px; width: 96px; aspect-ratio: 320 / 503; }
.cg-scene-carte img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; box-shadow: 0 8px 18px rgba(0, 0, 0, .6); }
.cg-scene-carte.moi { left: 18%; }
.cg-scene-carte.lui { right: 18%; }
.cg-scene-nrj { position: absolute; left: 50%; top: -24px; translate: -50% 0; display: flex; gap: 6px; }
.cg-scene-nrj i { width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, .85);
  background: radial-gradient(circle at 35% 30%, #fff, #ffd36a 45%, #c27c12); box-shadow: 0 0 10px rgba(255, 200, 90, .8);
  animation-duration: 3.2s; animation-iteration-count: infinite; animation-timing-function: ease-in-out; }
.cg-scene-texte { position: absolute; font-family: var(--font-title); font-size: 20px; opacity: 0; pointer-events: none;
  text-shadow: 0 2px 8px #000; white-space: nowrap; }
.cg-scene-texte.t1 { left: 18%; margin-left: 48px; translate: -50% 0; top: 22px; color: var(--accent); }
.cg-scene-texte.t2 { right: 18%; margin-right: 48px; translate: 50% 0; top: 22px; color: #ff8a7a; }
.cg-scene-fx { position: absolute; inset: 0; pointer-events: none; }
.cg-scene-p { position: absolute; width: 12px; height: 12px; border-radius: 50%; opacity: 0; pointer-events: none;
  background: var(--el); box-shadow: 0 0 12px var(--el); }
.cg-scene .cg-scene-texte, .cg-scene .cg-scene-carte, .cg-scene .cg-scene-fx, .cg-scene .cg-scene-p { animation-duration: 3.2s; animation-iteration-count: infinite; animation-timing-function: ease-in-out; }

/* FEU : ta carte frappe, l'autre s'embrase. */
.cg-scene.el-feu .moi { animation-name: sc-frappe; }
.cg-scene.el-feu .lui { animation-name: sc-touche; }
.cg-scene.el-feu .cg-scene-fx { right: 0; left: auto; width: 60%; animation-name: sc-flamme;
  background: radial-gradient(40% 50% at 70% 62%, rgba(255, 140, 40, .85), rgba(255, 60, 20, .35) 45%, transparent 70%); }
.cg-scene.el-feu .t1 { animation-name: sc-texte; }
.cg-scene.el-feu .t2 { animation-name: sc-texte2; }
/* EAU : une vague traverse ta carte, elle reprend des PV. */
.cg-scene.el-eau .cg-scene-fx { animation-name: sc-vague;
  background: linear-gradient(100deg, transparent 30%, rgba(80, 190, 255, .55) 45%, rgba(170, 230, 255, .8) 50%, rgba(80, 190, 255, .55) 55%, transparent 70%);
  background-size: 300% 100%; }
.cg-scene.el-eau .moi { animation-name: sc-soin; }
.cg-scene.el-eau .t1 { animation-name: sc-texte; color: #7ff0a0; }
/* AIR : trois traits de vent filent vers l'autre, ses energies s'envolent,
   puis l'icone d'etourdissement du jeu se pose sur lui. */
.cg-scene.el-air .cg-scene-fx { left: 14%; right: 14%; top: 30px; bottom: 40px; animation-name: sc-souffle;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 160' fill='none' stroke='white' stroke-linecap='round'><path d='M10 60 C 80 30, 150 30, 210 55 S 280 70, 270 45 S 245 30, 238 42' stroke-width='3' stroke-opacity='.75'/><path d='M30 95 C 110 75, 170 80, 240 95' stroke-width='2' stroke-opacity='.5'/><path d='M0 125 C 70 110, 140 112, 200 122 S 260 130, 255 112' stroke-width='2.5' stroke-opacity='.6'/></svg>") center / 100% 100% no-repeat; filter: drop-shadow(0 0 6px rgba(200, 235, 255, .8)); }
.cg-scene.el-air .cg-scene-p { display: none; }
.cg-scene.el-air .lui { animation-name: sc-vacille; }
.cg-scene.el-air .cg-scene-nrj .e0 { animation-name: sc-disperse; --dx: 40px; --dy: -70px; }
.cg-scene.el-air .cg-scene-nrj .e1 { animation-name: sc-disperse; --dx: 70px; --dy: -40px; animation-delay: .05s; }
.cg-scene.el-air .cg-scene-nrj .e2 { animation-name: sc-disperse; --dx: 85px; --dy: 10px; animation-delay: .1s; }
.cg-scene-etat { position: absolute; right: calc(18% + 48px); bottom: 78px; width: 54px; height: 54px; translate: 50% 0; opacity: 0;
  background: url("https://medias.kairostcg.com/icones/Etat_Etourdie.png?v=j1") center / contain no-repeat; filter: drop-shadow(0 2px 6px #000);
  animation: sc-etourdi 3.2s ease-in-out infinite; }
.cg-scene.el-air .t1 { animation-name: sc-texte; color: #ffd36a; left: auto; right: 18%; margin-right: 48px; translate: 50% 0; top: 14px; }
.cg-scene.el-air .t2 { animation-name: sc-texte2; color: #e3f3fd; font-size: 16px; top: 42px; }
/* TERRE : l'autre frappe, un bouclier arrete le coup. */
.cg-scene.el-terre .lui { animation-name: sc-frappe-g; }
.cg-scene.el-terre .cg-scene-fx { left: calc(18% - 30px); right: auto; width: 156px; animation-name: sc-bouclier;
  background: radial-gradient(50% 50% at 50% 55%, transparent 52%, rgba(120, 230, 170, .7) 56%, rgba(16, 185, 129, .25) 62%, transparent 68%); }
.cg-scene.el-terre .t1 { animation-name: sc-texte; color: #fff; font-size: 28px; }
.cg-scene.el-terre .t2 { animation-name: sc-texte2; color: #8fe0b8; left: 18%; right: auto; margin-left: 48px; translate: -50% 0; top: 56px; }
/* LUMIERE : deux energies descendent sur ta carte. */
.cg-scene.el-lumiere .cg-scene-p { left: calc(18% + 42px); top: -20px; animation-name: sc-descend; animation-delay: calc(var(--k) * .12s); }
.cg-scene.el-lumiere .cg-scene-p:nth-of-type(n+3) { display: none; }
.cg-scene.el-lumiere .moi { animation-name: sc-soin; }
.cg-scene.el-lumiere .t1 { animation-name: sc-texte; color: #ffe08a; }
/* ETHER : deux energies sont arrachees a l'autre et aspirees. */
.cg-scene.el-ether .cg-scene-fx { right: calc(18% - 42px); left: auto; width: 180px; top: -40px; bottom: auto; height: 150px; animation-name: sc-faille;
  background: conic-gradient(from 0deg, transparent, rgba(168, 85, 247, .6), transparent, rgba(168, 85, 247, .6), transparent);
  -webkit-mask: radial-gradient(circle, #000 30%, transparent 62%); mask: radial-gradient(circle, #000 30%, transparent 62%); }
/* Les deux premieres pastilles s'allument, se soulevent, tournent dans la
   faille et disparaissent ; la troisieme reste. Elles reviennent a la fin. */
.cg-scene.el-ether .cg-scene-p, .cg-scene.el-lumiere .cg-scene-p:nth-of-type(n+3) { display: none; }
.cg-scene.el-ether .cg-scene-nrj .e0 { animation-name: sc-arrache-g; }
.cg-scene.el-ether .cg-scene-nrj .e1 { animation-name: sc-arrache; }
.cg-scene.el-lumiere .cg-scene-nrj .e1, .cg-scene.el-lumiere .cg-scene-nrj .e2 { animation-name: sc-arrive; }
.cg-scene.el-lumiere .cg-scene-nrj .e2 { animation-delay: .12s; }
.cg-scene.el-ether .lui { animation-name: sc-vacille; }
.cg-scene.el-ether .t1 { animation-name: sc-texte; color: #d6b3ff; left: auto; right: 18%; margin-right: 48px; translate: 50% 0; }

@keyframes sc-frappe { 0%, 30%, 60%, 100% { transform: none; } 42% { transform: translateX(70px) rotate(6deg); } }
@keyframes sc-frappe-g { 0%, 30%, 60%, 100% { transform: none; } 42% { transform: translateX(-70px) rotate(-6deg); } }
@keyframes sc-touche { 0%, 42%, 100% { transform: none; filter: none; } 46% { transform: translateX(10px) rotate(4deg); filter: brightness(1.8) sepia(.6) saturate(3) hue-rotate(-20deg); } 60% { transform: none; filter: brightness(1.2) sepia(.3); } }
@keyframes sc-flamme { 0%, 40%, 80%, 100% { opacity: 0; transform: scale(.6); } 48% { opacity: 1; transform: scale(1.1); } 62% { opacity: .7; transform: scale(1); } }
@keyframes sc-vague { 0%, 15% { opacity: 0; background-position: 100% 0; } 25% { opacity: 1; } 55% { opacity: 1; background-position: 0 0; } 70%, 100% { opacity: 0; background-position: 0 0; } }
@keyframes sc-soin { 0%, 35%, 100% { filter: none; transform: none; } 50% { filter: brightness(1.35) drop-shadow(0 0 14px var(--el)); transform: translateY(-6px); } }
@keyframes sc-souffle { 0%, 12% { opacity: 0; transform: translateX(-40%) scaleX(.6); } 28% { opacity: 1; } 48% { opacity: .9; transform: translateX(10%) scaleX(1); } 62%, 100% { opacity: 0; transform: translateX(30%) scaleX(1.1); } }
@keyframes sc-vacille { 0%, 30%, 100% { transform: none; filter: none; } 40% { transform: translateX(14px) rotate(7deg); } 55% { transform: rotate(-3deg); filter: grayscale(.7) brightness(.8); } 85% { filter: grayscale(.7) brightness(.8); } }
@keyframes sc-envole { 0%, 35% { opacity: 0; transform: none; } 42% { opacity: 1; } 75% { opacity: 0; transform: translate(calc(80px + var(--k) * 12px), calc(-90px + var(--k) * 8px)) scale(.4); } 100% { opacity: 0; } }
@keyframes sc-bouclier { 0%, 30%, 75%, 100% { opacity: 0; transform: scale(.7); } 40% { opacity: 1; transform: scale(1.08); } 55% { opacity: .9; transform: scale(1); } }
@keyframes sc-descend { 0%, 15% { opacity: 0; transform: translateY(0); } 25% { opacity: 1; } 50% { opacity: 1; transform: translateY(150px); } 58%, 100% { opacity: 0; transform: translateY(160px) scale(.4); } }
@keyframes sc-faille { 0%, 20% { opacity: 0; transform: rotate(0deg) scale(.6); } 35% { opacity: 1; transform: rotate(120deg) scale(1); } 70% { opacity: 1; transform: rotate(320deg) scale(1); } 85%, 100% { opacity: 0; transform: rotate(400deg) scale(.6); } }
@keyframes sc-arrache { 0%, 18% { opacity: 1; transform: none; filter: none; } 26% { transform: scale(1.35); filter: brightness(1.6) hue-rotate(220deg); }
  34% { opacity: 1; transform: translate(0, -18px) scale(1.2); filter: hue-rotate(220deg); } 52% { opacity: 0; transform: translate(0, -46px) rotate(540deg) scale(.1); }
  90% { opacity: 0; transform: none; } 100% { opacity: 1; transform: none; filter: none; } }
@keyframes sc-arrache-g { 0%, 18% { opacity: 1; transform: none; filter: none; } 26% { transform: scale(1.35); filter: brightness(1.6) hue-rotate(220deg); }
  34% { opacity: 1; transform: translate(6px, -18px) scale(1.2); filter: hue-rotate(220deg); } 52% { opacity: 0; transform: translate(22px, -46px) rotate(540deg) scale(.1); }
  90% { opacity: 0; transform: none; } 100% { opacity: 1; transform: none; filter: none; } }
@keyframes sc-arrive { 0%, 46% { opacity: 0; transform: translateY(-30px) scale(.3); } 54% { opacity: 1; transform: translateY(0) scale(1.4); }
  62%, 88% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(.6); } }
@keyframes sc-disperse { 0%, 32% { opacity: 1; transform: none; } 40% { opacity: 1; transform: translate(calc(var(--dx) * .3), calc(var(--dy) * .3)) rotate(90deg); }
  62% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(360deg) scale(.4); } 90% { opacity: 0; transform: none; } 100% { opacity: 1; transform: none; } }
@keyframes sc-etourdi { 0%, 50% { opacity: 0; transform: translateY(10px) scale(.4) rotate(0deg); } 58% { opacity: 1; transform: translateY(0) scale(1.15) rotate(-12deg); }
  68% { transform: scale(1) rotate(10deg); } 78% { transform: rotate(-8deg); } 88% { opacity: 1; transform: rotate(0deg); } 100% { opacity: 0; } }
@keyframes sc-aspire { 0%, 30% { opacity: 0; transform: none; } 38% { opacity: 1; } 70% { opacity: 0; transform: translate(-20px, -60px) scale(.2); } 100% { opacity: 0; } }
@keyframes sc-texte { 0%, 45% { opacity: 0; transform: translateY(10px); } 55% { opacity: 1; transform: translateY(0); } 85% { opacity: 1; } 100% { opacity: 0; transform: translateY(-8px); } }
@keyframes sc-texte2 { 0%, 48% { opacity: 0; transform: translateY(10px) scale(.8); } 58% { opacity: 1; transform: translateY(0) scale(1.1); } 85% { opacity: 1; transform: scale(1); } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .cg-scene .cg-scene-texte { animation: none; opacity: 1; }
  :where(html:not(.mouvement-plein)) .cg-scene .cg-scene-carte, :where(html:not(.mouvement-plein)) .cg-scene .cg-scene-fx, :where(html:not(.mouvement-plein)) .cg-scene .cg-scene-p, :where(html:not(.mouvement-plein)) .cg-scene-nrj i, :where(html:not(.mouvement-plein)) .cg-scene-etat { animation: none; }
}

/* ══ LES AMIS ET LES BOOSTERS OFFERTS (amis.js, 24/10/2026) ══════════════════
 * La liste des amis, « Offrir » et le cadeau recu : l'habit des fenetres de
 * la Forge (.fs-voile, .fs-boite), le grimoire seul pour le cadeau, sans ruban (refuse le 24/10). */
.np-cadeau { color: #ffd77a; background: rgba(230, 170, 60, .14); box-shadow: inset 0 0 0 1px rgba(230, 170, 60, .4); }
.np-ami { color: #8fe0b8; background: rgba(60, 190, 130, .13); box-shadow: inset 0 0 0 1px rgba(60, 190, 130, .4); }
.boutique-offrir { --aura: #b57bff; }

.am-boite { width: min(480px, 100%); text-align: left; }
.am-boite > .fg-kicker, .am-boite > .fs-titre { text-align: center; }
.am-code { display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin-top: 6px; border-radius: 12px;
  background: rgba(201, 162, 39, .08); border: 1px dashed rgba(201, 162, 39, .5); }
.am-code-lib { font-size: 12px; color: var(--ink-dim, #b8b0c8); }
.am-code-val { flex: 1; font: 700 20px/1 ui-monospace, 'Cascadia Mono', Consolas, monospace; letter-spacing: .12em; color: #f3d57a; text-align: center; }
.am-copier { padding: 6px 10px; font-size: 12px; }
.am-aide { margin: 6px 0 12px; font-size: 12px; color: var(--ink-dim, #b8b0c8); text-align: center; }
.am-ajout { display: flex; gap: 8px; }
.am-ajout input, .am-mot { flex: 1; min-width: 0; padding: 9px 12px; border-radius: 10px; font: inherit; font-size: 14px;
  color: var(--ink, #e8e0f0); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .14); }
.am-ajout input { text-transform: uppercase; letter-spacing: .08em; }
.am-ajout input::placeholder { text-transform: none; letter-spacing: 0; }
.am-msg { min-height: 1em; margin: 6px 0 0; font-size: 12px; color: #f0a868; text-align: center; }
.am-msg:empty { display: none; }
.am-sous-titre { margin: 16px 0 6px; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: #c9a227; }
.am-vide { margin: 4px 0; font-size: 13px; color: var(--ink-dim, #b8b0c8); }
.am-ligne { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; margin-bottom: 6px; border-radius: 12px;
  background: rgba(255, 255, 255, .035); border: 1px solid rgba(255, 255, 255, .07); color: inherit; font: inherit; text-align: left; }
.am-ligne.est-attente { opacity: .7; }
.am-choix { cursor: pointer; transition: border-color .2s, background .2s; }
.am-choix:hover { border-color: rgba(201, 162, 39, .55); background: rgba(201, 162, 39, .07); }
.am-fleche { color: #c9a227; font-size: 18px; }
.am-avatar { flex: none; width: 38px; height: 38px; border-radius: 50%; overflow: hidden; display: grid; place-items: center;
  background: #2a1f18; border: 1px solid rgba(201, 162, 39, .45); font-weight: 700; color: #e8c56a; }
.am-avatar img { width: 100%; height: 100%; object-fit: cover; }
.am-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; overflow: hidden; text-overflow: ellipsis; }
.am-txt small { color: var(--ink-dim, #b8b0c8); font-style: italic; }
.am-gestes { display: flex; gap: 6px; flex: none; }
.am-gestes button, .am-ligne > button { padding: 6px 12px; font-size: 13px; }
.am-retirer { padding: 6px 9px !important; opacity: .6; }
.am-retirer:hover { opacity: 1; }
.am-cadeau-ligne { border-color: rgba(230, 170, 60, .5); background: rgba(230, 170, 60, .08); }
.am-confirmer { margin: 10px 0; padding: 10px 12px; border-radius: 12px; background: rgba(240, 120, 90, .08);
  border: 1px solid rgba(240, 120, 90, .4); display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.am-confirmer p { flex: 1 1 100%; margin: 0 0 4px; font-size: 13px; }

.am-offrir, .am-recu, .am-envoye { text-align: center; }
.am-pour { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 6px 0 10px; font-size: 16px; }
.am-paquet { position: relative; width: 132px; margin: 6px auto 12px; filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .6)); }
.am-paquet img { display: block; width: 100%; }
.am-nombre { position: absolute; right: -10px; bottom: -6px; z-index: 2; padding: 3px 9px; border-radius: 999px;
  font-size: 15px; color: #1a1206; background: linear-gradient(#ffe39a, #d9a93a); box-shadow: 0 3px 8px rgba(0, 0, 0, .5); }
.am-paquet.est-recu { animation: am-tremble 2.4s ease-in-out infinite; }
.am-paquet.est-ouvert { animation: am-ouvre .7s ease forwards; }
.am-paquet.est-parti { animation: am-part 1.6s ease-in-out forwards; }
@keyframes am-tremble { 0%, 70%, 100% { transform: none; } 76% { transform: rotate(-5deg); } 82% { transform: rotate(5deg); } 88% { transform: rotate(-3deg); } 94% { transform: rotate(2deg); } }
@keyframes am-ouvre { 0% { transform: scale(1); } 40% { transform: scale(1.12); filter: drop-shadow(0 0 30px rgba(243, 213, 122, .9)); } 100% { transform: scale(1.04); filter: drop-shadow(0 0 18px rgba(243, 213, 122, .6)); } }
@keyframes am-part { 0% { transform: none; opacity: 1; } 35% { transform: translateY(6px) scale(.96); } 100% { transform: translate(60px, -80px) rotate(14deg) scale(.5); opacity: 0; } }
.am-quantites { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.am-quantite { padding: 7px 12px; font-size: 13px; border-radius: 999px; }
.am-quantite.est-choisi, .am-quantite.est-choisi:hover:not(:disabled) { color: #1a1206; background: linear-gradient(#ffe39a, #d9a93a); border-color: transparent; }
/* Le survol general des boutons repeint le fond en sombre : celui qu'on
   survole prend une lueur doree, et le choisi garde son or. */
.am-quantite:not(.est-choisi):hover:not(:disabled) { color: #f3d57a; border-color: rgba(245, 185, 66, .6); }
.am-mot { display: block; width: 100%; box-sizing: border-box; }
.am-prix { margin: 12px 0 2px; font-size: 22px; font-weight: 700; color: #e3c8ff; display: flex; align-items: center; justify-content: center; gap: 6px; }
.am-prix .ic-prisme { width: 22px; height: 22px; }
.am-solde { margin: 0; font-size: 12px; color: var(--ink-dim, #b8b0c8); }
.am-solde.est-court { color: #f0a868; }
.am-pied { display: flex; justify-content: center; gap: 8px; }
.am-mot-recu { margin: 0 0 6px; font-style: italic; color: #f3dca0; }
/* LE PASSE OFFERT (25/10/2026) : un billet aux couleurs du passe de la
   Boutique (.boutique-passe), qui vit comme le grimoire. */
.am-passe { display: grid; gap: 3px; width: min(260px, 100%); margin: 6px auto 12px; padding: 14px 16px; border-radius: 14px;
  box-sizing: border-box; text-align: center;
  background: linear-gradient(120deg, rgba(190, 110, 255, .22), rgba(226, 178, 74, .16)), #1b1526;
  border: 1px solid rgba(226, 178, 74, .7);
  box-shadow: inset 0 0 0 4px rgba(26, 18, 6, .5), inset 0 0 0 5px rgba(226, 178, 74, .35), 0 10px 22px rgba(0, 0, 0, .6); }
.am-passe-kicker { font-size: 11px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: #c99bff; }
.am-passe-nom { font-size: 22px; color: #f3d57a; font-family: var(--font-titre, inherit); }
.am-passe-bonus { font-size: 12px; color: #e9d7ff; }
.am-passe.est-recu { animation: am-tremble 2.4s ease-in-out infinite; }
.am-passe.est-ouvert { animation: am-ouvre .7s ease forwards; }
.am-passe.est-parti { animation: am-part 1.6s ease-in-out forwards; }
.am-sorte { margin-bottom: 4px; }
.am-choix:disabled { cursor: default; opacity: .55; }
.am-choix:disabled:hover { border-color: inherit; background: none; }
.am-deja { color: var(--ink-dim, #b8b0c8); font-style: italic; font-size: 12px; }
@media (prefers-reduced-motion: reduce) { :where(html:not(.mouvement-plein)) .am-paquet, :where(html:not(.mouvement-plein)) .am-passe { animation: none !important; } }

/* ══ LE HALL DE SOLO (24/10/2026, campagne_vue.js `rendreHall`) ═════════════
 * « Cette page tres ordinaire... qu'elle prenne toute la fenetre ; on peut
 * sentir la campagne et son aventure, et meme chose plus simple pour Partie
 * libre » (Alexandre). Deux portes plein ecran : la Campagne fait defiler les
 * six regions peintes et flotter les iles du parcours ; la Partie libre montre
 * le plateau, sobrement. Les vues ouvertes gardent le fond de leur porte. */
body.play-on .no-match.est-plein {
  inset: 0; transform: none; width: auto; max-width: none; height: auto; max-height: none;
  margin: 0; padding: 14px 20px 20px; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; align-items: stretch;
  background: none; border: 0; border-radius: 0; box-shadow: none;
}
.no-match.est-plein > :not(.solo-fond) { position: relative; z-index: 1; }
/* Une vue ouverte (prologue, choix de l'element, decks) : un panneau sombre
 * pose sur le fond de sa porte, centre dans la hauteur. */
.no-match.est-plein > #campagne:not(.est-parcours):not([hidden]),
.no-match.est-plein > #solo-libre:not([hidden]) {
  width: min(1080px, 100%); margin: auto; padding: 26px 24px 24px; box-sizing: border-box;
  background: linear-gradient(180deg, rgba(16, 11, 8, .9), rgba(8, 6, 8, .94));
  border: 1px solid rgba(201, 162, 70, .32); border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .6);
}
.no-match.est-plein > #solo-libre:not([hidden]) { text-align: center; }

/* LE FOND DES PORTES : le panorama ou le plateau, assombris. */
.solo-fond { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.solo-fond .sh-panorama, .solo-fond-plateau { opacity: 0; transition: opacity .6s ease; }
.solo-fond .sh-panorama { filter: brightness(.3) saturate(.8) blur(1.5px); }
.solo-fond[data-porte="campagne"] .sh-panorama { opacity: 1; }
.solo-fond:not([data-porte="campagne"]) .sh-vue { animation-play-state: paused; }
.solo-fond-plateau { position: absolute; inset: -2%; background: url("https://medias.kairostcg.com/fonds/jeu_partie_v2_large.webp") center 40% / cover;
  filter: brightness(.16) saturate(.45) blur(2px); }
.solo-fond[data-porte="libre"] .solo-fond-plateau { opacity: 1; }
.no-match:has(#campagne.est-parcours:not([hidden])) .solo-fond { display: none; }

/* LE HALL. */
.no-match.est-plein > .solo-hall { position: absolute; inset: 0; display: flex; gap: 14px; padding: 14px; box-sizing: border-box; }
.no-match.est-plein > .solo-hall[hidden] { display: none; }
.sh-porte {
  position: relative; overflow: hidden; isolation: isolate; cursor: pointer;
  display: flex; align-items: flex-end; min-width: 0;
  border-radius: 18px; border: 1px solid rgba(201, 162, 70, .35);
  box-shadow: 0 20px 50px rgba(0, 0, 0, .55);
  transition: flex-grow .6s cubic-bezier(.2, .8, .2, 1), border-color .3s ease, box-shadow .3s ease;
}
/* Deux tiers pour la Campagne par defaut ; la porte survolee prend les deux
 * tiers (Alexandre, 24/10/2026). */
.sh-campagne { flex: 2 1 0; background: #120c08; }
.sh-libre { flex: 1 1 0; background: #0b0a10; }
.solo-hall:has(.sh-libre:hover) .sh-campagne { flex-grow: 1; }
.solo-hall:has(.sh-libre:hover) .sh-libre { flex-grow: 2; }
.sh-porte:hover {
  border-color: rgba(245, 185, 66, .8);
  box-shadow: 0 0 0 1px rgba(245, 185, 66, .25), 0 24px 60px rgba(0, 0, 0, .65), 0 0 46px rgba(245, 185, 66, .16);
}
/* LA VRAIE CARTE : six vues de la nappe, une par region, qui se succedent en
 * fondu (8 s chacune) avec un lent travelling. */
.sh-panorama { position: absolute; inset: 0; overflow: hidden; background: #120706; }
.sh-vue { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0;
  animation: sh-vue 48s linear infinite; animation-delay: calc(var(--i) * 8s - 1.5s); will-change: opacity, transform; }
.sh-vue:first-child { opacity: 1; }
@keyframes sh-vue {
  0% { opacity: 0; transform: scale(1.07) translateX(1.5%); }
  3% { opacity: 1; }
  16.7% { opacity: 1; }
  20% { opacity: 0; transform: scale(1) translateX(-1.5%); }
  100% { opacity: 0; transform: scale(1) translateX(-1.5%); }
}
.sh-campagne .sh-panorama { transition: filter .6s ease; filter: saturate(.95) brightness(.88); }
.sh-campagne:hover .sh-panorama { filter: saturate(1.1) brightness(1); }
/* Le voile : sombre a gauche et en bas, ou le texte se lit ; les regions
 * restent vives a droite. */
.sh-campagne::after, .sh-libre::after { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.sh-campagne::after {
  background:
    linear-gradient(90deg, rgba(6, 4, 2, .88) 0%, rgba(6, 4, 2, .5) 38%, rgba(6, 4, 2, .08) 70%),
    linear-gradient(0deg, rgba(6, 4, 2, .92) 0%, rgba(6, 4, 2, 0) 46%),
    radial-gradient(120% 90% at 50% 50%, transparent 60%, rgba(0, 0, 0, .55) 100%);
}
/* Le calque des braises, au-dessus de la carte. */
.sh-iles { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
/* Des braises qui montent : l'air bouge. */
.sh-poussiere { position: absolute; left: calc(var(--k) * 7% + 2%); bottom: -12px; width: 4px; height: 4px; border-radius: 50%;
  background: #ffd98a; box-shadow: 0 0 8px 2px rgba(255, 184, 74, .7); opacity: 0;
  animation: sh-monte 10s linear infinite; animation-delay: calc(var(--k) * -.73s); }
.sh-poussiere:nth-child(odd) { animation-duration: 13s; width: 3px; height: 3px; }
.sh-poussiere:nth-child(3n) { background: #bfe6ff; box-shadow: 0 0 8px 2px rgba(120, 190, 255, .6); }
@keyframes sh-monte { 0% { transform: translate(0, 0); opacity: 0; } 12% { opacity: .85; } 80% { opacity: .5; } 100% { transform: translate(34px, -78vh); opacity: 0; } }

.sh-texte { position: relative; z-index: 3; padding: clamp(20px, 3.6vw, 48px); max-width: 580px; text-align: left; }
.sh-kicker { display: block; font-size: 11px; font-weight: 700; letter-spacing: .32em; text-transform: uppercase; color: #e8c56a; }
.sh-titre {
  margin: 8px 0 10px; font-family: var(--font-title); font-size: clamp(42px, 6vw, 88px); line-height: .95; letter-spacing: .02em;
  color: #fff1d0; text-shadow: 0 4px 24px rgba(0, 0, 0, .85), 0 0 44px rgba(245, 185, 66, .28);
}
.sh-ligne { margin: 0 0 16px; max-width: 470px; font-size: clamp(14px, 1.25vw, 17px); line-height: 1.5; color: rgba(242, 230, 208, .86); }
.sh-etat { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 18px; }
.sh-etat:empty { display: none; }
.sh-pastille { display: inline-flex; align-items: center; padding: 5px 12px; border-radius: 999px; font-size: 13px;
  color: #f2e6cf; background: rgba(8, 6, 4, .66); border: 1px solid rgba(201, 162, 70, .45); backdrop-filter: blur(4px); }
.sh-pastille i { margin-right: 7px; font-style: normal; color: #f3d57a; }
.sh-gestes { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.sh-cta { padding: 13px 28px; font-size: 16px; border-radius: 12px; }
.sh-passer { padding: 12px 18px; background: rgba(6, 4, 2, .55); }

/* La Partie libre, plus sobre : le plateau dans l'ombre, qui s'eclaire au survol. */
.sh-plateau { position: absolute; inset: -3%; background: url("https://medias.kairostcg.com/fonds/jeu_partie_v2_large.webp") center 42% / cover;
  filter: saturate(.55) brightness(.42); transition: transform 1.4s cubic-bezier(.2, .8, .2, 1), filter .6s ease; }
.sh-libre:hover .sh-plateau { transform: scale(1.05); filter: saturate(.85) brightness(.58); }
.sh-libre::after { background: linear-gradient(0deg, rgba(5, 5, 9, .94) 0%, rgba(5, 5, 9, .35) 55%, rgba(5, 5, 9, .55) 100%); }
.sh-libre .sh-titre { font-size: clamp(30px, 3.6vw, 54px); color: #eef0f8; text-shadow: 0 4px 20px rgba(0, 0, 0, .85); }
.sh-libre .sh-kicker { color: #9fb0d8; }
.sh-cta-libre { color: #f3d57a; background: rgba(255, 255, 255, .06); border: 1px solid rgba(201, 162, 70, .6); }
.sh-cta-libre:hover:not(:disabled) { color: #ffe6a0; background: rgba(245, 185, 66, .14); }
/* Fermee avant le prologue de la Campagne (campagne_vue.js, `libreOuverte`). */
.sh-libre.est-verrouille .sh-plateau,
.sh-libre.est-verrouille:hover .sh-plateau { filter: grayscale(.85) brightness(.32); }
.sh-libre.est-verrouille .sh-titre { color: #b9bccb; }

@media (max-width: 700px) {
  .no-match.est-plein > .solo-hall { flex-direction: column; gap: 10px; padding: 10px; }
  .sh-campagne { flex: 1.7 1 0; }
  .solo-hall:has(.sh-libre:hover) .sh-campagne { flex-grow: 1.7; }
  .solo-hall:has(.sh-libre:hover) .sh-libre { flex-grow: 1; }
  .sh-campagne::after {
    background: linear-gradient(0deg, rgba(6, 4, 2, .94) 0%, rgba(6, 4, 2, .55) 50%, rgba(6, 4, 2, .1) 85%);
  }
  .sh-titre { font-size: 40px; }
  .sh-libre .sh-titre { font-size: 28px; }
  .sh-libre .sh-ligne { display: none; }
  .sh-texte { padding: 16px; }
  .sh-cta { padding: 11px 20px; font-size: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  :where(html:not(.mouvement-plein)) .sh-vue, :where(html:not(.mouvement-plein)) .sh-poussiere { animation: none; }
  :where(html:not(.mouvement-plein)) .sh-poussiere { display: none; }
}
