/* ═══════════════════════════════════════════════════════════════════════════
   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%);
  --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;
}
@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) .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) .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) .fantasy-bg-fx::before,
body:has(#view-accueil.is-on) .fantasy-bg-fx::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
}
body:has(#view-accueil.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) .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) .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) .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('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) .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) .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) main { position: relative; z-index: 1; }@media (prefers-reduced-motion: reduce) {
  body:has(#view-accueil.is-on) .poussiere-accueil { display: none; }
}
body:has(#view-accueil.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) .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) .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(--gold-grad);
  -webkit-mask: url(logo/kairos-symbole.png) center / contain no-repeat;
  mask: url(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: var(--font-title);
  font-weight: 900;
  letter-spacing: 0.24em;
  font-size: 19px;
  line-height: 1.1;
  background: var(--gold-grad);
  -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; }

/*  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; }
}

/* ── 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);
}
.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 {
  display: grid; grid-template-columns: 120px 1fr 48px; align-items: center; gap: 12px;
  padding: 10px 0;
}
.parametre-nom { font-weight: 700; font-size: 14px; }
.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; }
.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;
}

/* ══ 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) {
  .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: .2em; font-weight: 900;
  font-family: var(--font-title); line-height: 1.05;
  background: var(--gold-grad);
  -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-cap {
  position: absolute; left: 8px; bottom: 8px;
  font-size: 10px; font-weight: 800; letter-spacing: 0.04em;
  color: var(--accent); background: rgba(8, 11, 18, 0.85);
  border: 1px solid rgba(245, 185, 66, 0.35);
  border-radius: 6px; padding: 2px 6px;
  pointer-events: none; z-index: 12;
}
.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;
}
.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%;
  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(var(--ry, 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; }
.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));
}

/* 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; }

/* ══ 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 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;
}
.dp-cadre img { 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: 820px) 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); }
.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; }
/* 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) {
  .mc-carte.jouable { animation: none; filter: drop-shadow(0 0 8px rgba(255, 205, 110, .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; }
  /*  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; }
  .match-actions #quit { flex: 1 1 auto; padding-block: 8px; }
  .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; }

/* 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;
}

/* ── 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 {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  pointer-events: none; z-index: 48;
}
.dnp-val {
  font-family: var(--font-num); font-size: 38px; font-weight: 900;
  color: #fff;
  text-shadow:
    0 0 20px #ff2200,
    0 0 40px #ff5500,
    0 4px 10px rgba(0, 0, 0, 0.95);
  animation: dmgPopBounce 1.1s cubic-bezier(0.18, 0.89, 0.32, 1.28) forwards;
}
.damage-number-pop.ascendant .dnp-val {
  font-size: 48px;
  color: #fff5cc;
  text-shadow:
    0 0 25px #ffd700,
    0 0 55px #ff9900,
    0 0 80px #ff3300,
    0 4px 12px rgba(0, 0, 0, 0.98);
}
.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);
  animation: badgePop 1.1s ease-out forwards;
}

@keyframes dmgPopBounce {
  0% { transform: scale(0.2) translateY(20px); opacity: 0; }
  25% { transform: scale(1.35) translateY(-25px); opacity: 1; }
  45% { transform: scale(0.95) translateY(-32px); }
  70% { transform: scale(1.05) translateY(-42px); opacity: 1; }
  100% { transform: scale(0.9) translateY(-75px); opacity: 0; }
}
@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;
}
.death-burst {
  color: #ffd8d8; background: rgba(74,10,18,.9);
}
.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.show .match-result-panel { animation: resultReveal .85s cubic-bezier(.18,.8,.2,1.05) both; }
.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; }
}

.event-feed {
  position: absolute; z-index: 40; left: 132px; bottom: 16px;
  width: min(390px, calc(100% - 280px));
  display: flex; flex-direction: column; gap: 6px;
  pointer-events: none;
}
.event-card {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 11px; border-radius: 4px;
  color: #e8dcc4; background: rgba(10, 8, 8, .82);
  border: 1px solid rgba(201, 162, 70, .28);
  box-shadow: 0 6px 18px rgba(0,0,0,.35);
  backdrop-filter: blur(5px);
  font-size: 11px;
  animation: eventIn .3s ease-out both;
}
.event-card i { width: 16px; text-align: center; color: var(--accent); font-style: normal; }
.event-card.danger i { color: #ff6d62; }
.event-card.energy i { color: #66dcff; }
.event-card.heal i { color: var(--ok); }
.event-card.wheel i { color: var(--accent); }
.event-card.leaving { animation: eventOut .55s ease-in forwards; }
@keyframes eventIn {
  from { opacity: 0; transform: translateX(-18px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes eventOut {
  to { opacity: 0; transform: translateX(-12px); }
}

/* 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; }
.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;
  max-height: min(82vh, 650px); 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); }
.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; }
.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;
}
.jeter {
  position: absolute; inset: 0; z-index: 20;
  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; }
    .event-feed { left: 10px; bottom: 10px; width: calc(100% - 20px); }
  .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; }
.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; }
.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) {
  .vr-item .vr-carte, .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) { .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) { .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;
}

/* ── 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: 52.6%;
  --poche-y: 35.0%;
  --poche-l: 22.9%;
  --poche-h: 32.1%;
  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;
  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;
}
.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 {
  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;
}
/*  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;
  width: 100%; height: 100%; object-fit: cover; display: block;
  border-radius: 6px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, .6),
              inset 0 1px 0 rgba(255, 228, 170, .5);
  /*  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 carte du dessus porte l'ombre longue et le halo : c'est elle qu'on
 *  voit, les huit autres ne sont que son epaisseur. */
.pack-pile img:last-of-type {
  box-shadow: 0 18px 34px rgba(0, 0, 0, .85),
              0 0 22px rgba(245, 185, 66, .4),
              inset 0 1px 0 rgba(255, 236, 190, .65);
}

/*  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;
}
/*  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 {
  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); }
}

/* ── 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;
  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;
  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. */
.reveal-card-slot.parait {
  animation: carteParait .78s cubic-bezier(.16, 1, .28, 1) var(--app-delai, 0ms) both;
}
@keyframes carteParait {
  0% {
    opacity: 0;
    transform: perspective(900px) rotateX(-52deg) translateY(26px) scale(.74);
    filter: blur(9px) brightness(2.6);
  }
  38% { opacity: 1; filter: blur(3px) brightness(1.8); }
  72% {
    transform: perspective(900px) rotateX(0deg) translateY(0) scale(1.055);
    filter: blur(0) brightness(1.18);
  }
  100% {
    opacity: 1;
    transform: perspective(900px) rotateX(0deg) translateY(0) scale(1);
    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);
  animation: sceauAnneau .92s cubic-bezier(.15, .85, .3, 1) var(--app-delai, 0ms) 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);
}

/* 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. */
  background: #06080e;
  border: 2px solid var(--accent);
  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 {
  transform: translateY(-12px) 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 */
/* Une carte devoilee s'AGRANDIT au survol : c'est le moment ou l'on veut la
   lire -- l'illustration, les stats, le texte. Un simple soulevement de
   quatorze pixels ne montrait rien de plus qu'avant. */
.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. */
  transform: perspective(900px)
             rotateX(var(--tx, 0deg)) rotateY(var(--ty, 0deg))
             translateY(-24px) scale(1.55);
  z-index: 60;
  filter: drop-shadow(0 30px 50px rgba(0, 0, 0, .9))
          drop-shadow(0 0 34px 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) {
  .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) {
  .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: 820px) 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; }
  .tabs { gap: 2px; }
  .tab { padding: 7px 9px; }
  .tab-text { display: none; }
  .tab-glyph { font-size: 16px; }
  .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; }

  /* Le journal remonte au-dessus du pupitre, sinon il passe dessous. */
  /* LE JOURNAL SE REDUIT A SA DERNIERE LIGNE.
     Trois evenements empiles, chacun sur deux lignes a cette largeur, faisaient
     un pave de cent trente pixels pose en travers du plateau -- juste au-dessus
     du pupitre, c'est-a-dire pile sur la moitie basse de la table. Au large,
     trois lignes tiennent dans une marge vide ; ici, il n'y a pas de marge. On
     ne garde donc que le dernier evenement, sur une seule ligne. */
  .event-feed { left: 8px; right: 8px; width: auto; bottom: calc(var(--reserve-bas) + 6px); }
  .event-feed .event-card:nth-child(n + 2) { display: none; }
  .event-card {
    padding: 5px 9px; font-size: 10px; gap: 6px;
    background: rgba(10, 8, 8, .7);
    white-space: nowrap; overflow: hidden;
  }
  .event-card span { overflow: hidden; text-overflow: ellipsis; }
  .event-card i { width: 12px; flex: 0 0 auto; }
}

/* 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: 820px) 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-lien, .tab-caret { display: none; }
  .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; }


  /* ── 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; }

  /* ── 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); }
  .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; }
  .deck-name { min-width: 0; font-size: 13px; }
  #view-atelier.en-feuilles .reqs { flex: 1 1 100%; flex-wrap: wrap; gap: 4px; }
  .req { font-size: 10px; padding: 3px 8px; }
  #view-atelier.en-feuilles .deck-score { flex: 0 0 auto; flex-direction: row; align-items: baseline; gap: 4px; padding: 3px 8px; }
  .score-label { display: none; }
  .deck-score b { font-size: 16px; }
  #view-atelier.en-feuilles .deck-els-wrap { flex: 1 1 100%; min-width: 0; flex-wrap: wrap; }
  .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%; }
  #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;
  }
  .fan-peek { display: none; }
  #view-atelier.en-feuilles .saved-decks-bar { flex: 1 1 100%; gap: 6px; margin-top: 4px; }
  .saved-decks-lbl { display: none; }
  .saved-deck { padding: 3px 8px 3px 10px; }
  .saved-deck .sd-name { font-size: 11px; }

  /* ── LA FEUILLE DES FILTRES ── */
  #view-atelier.en-feuilles .filters {
    flex-direction: column; gap: 9px; max-height: 74vh;
    border-right: none;
  }
  .filter-title { font-size: 10px; }
  .search-box input { padding-top: 7px; padding-bottom: 7px; font-size: 16px; }
  #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;
  }
  .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; }

  /* 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; }

  /* 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-cap, .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; }
  .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; }
}

/* 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%; }
}


/* ══ L'ATELIER DU FOND ══════════════════════════════════════════════════════
 *
 * Un panneau de reglage, pas un element de jeu : il emprunte les couleurs de
 * l'interface mais assume d'etre un outil -- lisible, dense, sans decor. Il
 * flotte par-dessus la table, du cote oppose au cadran, et se ferme des qu'on
 * a fini.
 */
.atelier-fond {
  position: fixed; z-index: 90;
  left: 12px; top: 12px; width: min(310px, calc(100vw - 24px));
  max-height: calc(100dvh - 24px); overflow-y: auto;
  padding: 12px 13px 11px;
  border: 1px solid var(--line-gold); border-radius: 12px;
  background: rgba(10, 8, 14, .95);
  backdrop-filter: blur(12px);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .8);
  color: var(--ink);
  font-size: 11px;
}
.af-tete { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.af-tete b {
  font-family: var(--font-title), Georgia, serif;
  font-size: 12px; letter-spacing: .06em; color: var(--accent);
}
.af-x {
  width: 24px; height: 24px; padding: 0; border-radius: 6px;
  font-size: 12px; line-height: 1;
}
/* Les six elements, chacun avec la pastille de SA couleur : on choisit celui
   qu'on regle en le reconnaissant, pas en lisant son nom. */
.af-elements { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-bottom: 10px; }
.af-el {
  display: flex; align-items: center; gap: 5px;
  padding: 5px 6px; border-radius: 6px;
  font-size: 10px; font-weight: 700;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
}
.af-el::before {
  content: ''; width: 10px; height: 10px; border-radius: 50%;
  background: var(--puce, #888); box-shadow: 0 0 6px var(--puce, #888);
  flex: 0 0 auto;
}
.af-el.is-on { border-color: var(--accent); background: rgba(255, 190, 77, .12); color: var(--ink-bright); }

.af-groupe { margin-bottom: 9px; }
.af-titre {
  font-size: 9px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 5px;
}
.af-curseurs { display: flex; flex-direction: column; gap: 5px; }
/* Trois colonnes fixes : le nom, la reglette, la valeur. Alignees, les cinq
   lignes se lisent comme un tableau de bord et non comme cinq formulaires. */
.af-c { display: grid; grid-template-columns: 76px minmax(0, 1fr) 42px; align-items: center; gap: 7px; }
.af-n { color: var(--ink-dim); }
.af-v { font-family: var(--font-num), Georgia, serif; text-align: right; color: var(--ink-bright); }
.af-c input[type="range"] { width: 100%; accent-color: var(--accent); height: 18px; }

.af-pied { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-top: 10px; }
.af-pied button { padding: 6px 9px; font-size: 10px; border-radius: 6px; }
.af-enr { background: var(--gold-grad); color: #1a1202; border-color: #ffe082; font-weight: 800; }
.af-mot { flex: 1 1 100%; color: var(--ok); font-size: 10px; min-height: 13px; }

/* Le bouton d'ouverture, sous le drapeau d'abandon. */
.arena-ctrl-palette::before { content: '◐'; font-size: 15px; line-height: 1; }
.arena-ctrl-palette { color: #cbb6e8; }

@media (max-width: 820px) and (orientation: portrait) {
  /* En portrait il prend toute la largeur : les reglettes ont besoin de course
     pour etre reglables au doigt. */
  .atelier-fond { left: 8px; right: 8px; width: auto; top: 8px; font-size: 12px; }
  .af-c { grid-template-columns: 72px minmax(0, 1fr) 40px; }
  .af-c input[type="range"] { height: 26px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   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) {
  .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; }

/* ── 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);
}

/* ── 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; }
}


/* ── 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); }

/* 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;
}
@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; }
}
@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);
}
.aw-texte {
  margin: 0; text-align: center;
  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; }
.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; }
}


/* ══════════════════════════════════════════════════════════════════════════
   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     */

  height: 100%;
  display: flex; flex-direction: column;
  min-height: 0;
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(201, 162, 39, .10), transparent 60%),
    linear-gradient(180deg, #0b0910 0%, #07060b 100%);
}

/* ── 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: clamp(4px, 1vw, 16px);
  perspective: 2600px;
  perspective-origin: 50% 44%;
}

.cart-reliure {
  position: relative;
  height: 100%;
  /* 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: 100%;
  display: grid; grid-template-columns: 1fr 1fr;
  transform-style: preserve-3d;
  border-radius: 6px;
  background: linear-gradient(180deg, #443d51 0%, var(--ct-cuir) 55%, #2c2735 100%);
  box-shadow:
    0 40px 90px rgba(0, 0, 0, .72),
    0 0 0 1px rgba(201, 162, 39, .22),
    inset 0 0 0 1px rgba(0, 0, 0, .35);
}

/* Une page : le plastique de la pochette, pose sur le carton du classeur. */
.cart-page {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  padding: var(--ct-marge);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012)),
    linear-gradient(160deg, var(--ct-feuille) 0%, var(--ct-feuille-b) 100%);
  cursor: pointer;
}
/* Une feuille se creuse vers le pli : c'est cette ombre-la, et elle seule,
   qui donne l'epaisseur du classeur. */
.cart-page--g {
  border-radius: 8px 2px 2px 8px;
  box-shadow: inset -28px 0 40px -25px rgba(0, 0, 0, .92);
}
.cart-page--d {
  border-radius: 2px 8px 8px 2px;
  box-shadow: inset 28px 0 40px -25px rgba(0, 0, 0, .92);
}
.cart-page.est-vide {
  background: 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);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .09),
    inset 0 -6px 10px -8px rgba(0, 0, 0, .8);
  /*  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 {
  position: absolute; left: 50%; top: 0; bottom: 0;
  width: 26px;
  /*  PAS DE `translateZ` ICI.
      `.cart-reliure` est en `preserve-3d` : ses enfants y sont tries par leur
      POSITION DANS L'ESPACE, et le z-index ne les departage qu'a profondeur
      egale. Le pli portait un `translateZ(1px)` -- un pixel devant les pages,
      donc devant TOUT, y compris une carte qu'on tient et qu'on venait de
      lever avec sa page. Le trait du pli barrait la carte. Remis a plat, le
      z-index reprend la main. */
  transform: translateX(-50%);
  pointer-events: none;
  background:
    linear-gradient(90deg,
      rgba(0, 0, 0, .7) 0%,
      rgba(0, 0, 0, .3) 34%,
      rgba(0, 0, 0, .9) 47%,
      rgba(201, 162, 39, .16) 50%,
      rgba(0, 0, 0, .9) 53%,
      rgba(0, 0, 0, .3) 66%,
      rgba(0, 0, 0, .7) 100%);
}
.cart-anneaux i { display: none; }

/* ── La feuille qui tourne ───────────────────────────────────────────── */
.cart-feuille {
  position: absolute; top: 0; bottom: 0; width: 50%;
  transform-style: preserve-3d;
  transition: transform .62s 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; }

.cart-face {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  display: flex; align-items: center; justify-content: center;
  padding: var(--ct-marge);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012)),
    linear-gradient(160deg, var(--ct-feuille) 0%, var(--ct-feuille-b) 100%);
  box-shadow: 0 0 34px rgba(0, 0, 0, .6);
}
.cart-face--verso { transform: rotateY(180deg); }
.cart-feuille--d .cart-face--recto { border-radius: 2px 8px 8px 2px; }
.cart-feuille--d .cart-face--verso { border-radius: 8px 2px 2px 8px; }
.cart-feuille--g .cart-face--recto { border-radius: 8px 2px 2px 8px; }
.cart-feuille--g .cart-face--verso { border-radius: 2px 8px 8px 2px; }

/* 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; }

/* ── 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 (max-width: 900px), (orientation: portrait) and (max-width: 1100px) {
  /*  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; }
  .cart-reliure {
    aspect-ratio: calc(var(--ct-cols) * 1024) / calc(var(--ct-rangs) * 1610);
    grid-template-columns: 1fr;
  }
  .cart-page--g, .cart-anneaux { display: none; }
  .cart-page--d { border-radius: 8px; box-shadow: none; }
  .cart-feuille { width: 100%; }
  .cart-feuille--d { left: 0; transform-origin: left center; }
  .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;
    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; }
}

/* ══ 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);
}
.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 quarante cartes */
.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-pied .dg-go { flex: 1 1 100%; order: 3; }
  .dg-atelier { flex: 1 1 100%; order: 4; min-height: 44px; }
  .dg-note { font-size: .8rem; }
}

/* 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). */
.cart-pastille-free {
  position: absolute; top: 6px; left: 6px; z-index: 4;
  padding: 2px 7px; border-radius: 999px;
  font-family: var(--font-title); font-size: .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: 6px; right: 6px; z-index: 4;
  min-width: 1.5em; padding: 2px 6px; border-radius: 999px;
  font-family: var(--font-num), Georgia, serif;
  font-size: .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; }
/*  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(.9) brightness(1.15);
  background: radial-gradient(circle at 40% 32%,
              color-mix(in srgb, var(--el-color) 18%, #232c42) 0%, #10141f 100%);
  border-color: color-mix(in srgb, var(--el-color) 70%, transparent);
}
.roue-table .roue-piece:not(.is-on) .el-ico { filter: drop-shadow(0 0 4px var(--el-color)); }
.roue-table .roue-coeur {
  background: radial-gradient(circle, #222b40 0%, #10141f 100%);
  border-color: rgba(245, 185, 66, .65);
}
.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(62, 52, 84, .7) 0%, rgba(26, 30, 46, .82) 62%, rgba(14, 16, 26, .9) 100%);
  border-color: rgba(245, 185, 66, .7);
}

/* 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 { filter: brightness(1.08); }

/*  ══ 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 { color: var(--ink-bright); border-color: var(--ink-faint); }

/*  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; }
  .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; }
}

/* ══ 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; }
}
@media (prefers-reduced-motion: reduce) {
  .achat-fete *, 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) { .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) { .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)); } }

/* ══ 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; }
.moment-rarete.is-supreme .mr-rayons {
  display: block; position: absolute; left: 50%; top: 42%; width: 1500px; height: 1500px; margin: -750px 0 0 -750px;
  border-radius: 50%;
  background: repeating-conic-gradient(color-mix(in srgb, var(--rc) 30%, transparent) 0deg 5deg, transparent 5deg 15deg);
  -webkit-mask: radial-gradient(circle, #000, transparent 58%); mask: radial-gradient(circle, #000, transparent 58%);
  animation: af-tourne 40s linear infinite;
}
.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) { .mr-carte, .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 {
  transform: perspective(900px)
             rotateX(var(--tx, 0deg)) rotateY(var(--ty, 0deg))
             translateY(-24px) scale(1.55);
  z-index: 60;
  filter: drop-shadow(0 30px 50px rgba(0, 0, 0, .9))
          drop-shadow(0 0 34px 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) { .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; }
.vitrine-tirage.is-supreme .mr-rayons {
  display: block; position: fixed; left: 50%; top: 45%; width: 1500px; height: 1500px; margin: -750px 0 0 -750px;
  border-radius: 50%;
  background: repeating-conic-gradient(color-mix(in srgb, var(--rc) 28%, transparent) 0deg 5deg, transparent 5deg 15deg);
  -webkit-mask: radial-gradient(circle, #000, transparent 58%); mask: radial-gradient(circle, #000, transparent 58%);
  animation: af-tourne 40s linear 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); }
.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; }
  .vt-item { width: auto; gap: 2px; }
  .vt-item img { 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; }
.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; }
.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; }
.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) {
  .forge-feu .fg-trait.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) {
  .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) {
  .fg-revele, .fg-revele-carte, .fg-revele-dit, .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); } }
.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; }
.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; }
}
@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) {
  .fg-autel *, .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(0, 1fr) 420px; gap: 16px; }
.st-liste { max-height: 520px; overflow: auto; display: flex; flex-direction: column; }
.st-carte {
  display: grid; grid-template-columns: minmax(0, 200px) 1fr 70px 70px; gap: 10px; align-items: center;
  padding: 5px 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-offre { position: relative; height: 8px; }
.st-offre i { position: absolute; inset: 0 auto 0 0; border-radius: 0 3px 3px 0; }
.st-offre-ed { background: rgba(255, 255, 255, .07); }
.st-offre-so { background: #c9a227; }
.st-fiche { display: grid; grid-template-columns: 150px 1fr; gap: 14px; align-content: start; }
.st-face { padding: 0; border: 0; background: none; cursor: pointer; aspect-ratio: 1024 / 1610; border-radius: 10px; overflow: hidden; transform: none !important; }
.st-face > :first-child { width: 100%; height: 100%; pointer-events: none; }
.st-fiche-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.st-fiche-nom { font-size: 16px; color: var(--ink, #ece6f5); }
.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-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-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 {
  content: '✓ Choisi'; position: absolute; top: 8px; right: 8px;
  padding: 3px 9px; border-radius: 999px;
  background: var(--accent); color: #1a1202; font-size: 11px; 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; }

.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; }
  #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; }
  .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%; }
}

/*  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('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("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: 701px) {
  #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: 701px) {
  #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: 701px) {
  #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: 701px) {
  #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: 701px) {
  #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: 701px) {
  #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: 701px) {
  #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; }

/* 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) { .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) { .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: 701px) {
  #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: 701px) {
  #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; }
.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; }

/* ══ 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: 701px) {
  #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: 701px) {
  #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: 701px) {
  /* ── 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: 701px) {
  #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: 701px) {
  #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 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: 701px) {
  #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: 701px) {
  #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: 701px) {
  #view-atelier .kit .vt-boite .cof3d { top: var(--cof-top, 0px); }
}
@media (min-width: 701px) {
  #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: 701px) {
  #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; }
#view-atelier .auto-pop .el-chip.is-on { color: #fff !important; box-shadow: 0 0 12px color-mix(in srgb, var(--el) 45%, transparent); }
#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); }

/* ── La page */
#view-profil { overflow-y: auto; background: #e9e1d2; }
.profil-page {
  max-width: 1100px; margin: 0 auto; padding: 30px 28px 60px;
  display: flex; flex-direction: column; gap: 22px;
}
.pf-carte, .pf-bloc {
  background: #1c2433; border: 1px solid rgba(201, 162, 70, .45); border-radius: 18px;
  box-shadow: 0 14px 34px rgba(20, 16, 10, .25);
}
.pf-carte {
  display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 30px; align-items: center;
  padding: 28px 32px;
  background: radial-gradient(ellipse 70% 120% at 0% 50%, rgba(232, 194, 90, .12), transparent 60%), #1c2433;
}
.pf-avatar {
  width: 190px; height: 190px; border-radius: 50%; display: grid; place-items: center; overflow: hidden;
  background: #0f1520;
  box-shadow: 0 0 0 5px #1c2433, 0 0 0 8px #c9a246, 0 0 36px rgba(232, 194, 90, .35);
}
.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: 64px; font-weight: 800; color: #ffe3a0; }
.pf-ident { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pf-titre { font-size: 12px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: #c9a246; }
.pf-nom { margin: 0; font-family: var(--font-title); font-size: 38px; color: #fff3d6; line-height: 1.05; }
.pf-desc { margin: 0; color: var(--ink-dim); font-size: 14px; max-width: 60ch; }
.pf-niveau { display: flex; align-items: baseline; gap: 12px; margin-top: 6px; }
.pf-niveau b { font-family: var(--font-num); font-size: 22px; color: #ffe3a0; }
.pf-niveau span { font-size: 13px; color: var(--ink-dim); }
/*  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 {
  height: 10px; border-radius: 999px; overflow: hidden; max-width: 520px;
  background: rgba(0, 0, 0, .45);
  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 { font-size: 12px; color: var(--ink-faint); }
#view-profil .pf-modifier {
  align-self: flex-start; margin-top: 8px; padding: 9px 16px; border-radius: 10px; font-weight: 700;
  background: rgba(255, 255, 255, .06) !important; color: #ffe3a0 !important;
  border: 1px solid rgba(201, 162, 70, .6) !important; box-shadow: none !important;
}
#view-profil .pf-modifier:hover { background: rgba(232, 194, 90, .15) !important; }

.pf-bloc { padding: 20px 24px 24px; }
.pf-bloc h2 {
  margin: 0 0 14px; font-family: var(--font-title); font-size: 20px; color: #e8c25a; letter-spacing: .04em;
}
.pf-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.pf-stat {
  display: flex; flex-direction: column; gap: 4px; padding: 16px 16px 14px; border-radius: 12px;
  background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .08);
}
.pf-stat b { font-family: var(--font-num); font-size: 28px; color: #fff3d6; line-height: 1; }
.pf-stat span { font-size: 12.5px; color: var(--ink-dim); }
/*  Le tiret s'efface : il dit « pas encore », pas « zero ». */
.pf-stat.est-vide { opacity: .46; }
.pf-stat.est-vide b { color: var(--ink-dim); font-size: 22px; }
.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: 12.5px; color: var(--ink-faint); }

.pf-kit { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
#view-profil .pf-tuile {
  display: flex; flex-direction: column; overflow: hidden; padding: 0; text-align: left; cursor: pointer;
  border-radius: 14px; background: radial-gradient(ellipse 80% 70% at 50% 35%, #2b3850, #141a26) !important;
  border: 1px solid rgba(201, 162, 70, .4) !important; box-shadow: none !important;
  transition: transform .15s ease, border-color .15s ease;
}
#view-profil .pf-tuile:hover { transform: translateY(-3px); border-color: #e8c25a !important; }
.pf-vue { display: grid; place-items: center; height: 190px; background: center / cover no-repeat; }
.pf-vue img { width: 180px; height: 180px; object-fit: contain; }
.pf-de { width: 120px; height: 120px; }
.pf-tuile-txt {
  display: flex; flex-direction: column; gap: 2px; padding: 10px 14px 12px;
  background: rgba(10, 14, 22, .85); border-top: 1px solid rgba(201, 162, 70, .3);
}
.pf-tuile-txt small { font-size: 10px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: #c9a246; }
.pf-tuile-txt b { font-size: 16px; color: #fff3d6; }
.pf-tuile-txt span { font-size: 12px; color: var(--ink-faint); }

@media (max-width: 900px) {
  .pf-carte { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .pf-ident { align-items: center; }
  .pf-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pf-kit { grid-template-columns: 1fr; }
  .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 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; }
@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; }
.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 {
  display: flex; gap: 6px; flex: none;
}
.marche-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 {
  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-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 { width: 100%; }
  .marche-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; }

  #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("classeurs/Creature.webp"); }
.ct-classeur[data-classeur="Lieu"]     { --couv: url("classeurs/Lieu.webp"); }
.ct-classeur[data-classeur="Piege"]    { --couv: url("classeurs/Piege.webp"); }
.ct-classeur[data-classeur="Effet"]    { --couv: url("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. */
.ct-elements-marge {
  flex: none;
  align-self: center;
  display: flex; flex-direction: column;
  /*  Aucun intervalle : les languettes se touchent et font un bloc. Le
      `margin-left` negatif rattrape le `gap` de la scene pour venir au
      contact du papier. */
  gap: 0;
  margin-left: calc(clamp(4px, 1vw, 16px) * -1);
}
.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. */
  width: clamp(38px, 3.1vw, 54px);
  height: clamp(46px, 7.2vh, 70px);
  display: grid; grid-template: 1fr / 1fr; place-items: center;
  padding: 0;
  /*  Pas de bord a GAUCHE : c'est le cote qui entre sous les pages. Un trait
      la aurait ferme la languette et l'aurait detachee du classeur. */
  border: 1px solid rgba(201, 162, 39, .16);
  border-left: 0;
  border-radius: 0 8px 8px 0;
  background: rgba(20, 16, 10, .55);
  cursor: pointer;
  transition: transform .16s ease, background .16s ease, border-color .16s ease;
}
/*  Une seule ligne entre deux languettes voisines, jamais deux. */
.ct-onglet + .ct-onglet { border-top: 0; }
.ct-onglet:first-child { border-radius: 0 11px 8px 0; }
.ct-onglet:last-child { border-radius: 0 8px 11px 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 { background: rgba(201, 162, 39, .12); }
.ct-onglet:hover > i { background: rgba(201, 162, 39, .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 {
  transform: translateX(9px);
  background: color-mix(in srgb, var(--el, #c9a227) 22%, rgba(20, 16, 10, .8));
  border-color: color-mix(in srgb, var(--el, #c9a227) 60%, transparent);
}
.ct-onglet.is-ici > i { background: var(--el, #c9a227); }

@media (max-width: 900px) {
  /*  Sur un telephone le classeur n'a qu'une page et la place manque a
      droite : les languettes passent dessous, a l'horizontale. Elles sortent
      alors vers le bas -- toujours hors du papier, jamais a cote. */
  .ct-elements-marge {
    flex-direction: row; justify-content: center;
    margin: 0; padding-top: 4px;
  }
  .ct-onglet { border: 1px solid rgba(201, 162, 39, .16); border-top: 0; border-radius: 0 0 6px 6px; }
  .ct-onglet + .ct-onglet { border-top: 0; border-left: 0; }
  .ct-onglet.is-ici { transform: translateY(4px); }
}


/*  L'ETAGERE : les quatre cartables fermes, avant d'en ouvrir un. */
.ct-etagere { display: none; }
#view-cartable.en-etagere > .cartable { display: none; }
#view-cartable.en-etagere > .ct-etagere {
  display: flex; flex-direction: column; align-items: center;
  padding: clamp(24px, 6vh, 64px) 16px 40px; text-align: center;
}
.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: 8px 0 clamp(22px, 5vh, 48px); color: var(--ink-dim); font-size: 14px; }
.ct-etagere-rang {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  width: min(760px, 100%);
  gap: clamp(14px, 2.2vh, 22px) clamp(14px, 2vw, 22px);
}

/*  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 il n'y a plus d'image ni de pictogramme : la couleur porte le
 *  classeur, et le mouvement le rend vivant. 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;
  aspect-ratio: 5 / 4; padding: 0;
  border: 1px solid rgba(255, 255, 255, .10); border-radius: 16px;
  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;
}

.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. */
.ct-tu-tete { display: grid; place-items: center; padding: 0 14px; }

/*  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: .14em; 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: 0 clamp(14px, 1.8vw, 20px) clamp(13px, 1.7vh, 17px);
  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, 3.8vw, 46px); 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, 1.3vw, 16px); 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: 10px; height: 10px; 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: 12px; 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. */
  #view-cartable.en-etagere > .ct-etagere { height: 100%; overflow: hidden; }
  .ct-etagere-rang {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: repeat(4, minmax(0, 1fr));
    flex: 1 1 auto; min-height: 0; 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; }
}

/* ══ 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 {
  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) {
  .dd-jeton, .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) { .vie-liquide, .vie-liquide::before, .vie-liquide::after, .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; }
.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; }
.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-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: carteParaitSobre;
  }

  /*  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 carteParaitSobre {
  0% {
    opacity: 0;
    transform: perspective(900px) rotateX(-52deg) translateY(26px) scale(.74);
  }
  38% { opacity: 1; }
  72% { transform: perspective(900px) rotateX(0deg) translateY(0) scale(1.055); }
  100% {
    opacity: 1;
    transform: perspective(900px) rotateX(0deg) translateY(0) scale(1);
  }
}

/*  ══ 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); }
