/* ══════════════════════════════════════════════════════════════════════════
 *  KAIROS AU TÉLÉPHONE
 *
 *  Chargée APRÈS style.css, et seulement sous 700 px : c'est la dernière
 *  couche, celle qui tranche. Les règles « au téléphone » de style.css
 *  s'étaient empilées page par page, chacune corrigeant la précédente ; ici
 *  on reprend les quatre écrans que le pouce touche le plus (navigation,
 *  atelier, marché, forge) avec une seule idée : une chose par écran, en
 *  grand, et tout ce qui se touche fait au moins 44 px.
 *
 *  LES DEUX BARRES.
 *  Tout vivait dans une seule barre en bas : sept onglets en pictos de 14 px
 *  ET le portefeuille, le profil, le grimoire, les réglages. Rien n'y était
 *  lisible ni visable. On sépare donc :
 *    - en haut, QUI JE SUIS : blason, grimoire, portefeuille, profil, réglages ;
 *    - en bas, OÙ JE VAIS : six onglets, icône + libellé, pleine largeur.
 *  `--topbar-h` reste la somme des deux : toutes les vues calées dessus
 *  (`100dvh - --topbar-h`) restent justes sans qu'on les touche.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  :root {
    --mob-haut: calc(52px + env(safe-area-inset-top, 0px));
    --mob-bas: calc(62px + env(safe-area-inset-bottom, 0px));
    --topbar-h: calc(var(--mob-haut) + var(--mob-bas));
  }
  body { padding-top: var(--mob-haut); padding-bottom: var(--mob-bas); }
  /* En partie, la table prend tout l'écran : style.css cache déjà la barre. */
  body.play-on { --mob-haut: 0px; --mob-bas: 0px; padding: 0; }

  /* ── EN HAUT : l'identité ─────────────────────────────────────────────── */
  .topbar {
    position: fixed; top: 0; bottom: auto; left: 0; right: 0; z-index: 60;
    height: var(--mob-haut);
    padding: env(safe-area-inset-top, 0px) 10px 0;
    gap: 8px;
    border-top: 0; border-bottom: 1px solid var(--line-gold);
    background: linear-gradient(180deg, rgba(14, 12, 20, .98), rgba(9, 8, 14, .98));
    box-shadow: 0 4px 18px rgba(0, 0, 0, .5), inset 0 -1px 0 rgba(245, 185, 66, .12);
    /* Un `backdrop-filter` ferait de la barre le bloc conteneur de ses
       enfants fixes : la rangée d'onglets, qui en est un, se collerait à elle
       au lieu du bas de l'écran. */
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  /*  LE NOM RESTE. Il tenait le tiers de la barre en 17 px ; il la tient en
      15 px sans sous-titre, et les quatre boutons y trouvent leur compte.
      Sous 370 px, c'est lui qui cede -- la regle est plus bas. */
  .brand { gap: 7px; flex: none; min-width: 0; }
  .brand-crest-wrap { width: 30px; height: 30px; flex: none; }
  .brand-text { display: flex; }
  .brand-sub { display: none; }
  .brand-title { font-size: 15px; letter-spacing: .1em; line-height: 1; }

  /*  RIEN NE DOIT POUVOIR POUSSER L'ENGRENAGE HORS DE L'ECRAN. Les boutons
      gardent leur taille, le nom du jeu et le libelle du portefeuille cedent
      -- dans cet ordre -- si la largeur vient a manquer. */
  .topbar { flex-wrap: nowrap; }
  .header-actions { margin-left: auto; gap: 6px; min-width: 0; flex: 0 1 auto; }
  .profil-chip, .cta-booster, .btn-parametres { flex: none; }
  .brand { overflow: hidden; }
  .brand-title { white-space: nowrap; overflow: hidden; text-overflow: clip; }
  .wallet-btn, .profil-chip, .btn-parametres, .cta-booster { height: 36px; }

  /*  LE PORTEFEUILLE EST LE SEUL A PORTER UN MOT. Reduit a un rond, il ne se
      distinguait ni du profil ni des reglages : le geste qui compte le plus
      pour un nouveau venu etait celui qu'on ne pouvait pas deviner. Il garde
      donc sa pastille et son libelle -- « Connecter » au telephone, l'adresse
      abregee une fois connecte. */
  .wallet-btn,
  .wallet-btn:not(.is-connecte) {
    width: auto; max-width: none; padding: 0 11px;
    font-size: 11.5px; font-weight: 700; white-space: nowrap;
    /*  LA CEINTURE, EN PLUS DES BRETELLES. Le libelle court est choisi en JS,
        au moment de peindre ; si ce choix arrive en retard -- fenetre ouverte
        large puis retrecie -- la phrase entiere poussait l'engrenage hors de
        l'ecran. Ici le bouton ne peut PAS depasser ce que la barre lui laisse :
        les trois ronds font 116 px, les ecarts et les marges 40, le blason 110. */
    flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    max-width: calc(100vw - 278px);
  }
  /* style.css remplacait le libelle par un « ◎ » : le mot revient, le signe
     s'en va -- sinon les deux se suivent dans le bouton. */
  .wallet-btn:not(.is-connecte)::after { content: none; }
  .wallet-menu {
    top: calc(100% + 8px); bottom: auto; right: 0;
    max-height: min(70vh, 440px);
  }
  .profil-chip { padding: 2px; }
  .pc-avatar { width: 32px; height: 32px; }

  /*  LES REGLAGES PASSENT DERRIERE. Cercle d'or comme les autres, l'engrenage
      pesait autant que le profil et le grimoire. Il reste visable a 36 px,
      mais il ne brille plus. */
  .btn-parametres {
    width: 36px; padding: 0; font-size: 17px;
    border-color: rgba(201, 162, 70, .28); color: rgba(226, 214, 190, .7);
    background: rgba(255, 255, 255, .03);
  }

  /*  LE GRIMOIRE QUITTE LA BARRE. Quatre boutons pour quatre choses a
      faire, dans 375 px, c'etait un de trop -- et celui-la double un bloc de
      l'accueil qui fait la meme chose en grand, le livre pose sur l'autel.
      La notification descend donc avec lui : la pastille « en main » y devient
      lisible, et l'appel a ouvrir revient. */
  .cta-booster { display: none; }

  /*  ET UNE SEULE VOIX SOUS LE LIVRE. « 5 en main » et « Ouvre tes 5
      grimoires » se superposaient sous la couverture en disant la meme
      chose. Le compteur gagne : la colonne du livre fait 90 px, et l'invite
      s'y pliait en trois lignes par-dessus la couverture. Il passe a l'or
      pour tenir le role de notification que la barre du haut a lache. */
  .altar-pack-count-tag {
    font-size: 10px; padding: 3px 9px; bottom: -7px; white-space: nowrap;
    color: #1a1202; background: var(--gold-grad, #f5b942);
    border-color: transparent;
    box-shadow: 0 2px 10px rgba(245, 185, 66, .45);
  }
  /* A vide, la pastille se tait : un zero ne s'annonce pas en or. */
  .altar-pack-count-tag.est-vide {
    color: rgba(226, 214, 190, .7); background: rgba(255, 255, 255, .12);
    box-shadow: none;
  }

  /* ── EN BAS : la navigation ───────────────────────────────────────────── */
  .tabs {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    height: var(--mob-bas);
    padding: 0 2px env(safe-area-inset-bottom, 0px);
    display: flex; align-items: stretch; justify-content: space-around; gap: 0;
    min-width: 0;
    background: linear-gradient(180deg, rgba(18, 15, 24, .98), rgba(7, 6, 10, 1));
    border-top: 1px solid var(--line-gold);
    box-shadow: 0 -6px 24px rgba(0, 0, 0, .6);
  }
  .tabs > .tab, .tabs > .tab-groupe { flex: 1 1 0; min-width: 0; }
  .tab-groupe { display: flex; }
  .tab-groupe > .tab { flex: 1 1 auto; }
  .tabs .tab,
  .tabs .tab:hover,
  .tabs .tab.is-on {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px; padding: 6px 0 4px; margin: 0;
    border: 0; border-radius: 0; background: none; box-shadow: none;
    transform: none;
  }
  .tabs .tab { color: #8e8799; }
  .tabs .tab.is-on,
  .tab-groupe.est-ouvert > .tab-parent { color: #f6cf6f; }
  .tab-text {
    display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .01em;
    line-height: 1; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tab[data-view="stats"] .tab-text::after { font-size: 10.5px; }
  .tab-caret, .tabs .tab.tab-lien, .tabs .tab[data-view="accueil"] { display: none; }

  /* Des icônes dessinées plutôt que des caractères : ⌂ ✎ ▦ ♦ n'ont ni la
     même taille ni la même graisse d'une police à l'autre, et à 14 px on ne
     les distinguait plus. Même trait, même boîte, et la couleur suit
     `currentColor` pour s'allumer avec l'onglet. */
  .tabs .tab::before,
  .tabs #nav-jouer-btn::before {
    content: '' !important;
    display: block; width: 24px; height: 24px; flex: none;
    background: currentColor; opacity: 1;
    -webkit-mask: var(--ico) center / contain no-repeat;
            mask: var(--ico) center / contain no-repeat;
  }
  .tabs .tab.is-on::after,
  .tab-groupe.est-ouvert > .tab-parent::after {
    content: ''; position: absolute; top: 0; left: 26%; right: 26%;
    height: 3px; border-radius: 0 0 3px 3px;
    background: linear-gradient(90deg, #f6cf6f, #d99a2b);
    box-shadow: 0 0 10px rgba(245, 185, 66, .6);
  }
  #nav-jouer-btn { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.5 17.5 3 6V3h3l11.5 11.5'/%3E%3Cpath d='m13 19 6-6M16 16l4 4M19 21l2-2'/%3E%3Cpath d='M9.5 17.5 21 6V3h-3L6.5 14.5'/%3E%3Cpath d='m11 19-6-6M8 16l-4 4M5 21l-2-2'/%3E%3C/svg%3E"); }
  .tab[data-view="atelier"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'%3E%3Crect x='3' y='6' width='11' height='15' rx='2'/%3E%3Cpath d='M8 3h11a2 2 0 0 1 2 2v13'/%3E%3C/svg%3E"); }
  .tab[data-view="collection"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'%3E%3Cpath d='M4 4h7v16H4zM13 4h7v16h-7z'/%3E%3Cpath d='M7 8h1M7 12h1M16 8h1M16 12h1'/%3E%3C/svg%3E"); }
  .tab[data-view="marche"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l2-5h14l2 5'/%3E%3Cpath d='M3 9h18v2a3 3 0 0 1-6 0 3 3 0 0 1-6 0 3 3 0 0 1-6 0z'/%3E%3Cpath d='M5 13v8h14v-8M10 21v-5h4v5'/%3E%3C/svg%3E"); }
  .tab[data-view="forge"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3c1 3 4 4.5 4 8a4 4 0 0 1-8 0c0-1.5.7-2.6 1.5-3.5.2 1.3 1 2 1.8 2C11 7 11 5 12 3z'/%3E%3Cpath d='M4 17h16l-2 4H6z'/%3E%3C/svg%3E"); }
  .tab[data-view="stats"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 20h16'/%3E%3Cpath d='M7 16v-5M12 16V6M17 16v-8'/%3E%3C/svg%3E"); }
  .tab-pastille { top: 5px; right: calc(50% - 20px); }

  /* Le menu « Jouer » monte de la barre, au-dessus de son onglet. */
  .tab-menu {
    position: fixed; top: auto; left: 8px; right: 8px;
    bottom: calc(var(--mob-bas) + 8px);
    max-width: none; padding: 6px;
  }
  .tab-menu { display: flex; flex-direction: column; gap: 4px; }
  .tab-menu[hidden] { display: none; }
  .tab-menu-item {
    display: flex; align-items: center; justify-content: flex-start; gap: 12px;
    width: 100%; min-height: 60px; padding: 10px 14px; text-align: left;
  }
  .tab-menu-item .tmi-txt { display: flex; flex-direction: column; align-items: flex-start; }
  .tab-groupe.est-ouvert > .tab-parent { background: none !important; box-shadow: none !important; }

  /* Les feuilles qui montent du bas s'arrêtent AU-DESSUS de la barre : elles
     étaient calées sur `--topbar-h`, qui vaut désormais les deux barres. */
  #view-atelier.en-feuilles .deck-rail,
  body.marche-filtres-ouverts .marche .cartable-outils,
  body.ct-filtres-ouverts #view-cartable .cartable-outils { bottom: var(--mob-bas); }
  .voile-feuille { top: 0; bottom: var(--mob-bas); }
  .ma-voile { padding: 8px 8px calc(8px + var(--mob-bas)); }
  .ma-panneau { max-height: calc(100dvh - var(--topbar-h) - 16px); }

  /* ══ L'ATELIER ════════════════════════════════════════════════════════ */
  .barre-atelier { gap: 6px; padding: 6px 8px; }
  .ba-btn {
    flex-direction: row; justify-content: center; gap: 6px;
    min-height: 42px; padding: 6px 8px; font-size: 13px;
  }
  .ba-ico { font-size: 17px; }

  /* L'interrupteur « Toutes / Mon deck » débordait de l'écran avec son
     compteur : il prend toute la largeur, et le compteur se tait. */
  #view-atelier .gal-barre { padding: 8px 8px 6px; gap: 0; }
  #view-atelier .gal-compte { display: none; }
  .gal-vue { display: flex; width: 100%; padding: 3px; gap: 3px; border-radius: 11px; }
  .gv-btn {
    flex: 1 1 0; justify-content: center; gap: 8px;
    min-height: 40px; padding: 6px 8px; font-size: 14px; white-space: nowrap;
  }
  .gv-btn b { font-size: 12px; padding: 1px 7px; }

  #view-atelier .gallery {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px 6px; padding: 2px 8px 20px;
  }
  /* Les « − / + » restent : ce sont eux qui disent que la carte se touche. */
  #view-atelier .slot-actions { display: flex; right: 4px; bottom: 4px; gap: 4px; }
  #view-atelier .slot-actions button { width: 30px; height: 30px; font-size: 17px; }
  #view-atelier .slot-cap { display: none; }
  .slot.vient-d-entrer { animation: mob-pouls .32s ease-out; }
  @keyframes mob-pouls {
    40% { transform: scale(.94); }
    100% { transform: none; }
  }

  /* La feuille du deck : la liste, pas quarante vignettes.
     Un deck se RELIT ; on veut voir d'un coup d'œil ce qu'il contient et
     combien de chaque. Quarante images de 66 px n'en disaient rien. */
  #view-atelier.en-feuilles .deck-rail { max-height: calc(100dvh - var(--topbar-h) - 24px); }
  #view-atelier.en-feuilles .fan.fan-liste {
    display: flex; flex-direction: column; align-items: stretch; gap: 4px;
    width: 100%; height: auto; overflow: visible; padding: 4px 0 0; margin: 0;
    transform: none; perspective: none;
  }
  #view-atelier.en-feuilles .fan-container:has(.fan-liste) {
    height: auto; padding: 0; margin: 6px 0 0; overflow: visible;
  }
  .fan-liste > * { margin: 0 !important; transform: none !important; width: auto; }
  .dl-ligne {
    display: grid; grid-template-columns: 44px minmax(0, 1fr) auto auto auto auto;
    align-items: center; gap: 8px;
    min-height: 52px; padding: 4px 6px 4px 4px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .06);
    border-left: 3px solid var(--rc, #c9ccd4);
  }
  .dl-vignette {
    width: 44px; height: 44px; border-radius: 7px; overflow: hidden;
    padding: 0; border: 0; background: #111;
  }
  .dl-vignette img {
    width: 100%; height: 100%; object-fit: cover;
    /* L'illustration, pas le titre : on vise la fenêtre de l'art. */
    object-position: 50% 26%; transform: scale(1.9); transform-origin: 50% 26%;
  }
  .dl-texte {
    min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    text-align: left; min-height: 44px; justify-content: center; background: none; border: 0; padding: 0; box-shadow: none;
    color: inherit;
  }
  .dl-texte b {
    font-size: 14px; color: var(--ink-bright, #f3eee3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .dl-texte small { font-size: 11px; color: var(--ink-faint, #8d86a0); }
  .dl-qte {
    min-width: 30px; text-align: center;
    font: 800 15px var(--font-num, sans-serif); color: #f6cf6f;
  }
  .dl-ligne .dl-bouton {
    width: 36px; height: 36px; padding: 0; border-radius: 50%;
    font-size: 19px; font-weight: 800; line-height: 1;
  }
  .dl-ligne .dl-bouton.add { background: var(--gold-grad); color: #1a1202; border-color: #ffe082; }
  .dl-groupe {
    margin: 8px 2px 2px; font-size: 11px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase; color: #c9a246;
  }

  /* ══ LA LOUPE D'UNE CARTE ═══════════════════════════════════════════════
     Six gestes sous la carte (retirer, ajouter, forger, acheter, vendre,
     fermer) s'enroulaient au hasard de leur largeur. Ils se rangent en
     rangées égales, assez hautes pour le pouce. */
  .zoom-bar { display: flex; flex-wrap: wrap; gap: 6px; justify-content: stretch; }
  .zoom-bar > button { flex: 1 1 28%; min-height: 44px; justify-content: center; font-size: 14px; }
  .zoom-bar > .zoom-force, .zoom-bar > .hint { flex: 1 1 100%; text-align: center; }

  /* ══ LE MARCHÉ : une liste, pas une vitrine ══════════════════════════════
     Deux annonces par écran, c'était deux cartes à 170 px et un bouton
     géant sous chacune. En ligne, la carte à gauche et tout le reste à
     droite : cinq à six annonces par écran, et le prix au même endroit
     d'une ligne à l'autre, comme dans toute boutique. */
  .ma-grille { grid-template-columns: 1fr; gap: 8px; }
  /*  TROIS COLONNES, PAS DEUX.
   *
   *  Le bouton occupait une RANGEE entiere sous le prix : la ligne montait a
   *  150 px et il n'en tenait que trois par ecran, avec un grand vide a
   *  droite du prix. En troisieme colonne, centre sur la hauteur, il ne
   *  coute plus une rangee -- la ligne tombe sous 110 px et le vide est
   *  rempli par ce qu'on venait chercher : le bouton. */
  .ma-tuile {
    display: grid;
    grid-template-columns: 70px minmax(0, 1fr) auto;
    grid-template-rows: auto auto auto auto;
    column-gap: 12px; row-gap: 2px;
    padding: 9px 10px; align-items: start;
  }
  .ma-tuile > .ma-visuel { grid-column: 1; grid-row: 1 / -1; align-self: center; width: 70px; padding: 0; margin: 0; border: 0; background: none; }
  .ma-tuile > .ma-visuel .cf { --cf-w: 70px; width: 70px; }
  .ma-tuile > :not(.ma-visuel) { grid-column: 2; margin: 0; }
  .ma-tuile .ma-nom { font-size: 15px; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ma-tuile .ma-meta { font-size: 12px; }
  .ma-tuile .ma-prix { flex-direction: row; align-items: baseline; gap: 8px; margin-top: 4px; }
  .ma-tuile .ma-prix-sol { font-size: 16px; }
  .ma-tuile .ma-prix-usd { font-size: 12px; }
  .ma-tuile .ma-vendeur { font-size: 11px; grid-column: 2; margin-top: 2px; }
  /*  LA PASTILLE DE REMISE se cale en haut a droite, AU-DESSUS du bouton :
      celui-ci est centre sur la hauteur, donc son sommet commence plus bas.
      Elle ne prend aucune rangee et ne repousse rien. */
  .ma-tuile .ma-badge {
    top: 8px; right: 10px;
    font-size: 11.5px; padding: 3px 9px;
    color: #10240f; border-color: rgba(120, 240, 130, .5);
    background: linear-gradient(180deg, #b8f5b0, #6fd37a);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .45);
  }
  /*  Le bouton tient toute la hauteur de la ligne et s'y centre : ou qu'en
   *  soit le texte -- « Acheter », « Retirer » --, le pouce le trouve au
   *  meme endroit d'une annonce a l'autre. */
  .ma-tuile .ma-actions {
    grid-column: 3; grid-row: 1 / -1; align-self: center; justify-self: end;
    flex-direction: column; margin-top: 0;
  }
  .ma-tuile .ma-actions button { width: auto; min-width: 92px; min-height: 42px; padding: 9px 14px; font-size: 14px; }
  /*  La gemme de rarete : on balaie la liste a la couleur, pas au mot. */
  .ma-tuile .ma-rar::before {
    content: ""; display: inline-block; vertical-align: middle;
    width: 8px; height: 8px; margin: -2px 5px 0 0;
    border-radius: 2px; transform: rotate(45deg);
    background: var(--rc, #9aa); box-shadow: 0 0 6px var(--rc, transparent);
  }
  .ma-tuile .ma-nom { font-size: 14px; }

  .marche .cartable-tete { padding: 8px 10px; gap: 8px; }
  .marche-onglets button { min-height: 42px; }

  /* ══ LA FORGE : l'autel prend l'écran ═══════════════════════════════════
     On y vient pour forger : l'autel était tassé à 38 % de la hauteur et
     les douze cartes du sacrifice se chevauchaient jusqu'à se cacher. Il
     prend désormais l'essentiel de l'écran, et le registre du burn se lit
     en dessous, en faisant défiler. */
  #view-forge .cartable-tete { padding: 8px 12px; }
  .forge-corps { padding: 8px 8px 24px; gap: 12px; }
  .forge-corps { display: flex; flex-direction: column; }
  /*  TOUT L'ESPACE VA AU VISUEL. La page se lit de haut en bas --
      l'avertissement, le creuset, les commandes -- et c'est le creuset, seul,
      qui s'etire : le texte et les boutons prennent ce qu'il leur faut, il
      prend le reste. */
  .forge-corps { display: flex; flex-direction: column; gap: 10px; padding: 8px 10px 10px; }
  .fg-scene {
    order: 0; flex: 1 1 auto; height: auto; min-height: 0;
    display: flex; flex-direction: column; gap: 8px;
  }
  .fg-bas { flex: none; }
  /* L'autel et le bouton « Forger » tiennent ensemble dans l'écran. */
  /*  LA PLACE VA A LA FORGE, PAS A SES STATISTIQUES.
      Le creuset prenait 511 px sur 664 pour une pastille de 130, et le
      tableau du burn -- six barres, une legende, un graphe -- occupait le
      reste en passant sous la barre. Au telephone, on vient ici pour FORGER.
      Le tableau s'efface donc, et de tout ce qu'il disait on garde la seule
      chose qu'on ne peut pas se permettre d'apprendre apres coup : une forge
      est sans retour. Le tableau reste entier sur l'ecran large. */
  .fg-autel { flex: 1 1 auto; height: auto; max-height: none; min-height: 200px; }
  /*  L'AVERTISSEMENT PASSE EN TETE. Il fermait la page, sous les boutons :
      on le lisait apres avoir decide. Il s'annonce maintenant avant le
      creuset, et les commandes -- Proposer, Vider, Lancer -- restent sous les
      cartes qu'elles concernent. */
  .fg-burn {
    order: -1; padding: 0; gap: 0; background: none; border: 0; overflow: visible;
  }
  .fg-burn .fg-fig, .fg-burn .fg-legende, .fg-burn .fg-vide,
  .fg-burn-tete h3, .fg-registre { display: none; }
  /*  `fg-avert` appartient deja a la Forge : c'est l'encart « cette forge
      ampute un deck ». Le mien porte son propre nom. */
  .fg-burn-avert {
    margin: 0; padding: 10px 12px; border-radius: 12px;
    font-size: 12px; line-height: 1.35; color: #ffd9a8;
    background: rgba(214, 96, 96, .12);
    border: 1px solid rgba(214, 96, 96, .35);
  }

  /* Le choix de la carte à forger : trois colonnes comme l'atelier.

     LES FILTRES REVIENNENT À LA LIGNE. Ils défilaient à l'horizontale, une
     bande par famille — sauf qu'une bande qui glisse ne dit pas qu'elle
     glisse : on voyait « Rare » et « Énergies » tranchés au bord, ce qui se
     lit comme un écran cassé et non comme une invitation à pousser du pouce.
     Les raretés mesuraient 743 px pour 335 disponibles, donc QUATRE des six
     étaient hors de l'écran, y compris celles qu'on vient chercher.

     Elles s'empilent maintenant. Ça coûte deux lignes de hauteur, dans un
     panneau qui défile déjà verticalement — le seul sens où le doigt cherche
     spontanément quelque chose. Le ratio quitte les pastilles, qui tiennent
     alors sur deux lignes au lieu de trois : il est dit en toutes lettres
     dans `.fg-regle`, juste au-dessus de la grille. */
  .fg-choix { padding: 12px 10px; }
  .fg-grille { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 8px 6px; }
  .fg-rars { flex-wrap: wrap; gap: 6px; }
  /*  Les cinq types tiennent sur une ligne pour 42 px pres : on les resserre
      plutot que de laisser « Énergies » descendre tout seul. S'ils ne passent
      pas sur un ecran plus etroit, ils reviennent a la ligne comme le reste --
      c'est un confort, pas une contrainte. */
  .fg-choix .fg-types { flex-wrap: wrap; gap: 4px; }
  .fg-choix .fg-types button { padding: 5px 7px; font-size: 11.5px; }
  .fg-rars > *, .fg-choix .fg-types > * { flex: none; min-height: 36px; }
  .fg-chip-ratio { display: none; }
  .fg-choix input[type="search"], .fg-choix input[type="text"] { width: 100%; font-size: 16px; min-height: 42px; }
}

/* LA LANGUETTE DU POUVOIR, au bord gauche de la planche, côté joueur. Elle
   se lit de bas en haut, respire en or tant qu'elle attend, et disparaît
   quand le geste n'est plus possible. */
@media (max-width: 820px) and (orientation: portrait) {
  #ma-geste.geste-lateral {
    position: absolute; z-index: 44; left: 0;
    /* `left` et `top` sont posés par placerLanguette() (main.js) : collée
       au bord gauche de la planche, à sa mi-hauteur. */
    top: 50%;
    /* Une seule transformation : avec la propriete `rotate` a part, la
       rotation s'appliquait AVANT le recentrage et le retournait -- la
       languette tombait d'une demi-hauteur trop bas. */
    transform: translateY(-50%) rotate(180deg);
    writing-mode: vertical-rl;
    width: 34px; min-height: 0; padding: 16px 0; margin: 0;
    border-radius: 0 12px 12px 0;
    font-family: var(--font-title), Georgia, serif; font-size: 12px; font-weight: 800;
    letter-spacing: .08em; white-space: nowrap;
    color: #1a1202; background: linear-gradient(180deg, #ffe29a, #d9982b);
    border: 1px solid #ffe7a6; border-left: 0;
    box-shadow: 0 0 18px rgba(245, 185, 66, .55), 0 6px 18px rgba(0, 0, 0, .5);
    animation: languette-appel 2.2s ease-in-out infinite;
  }
  #ma-geste.geste-lateral[hidden] { display: none; }
  @keyframes languette-appel {
    50% { box-shadow: 0 0 30px rgba(245, 185, 66, .9), 0 6px 18px rgba(0, 0, 0, .5); }
  }
}

/* Les très petits téléphones : le nom du jeu cède sa place aux boutons. */
@media (max-width: 370px) {
  .brand-text { display: none !important; }
  .tab-text { font-size: 9.5px; }
}

/* ══════════════════════════════════════════════════════════════════════════
 *  LA PARTIE, EN PORTRAIT
 *
 *  Le pupitre du haut faisait 128 px en trois lignes pleine largeur -- l'état,
 *  le message, puis « Finir le tour » en barre géante -- et le Pouvoir
 *  d'Ascendant, qui n'y tenait plus, débordait en texte nu sur la planche
 *  adverse. Deux lignes suffisent : en haut ce qui se passe et les deux
 *  gestes (finir, abandonner), en dessous la consigne. Le plateau récupère
 *  une quarantaine de pixels, et plus rien ne s'écrit par-dessus.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 820px) and (orientation: portrait) {
  :root {
    --info-h: 36px;
    --prompt-h: 30px;
    --module-h: calc(12px + var(--info-h) + 4px + var(--prompt-h));
  }
  .game-module {
    padding: 6px 8px; gap: 4px 6px;
    grid-template-columns: minmax(0, 1fr) auto 36px;
    grid-template-rows: var(--info-h) var(--prompt-h);
    grid-template-areas: "info fin quit" "msg asc asc";
  }
  .game-module .turn-info {
    grid-area: info; min-width: 0; overflow: hidden;
    display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto;
    column-gap: 7px; row-gap: 1px; align-content: center;
    padding: 0 2px; border: 0 !important; background: none !important; box-shadow: none !important;
  }
  .game-module .turn-info .turn-dot { grid-row: 1 / 3; align-self: center; }
  .game-module .turn-info .turn-round { grid-column: 2; grid-row: 1; line-height: 1.1; }
  .game-module .turn-info b { grid-column: 2; grid-row: 2; line-height: 1.15; }
  .game-module .turn-info .turn-round {
    font-size: 9px; letter-spacing: .12em; text-transform: uppercase; opacity: .7;
    white-space: nowrap;
  }
  .game-module .turn-info b {
    font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
  }
  .module-end-turn {
    grid-area: fin; width: auto; min-height: 36px; height: 36px;
    padding: 0 14px; font-size: 11px; white-space: nowrap;
  }
  /* RIEN DE FIGÉ. « Finir le tour » n'existe que quand il sert : grisé
     (pose du héros, tour adverse), il tenait un tiers de la ligne pour ne
     rien dire. Il s'efface, et l'état du tour reprend sa place. */
  .module-end-turn:disabled { display: none; }
  .game-module:has(.module-end-turn:disabled) {
    grid-template-areas: "info info quit" "msg asc asc";
  }
  /* Une consigne coupée se déplie d'un toucher, par-dessus la planche le
     temps de la lire ; un second toucher la replie. Le plateau, lui, ne
     bouge pas d'un pixel. */
  .prompt .msg { cursor: pointer; }
  .game-module.consigne-ouverte {
    height: auto; min-height: var(--module-h); z-index: 60;
    box-shadow: 0 14px 30px rgba(0, 0, 0, .6);
    grid-template-rows: var(--info-h) auto;
  }
  .game-module.consigne-ouverte .prompt { height: auto; max-height: 40vh; overflow-y: auto; }
  .game-module.consigne-ouverte .prompt .msg { -webkit-line-clamp: unset; display: block; }
  .prompt { grid-area: msg; height: var(--prompt-h); padding: 0 2px; scrollbar-width: none; }
  .prompt::-webkit-scrollbar { display: none; }
  .prompt .msg {
    font-size: 11px; line-height: 1.3;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .prompt > button { min-height: 28px; padding: 4px 10px; font-size: 11px; }

  /* Le Pouvoir d'Ascendant : son nom et son geste, en pastille, à côté de la
     consigne. Voilé (avant le lancer d'ouverture), il n'a rien à dire. */
  .game-module .module-ascendant {
    grid-area: asc; display: flex; align-items: center; gap: 6px;
    min-width: 0; max-width: 46vw; margin: 0; padding: 0; background: none; border: 0;
  }
  .game-module .module-ascendant.est-voile,
  .game-module .module-ascendant[hidden] { display: none; }
  .module-ascendant .ma-kicker, .module-ascendant .ma-ligne { display: none; }
  .module-ascendant .ma-nom { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .module-ascendant .ma-geste { min-height: 28px; padding: 2px 10px; font-size: 11px; white-space: nowrap; }

  /* LE POUVOIR QUITTE LE PUPITRE. Son nom et son bouton mangeaient la moitié
     de la ligne des objectifs, tronqués en « C… 1/1 ». Le bouton devient une
     languette au bord gauche du plateau (`.geste-lateral`, déplacé par
     renderPouvoirAscendant), qui n'existe que quand le geste est possible ;
     l'élément Ascendant, lui, se lit déjà sur la Roue. */
  .game-module .module-ascendant { display: none !important; }
  .game-module { grid-template-areas: "info fin quit" "msg msg msg"; }
  .game-module:has(.module-end-turn:disabled) { grid-template-areas: "info info quit" "msg msg msg"; }

  /* LES ÉTAPES DU TOUR : UNE SEULE BARRE DE VERRE, QUI SE REMPLIT.
     Un seul corps : un tube épais, et trois renflements sphériques qui en
     font partie -- même verre, même reflet, aucune couture. Les étapes sont
     écrites DANS la barre. Une étape faite se remplit de liquide, sphère
     comprise ; l'étape en cours s'éclaire doucement de l'intérieur. */
  .prompt .registre {
    --tube-h: 22px;
    position: relative; flex: 1 1 100%; width: 100%; height: var(--tube-h);
    display: flex; flex-direction: row; align-items: center; gap: 0;
    margin: 0 4px 0 14px;
    border-radius: 999px;
    background:
      linear-gradient(180deg, rgba(255, 255, 255, .20) 0%, rgba(255, 255, 255, .04) 38%,
                      rgba(0, 0, 0, 0) 55%, rgba(255, 255, 255, .06) 100%),
      linear-gradient(180deg, #2a2733, #121017);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, .75), inset 0 -1px 1px rgba(255, 255, 255, .12),
                0 1px 0 rgba(255, 255, 255, .06);
  }
  .prompt .opt {
    position: relative; flex: 1 1 0; min-width: 0; height: 100%;
    display: flex; align-items: center; justify-content: center; gap: 5px;
    padding: 0 6px 0 16px; border: 0; background: none; border-radius: 0;
  }
  .prompt .opt:first-child { border-radius: 999px 0 0 999px; }
  .prompt .opt:last-child  { border-radius: 0 999px 999px 0; }
  .prompt .opt::before { display: none; }

  /* LE LIQUIDE. Il occupe la chambre d'une étape faite, avec une vague qui
     court sur sa surface et un reflet qui la traverse. */
  .prompt .opt::after {
    content: ''; position: absolute; z-index: 0; top: 3px; bottom: 3px; left: -12px;
    border-radius: 0; width: 0;
    background:
      radial-gradient(120% 60% at 50% 0%, rgba(255, 255, 255, .45), transparent 60%),
      repeating-linear-gradient(100deg, rgba(255, 255, 255, 0) 0 14px, rgba(255, 255, 255, .16) 14px 18px),
      linear-gradient(180deg, #b6ffc8 0%, #4fe07c 40%, #22a24c 100%);
    background-size: 100% 100%, 60px 100%, 100% 100%;
    /* Le front du liquide : un ménisque clair, arrondi, là où il s'arrête. */
    box-shadow: inset -3px 0 4px rgba(230, 255, 236, .55), 0 0 12px rgba(80, 230, 130, .6);
    transition: width .9s cubic-bezier(.3, .9, .3, 1);
    animation: liquide-courant 2.4s linear infinite;
  }
  /* LE LIQUIDE MONTE DE GAUCHE A DROITE, D'UN SEUL TENANT. Une étape faite
     ne se remplit que si toutes celles d'avant le sont : sinon la barre
     s'allumait par morceaux. Il coule sous la sphère suivante (+26 px) pour
     qu'aucune couture ne se voie entre deux chambres. */
  .prompt .opt--fait:not(.opt:not(.opt--fait) ~ .opt--fait)::after { width: calc(100% + 26px); }
  .prompt .opt:first-child::after { left: 0; border-radius: 999px 0 0 999px; }
  .prompt .opt--fait:first-child:not(.opt:not(.opt--fait) ~ .opt--fait)::after { width: calc(100% + 14px); }
  .prompt .opt:last-child::after { border-radius: 0 999px 999px 0; }
  .prompt .opt--fait:last-child:not(.opt:not(.opt--fait) ~ .opt--fait)::after { width: calc(100% + 12px); }
  @keyframes liquide-courant { to { background-position: 0 0, 60px 0, 0 0; } }

  /* LA SPHÈRE, renflement du même verre, à cheval sur la barre. */
  .prompt .opt-rang {
    position: absolute; z-index: 2; left: -12px; top: 50%;
    width: 28px; height: 28px; margin-top: -14px; border-radius: 50%; border: 0;
    font-size: 0; color: transparent;
    background:
      radial-gradient(circle at 36% 28%, rgba(255, 255, 255, .85) 0 9%, rgba(255, 255, 255, 0) 26%),
      radial-gradient(circle at 50% 60%, #2a2733 0 55%, #121017 100%);
    box-shadow: inset 0 -3px 5px rgba(0, 0, 0, .6), inset 0 2px 3px rgba(255, 255, 255, .18),
                0 2px 5px rgba(0, 0, 0, .5);
  }
  .prompt .opt:first-child .opt-rang { left: -14px; }
  .prompt .opt--fait:not(.opt:not(.opt--fait) ~ .opt--fait) .opt-rang {
    background:
      radial-gradient(circle at 36% 28%, rgba(255, 255, 255, .9) 0 9%, rgba(255, 255, 255, 0) 26%),
      radial-gradient(circle at 50% 62%, #8ff6ab 0 20%, #2fb35a 55%, #0f5e2a 100%);
    box-shadow: inset 0 -3px 5px rgba(0, 40, 10, .5), 0 0 12px rgba(80, 230, 130, .7);
  }
  .prompt .opt--ferme .opt-rang { filter: grayscale(1) brightness(.7); }
  /* EN COURS : une lueur douce au cœur de la sphère, qui respire. */
  .prompt .opt--ouvert:not(.opt--ouvert ~ .opt--ouvert) .opt-rang {
    background:
      radial-gradient(circle at 36% 28%, rgba(255, 255, 255, .85) 0 9%, rgba(255, 255, 255, 0) 26%),
      radial-gradient(circle at 50% 58%, #c9f6ff 0 12%, #3cb8d6 38%, #0e4a5c 78%, #121017 100%);
    animation: etape-lueur 1.8s ease-in-out infinite;
  }
  @keyframes etape-lueur {
    50% { box-shadow: inset 0 -3px 5px rgba(0, 0, 0, .5), 0 0 14px rgba(90, 225, 255, .8); }
  }

  /* LES ÉTAPES, GRAVÉES DANS LE VERRE. */
  .prompt .opt-nom, .prompt .opt-valeur { position: relative; z-index: 1; background: none; border: 0; }
  .prompt .opt-nom { min-width: 0; }
  .prompt .opt-nom b {
    font-family: var(--font-body), sans-serif; font-size: 11px; line-height: 1;
    letter-spacing: .02em; text-transform: none; color: #a7a2b3;
    text-shadow: 0 1px 1px rgba(0, 0, 0, .8);
  }
  /* Le compte « 0/1 » se tait : la barre dit déjà ce qui est fait. */
  .prompt .opt-valeur { display: none !important; }
  .prompt .opt-valeur { flex: none; font: 700 10px/1 var(--font-num, sans-serif); color: #8a8596; text-shadow: 0 1px 1px rgba(0, 0, 0, .8); }
  .prompt .opt--fait:not(.opt:not(.opt--fait) ~ .opt--fait) :is(.opt-nom b, .opt-valeur) { color: #f2fff5; text-shadow: 0 1px 2px rgba(0, 60, 20, .9); }
  .prompt .opt--ouvert:not(.opt--ouvert ~ .opt--ouvert) .opt-nom b { color: #e9fbff; font-weight: 800; }
  .prompt .opt--ouvert:not(.opt--ouvert ~ .opt--ouvert) .opt-valeur { color: #8fe9f8; }

  /* L'abandon rejoint le pupitre, dans sa troisième colonne : il ne flotte
     plus sur la planche, et le pouce ne le frôle pas en jouant. */
  .wheel-bar {
    left: auto; bottom: auto;
    right: calc(6px + 8px);
    top: calc(6px + 6px + env(safe-area-inset-top));
    z-index: 40;
  }
  .match-actions .arena-ctrl { width: 36px; height: 36px; }
}

/* LA ROUE NE PORTE QUE L'ÉLÉMENT. « ASCENDANT » au-dessus du nom de l'élément
   débordait du cœur de la pièce ; l'élément allumé suffit à le dire. */
.roue-table .roue-coeur-lbl { display: none; }

/* ══ LA CARTE EN GRAND, AVANT DE LA JOUER ══════════════════════════════════
   Toucher une carte de la main l'ouvre au centre, sur un voile : on la LIT.
   « Placer » referme la loupe et allume les places ; « Fermer » (ou le voile)
   la repose. Voir renderLecture() dans main.js. */
.lecture-carte {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: radial-gradient(ellipse at 50% 45%, rgba(10, 8, 16, .55), rgba(3, 2, 6, .88));
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: lc-voile .2s ease both;
}
.lecture-carte[hidden] { display: none; }
.lc-cadre { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.lc-img {
  display: block;
  width: min(80vw, calc(64dvh * 1024 / 1610), 420px); height: auto;
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .75), 0 0 0 1px rgba(255, 255, 255, .08);
  animation: lc-carte .28s cubic-bezier(.2, 1.3, .4, 1) both;
}
.lc-gestes { display: flex; gap: 12px; }
.lc-gestes button { min-width: 136px; min-height: 48px; font-size: 15px; border-radius: 12px; }
@keyframes lc-voile { from { opacity: 0; } }
@keyframes lc-carte { from { transform: scale(.82) translateY(20px); opacity: 0; } }

@media (max-width: 820px) and (orientation: portrait) {
  /* Le bouton « Annuler » passait à la ligne, sous la consigne, à moitié
     caché : la consigne et ses boutons tiennent sur une seule rangée. */
  .prompt { flex-wrap: nowrap; gap: 8px; align-items: center; }
  .prompt .msg { flex: 1 1 auto; min-width: 0; }
  .prompt > button { flex: none; min-height: 30px; padding: 4px 12px; font-size: 12px; }
}
.lc-note { align-self: center; font-size: 13px; color: #c9c1b2; }
/* La barre de vie prend la largeur de la carte qu'elle accompagne. */
.lc-cadre .vie-barre { align-self: stretch; margin-top: 0; }

/* ══════════════════════════════════════════════════════════════════════════
 *  L'ACCUEIL TIENT DANS L'ÉCRAN — LES DEUX TUILES, ENTIÈRES
 *
 *  L'accueil du téléphone n'a que deux tuiles : la présentation et le
 *  grimoire. Elles étaient pourtant écrites en pixels — titre, boutons,
 *  gages de confiance, livre — et leur somme dépassait l'écran de quarante
 *  pixels : le bouton « Tenter l'Anomalie » finissait sous la barre du bas,
 *  et sur un téléphone plus court la tuile du grimoire disparaissait en
 *  entier. Ce n'est pas une question de réglage : une pile de hauteurs fixes
 *  dans une boîte de hauteur variable ne peut pas tenir partout.
 *
 *  Tout ce qui pèse se mesure donc en `vh`, borné des deux côtés : l'éventail
 *  (qui prend ce qu'on lui laisse), le titre, les boutons, les gages, le
 *  grimoire. Les deux tuiles rétrécissent ensemble quand l'écran est court
 *  au lieu que la seconde passe par-dessus bord.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  /* La page s'arrête au ras de la barre du bas : plus rien à faire défiler. */
  .home { min-height: 0; gap: clamp(4px, .8vh, 8px); margin-bottom: 0; }

  /* ── La tuile de présentation ──
     L'éventail est une image, pas un bloc : il n'a pas besoin de sa marge
     au-dessus ni du couloir vide qu'il laissait sous lui. Le haut de la
     tuile se resserre, et la colonne de texte REMONTE DEVANT l'éventail —
     le kicker et le K de KAIROS passent sur le bas des cartes, là où il n'y
     a que des cadres. Une trentaine de pixels rendus au bas de la page,
     ce qui suffit à faire entrer « Tenter l'Anomalie » au-dessus de la
     barre des onglets. */
  .home-hero { padding: clamp(2px, .5vh, 6px) 12px clamp(6px, 1.2vh, 10px); gap: 0; }
  .hero-cards-stage { position: relative; z-index: 0; margin-bottom: clamp(-30px, -3.4vh, -12px); }
  .hero-text-col { position: relative; z-index: 2; }
  /* Le texte posé sur les cartes se lit quand même : une ombre portée, pas
     un voile — le voile aurait éteint l'éventail. */
  .home-kicker, .hero-title { text-shadow: 0 2px 10px rgba(0, 0, 0, .85), 0 0 22px rgba(0, 0, 0, .7); }
  /* L'éventail rend les quelques pixels que la vitrine des raretés prend
     en bas : deux rangées de cartes sur un écran de téléphone, c'est la
     seconde qui vend. */
  .hero-cards-fan { --fan-h: clamp(104px, 16.5vh, 216px); }
  .hero-title { font-size: clamp(24px, 4.4vh, 34px); }
  .btn-hero-cta { padding: clamp(7px, 1.2vh, 11px) 12px; font-size: clamp(12px, 1.7vh, 13.5px); }
  .hero-cta-group { gap: clamp(4px, .8vh, 6px); }
  /* Les quatre gages tenaient sur quatre lignes, une par gage. Deux colonnes
     les rendent au même prix que deux lignes de texte. */
  .hero-trust {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: 2px clamp(6px, 1.4vw, 12px);
    margin-top: clamp(4px, .9vh, 10px);
    font-size: clamp(8.5px, 1.25vh, 10.5px); line-height: 1.35;
    text-align: left;
  }
  .hero-trust span { gap: 5px; }

  /* ── La tuile du grimoire ── */
  .home-booster-altar {
    --grimoire: clamp(72px, 12.5vh, 132px);
    padding: clamp(6px, 1.1vh, 10px) 10px; gap: 10px;
  }
  /* Le livre était écrit deux fois en dur (190, puis 130 sous 760 px), et
     toujours avec un sélecteur plus fort que le nôtre : il gardait ses
     130 px sur un écran de 640 et poussait le bouton dehors. */
  .home-booster-altar .altar-pack-preview { width: var(--grimoire); height: var(--grimoire); }
  .home-booster-altar .altar-pack-side { padding-bottom: clamp(24px, 3.4vh, 30px); }
  .appel-titre { font-size: clamp(14px, 2.3vh, 18px); }
  .altar-pack-actions .btn-open-pack-main { padding: clamp(8px, 1.3vh, 12px) 12px; }

  /* ── LA TUILE DU GRIMOIRE DOIT DONNER ENVIE, PAS COMPTER ──────────────
     Au large, ce qui vend le grimoire n'est pas le bouton : c'est la
     vitrine des six raretés, l'escalier d'une Commune garantie jusqu'à
     l'Anomalie « 1 sur mille », et la promesse des cent exemplaires au
     monde. Le téléphone jetait tout cela (`.appel-kicker`, `.appel-ligne`,
     `.vitrine-raretes` en `display:none`) et ne gardait que le livre, un
     titre et un bouton rose : une caisse, pas une vitrine.

     On les remet, à l'échelle du pouce : le livre et l'accroche sur une
     rangée, puis les six cartes en dessous, pleine largeur. Une carte de
     48 px ne se lit pas, mais elle se COMPARE — c'est le dégradé de rareté
     qui parle, et sous chacune le seul chiffre qui compte. */
  .home-booster-altar {
    display: grid;
    grid-template-columns: var(--grimoire) minmax(0, 1fr);
    align-items: center; text-align: left;
    gap: clamp(6px, 1.2vh, 10px) 10px;
  }
  /* La vitrine est enfouie dans `.altar-appel`, donc deux boîtes sous la
     grille : `display: contents` les efface et remonte leurs enfants au
     rang de cases, ce qui laisse poser le livre à gauche, l'accroche à
     droite, et la vitrine puis le bouton en pleine largeur. */
  .home-booster-altar .altar-stats-side,
  .home-booster-altar .altar-appel { display: contents; }
  .home-booster-altar .altar-pack-side { grid-column: 1; grid-row: 1 / span 3; }
  .appel-kicker, .appel-titre, .appel-ligne { grid-column: 2; min-width: 0; }
  .home-booster-altar .altar-pack-actions { grid-column: 1 / -1; max-width: none; margin-top: 0; }
  /*  L'invite reste masquee : sous le livre retreci elle se plie en trois
      lignes par-dessus la couverture. Le compteur dore dit deja combien il
      reste, et le livre entier est cliquable. */
  .altar-invite { display: none; }

  .appel-kicker {
    display: block; font-size: clamp(7.5px, 1.1vh, 9px); letter-spacing: .2em;
  }
  .appel-titre { font-size: clamp(15px, 2.5vh, 20px); line-height: 1.05; }
  .appel-ligne {
    display: block; font-size: clamp(9.5px, 1.4vh, 11.5px); line-height: 1.35;
  }
  .altar-pack-actions .btn-open-pack-main { padding: clamp(8px, 1.3vh, 12px) 12px; }

  /* La vitrine traverse les deux colonnes : c'est la pièce qui vend. */
  .home-booster-altar .vitrine-raretes {
    display: grid; grid-column: 1 / -1;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: clamp(3px, 1.2vw, 7px); margin-top: 0; max-width: none;
  }
  .vr-item { gap: 2px; }
  /* Le nom de la rareté ne tient pas sous 50 px : la couleur du cadre le dit
     déjà, et le chiffre en dessous fait le reste. */
  .vr-nom, .vr-tirage { display: none; }
  .vr-chance { font-size: 0; line-height: 1; }
  .vr-chance b {
    font-size: clamp(8px, 1.25vh, 10px); line-height: 1.1; letter-spacing: -.02em;
    white-space: nowrap;
  }
  .vr-carte { border-radius: 4px; box-shadow: 0 3px 8px rgba(0, 0, 0, .55), 0 0 0 1px color-mix(in srgb, var(--rc) 55%, transparent); }

  /* Sur les écrans vraiment courts, les gages cèdent la place : ils se
     relisent au large, le grimoire ne se voit qu'ici. */
  @media (max-height: 660px) {
    .hero-trust { display: none; }
    /* L'accroche cède avant la vitrine : la vitrine EST l'argument. Le
       livre se resserre avec elle, sinon il creuse un vide à droite : c'est
       lui qui dicte la hauteur de la rangée. */
    .appel-ligne { display: none; }
    .home-booster-altar { --grimoire: clamp(62px, 9.5vh, 96px); }
  }
}

/* ══════════════════════════════════════════════════════════════════════════
 *  LE CARTABLE AU TÉLÉPHONE : LA PAGE D'ABORD
 *
 *  1. LES INTERCALAIRES DESCENDENT, ET CESSENT D'ÊTRE DES LANGUETTES.
 *  La scène du classeur est une rangée : flèche, pages, languettes, flèche.
 *  Sous 900 px les languettes se couchaient bien à l'horizontale, mais elles
 *  restaient DANS la rangée — 228 px posés à droite des pages, à mi-hauteur.
 *  Les deux ensemble dépassaient l'écran : le classeur était poussé hors du
 *  bord gauche et la bande barrait les pochettes.
 *
 *  Elles descendent sur leur propre ligne, sous le classeur. Et là, elles ne
 *  jouent plus les intercalaires : une languette dit « je sors du papier »,
 *  ce qui n'a de sens qu'accrochée au bord d'une page. Posée seule sous le
 *  classeur, avec son bord gauche ouvert et son décalage vers le bas, elle
 *  ressemblait à un onglet arraché. C'est donc une BARRE DE SECTIONS : six
 *  pastilles égales dans un même cadre, celle où l'on est prend la couleur
 *  de son élément. Même structure, même DOM, même geste.
 *
 *  2. LA PAGE PREND TOUT CE QUI RESTE.
 *  Une pochette faisait 64 px de large : on ne voyait pas les cartes. La
 *  page se mesure à sa hauteur (trois colonnes sur quatre rangs), donc tout
 *  pixel rendu au classeur en haut ou en bas revient en largeur de carte.
 *  On récupère partout : le blanc autour des pochettes, l'écart entre elles,
 *  la barre des sections, le pied, les marges du corps.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  /* ── La scène : les languettes sur leur propre ligne ── */
  .cartable-scene { flex-wrap: wrap; align-content: center; row-gap: 4px; gap: 2px; }
  .cartable-scene > .cart-fleche--g { order: 1; }
  .cartable-scene > .cart-reliure { order: 2; }
  .cartable-scene > .cart-fleche--d { order: 3; }
  .ct-elements-marge {
    order: 4; flex: 1 0 100%; width: 100%;
    align-self: auto; justify-content: center;
    margin: 0; padding: 0;
    /* Le cadre commun : c'est lui qui fait une barre de six, et non six
       languettes posées côte à côte. */
    gap: 2px; border-radius: 10px; padding: 2px;
    background: rgba(20, 16, 10, .55);
    border: 1px solid rgba(201, 162, 39, .16);
    max-width: 320px; margin: 0 auto;
  }
  .ct-onglet,
  .ct-onglet + .ct-onglet,
  .ct-onglet:first-child,
  .ct-onglet:last-child {
    flex: 1 1 0; width: auto; height: 32px;
    border: 0; border-radius: 8px; background: none;
  }
  .ct-onglet > i { width: 20px; height: 20px; }
  /* « On est ici » ne sort plus du papier : la pastille s'allume sur place. */
  .ct-onglet.is-ici {
    transform: none;
    background: color-mix(in srgb, var(--el, #c9a227) 24%, rgba(20, 16, 10, .8));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--el, #c9a227) 55%, transparent);
  }

  /* ── Tout le reste se serre pour agrandir les cartes ── */
  .cartable { --ct-marge: 5px; }
  .cart-grille { gap: 3px; }
  .cartable-corps { gap: 4px; padding: 6px 4px 6px; }
  .cart-pied { gap: 10px; }
  .cart-compteur { font-size: 11px; }
  /* Le classeur se mesurait à la scène entière (`height: 100%`) : la ligne
     des sections, ajoutée dessous, débordait d'autant et venait couvrir le
     compteur de feuilles. Il lui laisse sa hauteur, et rien de plus. */
  .cartable-scene > .cart-reliure { height: calc(100% - 40px); }
  /* Les flèches ne prennent plus de largeur au classeur : elles se posent
     sur ses bords, là où il n'y a que du cuir. */
  .cartable-scene > .cart-fleche { width: 30px; min-width: 0; margin: 0 -4px; }

  /* ══ LE PROFIL TIENT DANS UN ECRAN ══════════════════════════════════════
     Sous 900 px, la carte s'empilait et se centrait : un avatar de 190 px,
     un nom en 38, et il fallait faire rouler la page pour voir ne serait-ce
     que le bouton « Modifier ». Or un profil se consulte d'un coup d'oeil --
     qui je suis, ou j'en suis, ce que j'ai. Tout doit donc etre visible sans
     defiler, et c'est la hauteur disponible qui commande les tailles. */
  #view-profil { overflow: hidden; }
  .profil-page {
    height: 100%; padding: 8px 10px 10px; gap: 8px;
    justify-content: flex-start;
    /*  LE FILET. Les tailles ci-dessous suivent la hauteur disponible et la
        page tient dans les formats courants -- mais un ecran tres court, ou
        un texte grossi par le systeme, la fera toujours deborder. Plutot que
        de couper le kit en deux sans recours, on laisse defiler. */
    overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  }
  /*  La carte redevient une LIGNE : l'avatar a gauche, l'identite a droite.
      Centree, elle imposait sa largeur a la hauteur. */
  .pf-carte {
    grid-template-columns: auto minmax(0, 1fr); gap: 14px;
    justify-items: start; text-align: left;
    padding: clamp(8px, 1.4vh, 12px) 14px; border-radius: 14px;
  }
  .pf-ident { align-items: flex-start; gap: 4px; }
  .pf-avatar {
    width: clamp(56px, 9vh, 74px); height: clamp(56px, 9vh, 74px);
    box-shadow: 0 0 0 3px #1c2433, 0 0 0 5px #c9a246, 0 0 20px rgba(232, 194, 90, .3);
  }
  .pf-avatar .dl-initiales { font-size: 26px; }
  .pf-titre { font-size: 10px; letter-spacing: .16em; }
  .pf-nom { font-size: clamp(16px, 2.5vh, 20px); line-height: 1.05; }
  .pf-desc { font-size: 12px; }
  .pf-niveau { margin-top: 2px; gap: 8px; flex-wrap: wrap; }
  .pf-niveau b { font-size: clamp(13px, 1.9vh, 15px); }
  .pf-niveau span { font-size: 11px; }
  .pf-jauge { height: 7px; }
  /*  DEUX LIGNES POUR LA MEME CHOSE. « 80 / 120 XP avant le niveau 2 » est
      juste au-dessus ; le total cumule n'apprend rien de plus a qui regarde
      son telephone, et il coutait une ligne a une page qui debordait. */
  .pf-xp-total { display: none; }
  #view-profil .pf-modifier { margin-top: 3px; padding: 5px 11px; font-size: 11.5px; border-radius: 8px; }

  /*  Huit tuiles en deux rangees de quatre : a deux colonnes elles faisaient
      quatre rangees et mangeaient le kit. */
  .pf-bloc { padding: 10px 12px 12px; border-radius: 14px; }
  .pf-bloc h2 { margin: 0 0 8px; font-size: 15px; }
  .pf-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .pf-stat { padding: 7px 8px; border-radius: 9px; }
  .pf-stat b { font-size: clamp(15px, 2.2vh, 18px); }
  .pf-stat.est-vide b { font-size: 15px; }
  .pf-stat span { font-size: 9.5px; line-height: 1.15; }
  .pf-note { font-size: 11px; }

  /*  LES VIGNETTES DU KIT ETAIENT CARREES DE 190 px DANS UNE COLONNE DE 105 :
      elles poussaient la page cinquante pixels sous la barre, et c'est le kit
      qu'on ne voyait plus. Elles se calent sur la largeur de leur tuile. */
  .pf-kit { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  #view-profil .pf-tuile .pf-vue { height: clamp(64px, 13vh, 108px); }
  #view-profil .pf-tuile .pf-vue img { width: 100%; height: 100%; }
  /* Le de est un canvas de 120 px, pose la par le moteur : il debordait de sa
     tuile par la droite. On le ramene dans le cadre sans toucher au rendu. */
  #view-profil .pf-tuile .pf-vue .pf-de { width: 100%; height: 100%; }
  #view-profil .pf-tuile { padding: 8px; border-radius: 10px; }
  .pf-tuile-txt b { font-size: 12px; }
  .pf-tuile-txt span { font-size: 10px; }
}
/* ══════════════════════════════════════════════════════════════════════════
 *  TROIS FENÊTRES QUI S'ÉCHAPPAIENT DU POUCE
 *
 *  Trois pannes du même genre, toutes au téléphone : quelque chose de
 *  nécessaire finissait hors de l'écran, et rien ne permettait d'aller le
 *  chercher.
 *
 *  1. LE PUPITRE REMONTAIT. Il était posé en `absolute` dans la vue, donc
 *     dans le DOCUMENT. Sur un téléphone, `overflow: hidden` sur le corps
 *     n'empêche pas le navigateur de faire glisser le document lui-même :
 *     un glisser de carte qui rebondit, la barre d'adresse qui se replie, et
 *     le pupitre partait par le haut avec « Finir le tour ». On le fixe au
 *     RÉGARD, pas au document, et on verrouille vraiment le défilement
 *     pendant la partie.
 *
 *  2. LA LOUPE ÉTAIT UNE VITRE. Au large, elle laisse passer le pointeur
 *     pour qu'un clic à côté ouvre une autre créature -- seuls ses boutons
 *     l'arrêtent. Au téléphone elle occupe tout l'écran : il n'y a plus de
 *     « à côté », et `pointer-events: none` interdisait de la FAIRE DÉFILER.
 *     Une créature avec ses bonus et deux compétences poussait « Attaquer »
 *     sous le bord, hors d'atteinte : plus aucune action possible.
 *
 *  3. « FERMER » ÉTAIT EN BAS DE LA FICHE. Dernier élément d'une colonne qui
 *     commence par une carte plein écran : on ne le voyait pas, et rien ne
 *     disait qu'il fallait défiler.
 *
 *  La réponse est la même aux trois endroits : ce qui ferme et ce qui agit
 *  s'ancre à l'écran, et ce qui déborde se fait défiler pour de vrai.
 * ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. LE PUPITRE NE BOUGE PLUS ──────────────────────────────────────── */
/*  Les deux orientations : un téléphone couché fait glisser son document
 *  exactement comme un téléphone debout. */
@media (max-width: 820px) {
  /*  Le verrou du défilement. `overflow: hidden` seul laisse iOS emporter le
   *  document ; un corps posé en `fixed` sur les quatre bords n'a plus rien
   *  à faire glisser. */
  body.play-on {
    position: fixed; inset: 0; width: 100%; height: 100%;
    overscroll-behavior: none;
  }
  /*  Fixé au regard, pas au document : il garde sa place quoi que le
   *  navigateur fasse glisser dessous. Ses bords, eux, restent dits par la
   *  règle de l'orientation. */
  .game-module { position: fixed; }
}
@media (max-width: 820px) and (orientation: portrait) {
  .game-module {
    top: calc(6px + env(safe-area-inset-top, 0px));
    left: 6px; right: 6px; bottom: auto;
  }
}

/*  Au large, la loupe se referme d'un clic sur la table : la croix n'aurait
 *  qu'à encombrer le coin d'un panneau déjà lisible. */
.loupe-x { display: none; }

/* ── 2. LA LOUPE SE TOUCHE, ET SE FAIT DÉFILER ────────────────────────── */
@media (max-width: 820px) {
  .loupe {
    position: fixed; inset: 8px; transform: none; z-index: 40;
    /*  Elle prend le pointeur : elle couvre tout l'écran, il n'y a plus de
     *  table à toucher au travers. C'est ce qui lui rend le défilement. */
    pointer-events: auto;
    overflow-y: auto; overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 10px 12px 14px;
  }
  .loupe-scene { flex: 0 0 auto; }
  .loupe-gestes {
    min-width: 0; max-width: none; max-height: none; overflow: visible;
    display: flex; flex-direction: column; gap: 8px;
  }
  /*  Tout se presse, plus seulement les boutons : la règle du large
   *  (`pointer-events: auto` sur les seuls gestes) n'a plus lieu d'être. */
  .loupe > *, .loupe-gestes > * { pointer-events: auto; }
  .loupe-gestes button { min-height: 44px; }
  .loupe-action { min-height: 44px; }
  /*  LA CROIX, POSÉE SUR L'ÉCRAN.
   *
   *  Elle doit rester au coin quoi qu'on fasse défiler. Un premier essai en
   *  `fixed` repartait avec le contenu : le FLOU D'ARRIÈRE-PLAN de la loupe
   *  en fait un bloc conteneur, et tout `fixed` à l'intérieur s'y rattache.
   *  Le flou ne sert plus à rien ici -- au téléphone la loupe couvre l'écran,
   *  il n'y a plus de table à deviner au travers -- on le retire, et la croix
   *  retrouve le regard pour repère. */
  .loupe { backdrop-filter: none; -webkit-backdrop-filter: none; }
  .loupe-x {
    display: grid; position: fixed;
    top: calc(16px + env(safe-area-inset-top, 0px)); right: 16px; margin: 0;
    z-index: 3; width: 38px; height: 38px; padding: 0;
    place-items: center;
    font-size: 22px; line-height: 1; font-weight: 400;
    color: var(--ink, #ece6f5);
    background: rgba(12, 9, 18, .92);
    border: 1px solid var(--line-gold, rgba(201, 162, 70, .42));
    border-radius: 50%;
  }
}
/*  Debout, la loupe est une colonne -- la carte en haut, les gestes dessous ;
 *  couché, elle garde les deux côte à côte : la hauteur est ce qui manque. */
@media (max-width: 820px) and (orientation: portrait) {
  .loupe { flex-direction: column; align-items: stretch; }
  /*  La carte cède de la hauteur à ce qui se presse. Elle occupait plus de
   *  la moitié de l'écran pendant que les compétences attendaient dessous. */
  .loupe-carte { height: min(34vh, 300px); }
}
@media (max-width: 820px) and (orientation: landscape) {
  .loupe { flex-direction: row; align-items: flex-start; flex-wrap: wrap; }
  .loupe-carte { height: min(72vh, 300px); }
  .loupe-gestes { flex: 1 1 200px; }
}

/* ── 3. LA FICHE SE FERME DU COIN ─────────────────────────────────────── */
@media (max-width: 820px) {
  .card-zoom { padding: 56px 10px 16px; place-items: start center; }
  .zoom-print { max-height: 54vh; }
  .zoom-wrap { padding: 12px; gap: 10px; }
}
/*  Elle ne coûte rien au large, et elle y rend le même service : la sortie
 *  se voit sans lire la colonne jusqu'au bout. */
.card-zoom .zoom-x {
  position: fixed; z-index: 10;
  top: calc(10px + env(safe-area-inset-top, 0px)); right: 12px;
  width: 42px; height: 42px; padding: 0;
  display: grid; place-items: center;
  font-size: 24px; line-height: 1; font-weight: 400;
  color: var(--ink, #ece6f5);
  background: rgba(12, 9, 18, .92);
  border: 1px solid var(--line-gold, rgba(201, 162, 70, .42));
  border-radius: 50%;
  pointer-events: auto;
}
.card-zoom .zoom-fermer { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
 *  LES ECRANS COURTS (iPhone SE, telephone en barre d'onglets ouverte)
 *
 *  A 667 px de haut, le profil deborde encore de quatre-vingts pixels une
 *  fois toutes les tailles au minimum. Ce qui part alors, c'est le DETAIL --
 *  « 0/40 cartes · 0 pts · boite Noir » -- et non une rubrique entiere : le
 *  kit garde son image et son nom, qui suffisent a dire ce qu'on a equipe.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) and (max-height: 720px) {
  #view-profil .pf-tuile .pf-vue { height: clamp(58px, 11vh, 86px); }
  .pf-tuile-txt span { display: none; }
  .pf-bloc { padding: 8px 10px 9px; }
  .pf-bloc h2 { margin-bottom: 6px; font-size: 14px; }
  .pf-stat { padding: 5px 7px; }
  .pf-stats { gap: 5px; }
  .pf-kit { gap: 6px; }
  .profil-page { gap: 6px; padding: 6px 8px 8px; }
}

/* ══════════════════════════════════════════════════════════════════════════
 *  LA BIBLIOTHEQUE DES DECKS, AU TELEPHONE
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  .bib-voile { padding: 0; place-items: stretch; }
  .bib {
    width: 100%; max-height: none; height: 100dvh;
    border: 0; border-radius: 0;
  }
  .bib-tete { padding: calc(10px + env(safe-area-inset-top, 0px)) 12px 10px; }
  .bib-tete h2 { font-size: 19px; }
  .bib-corps { padding: 12px 12px calc(16px + env(safe-area-inset-bottom, 0px)); }
  .bib-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 10px; }
  .bib-nom { font-size: 14px; }
  /* Sans souris, il n'y a pas de survol : la croix reste visible. */
  .bib-x { opacity: 1; }

  /*  Le nom du deck et « Mes decks », descendus dans la feuille du deck par
      `placerIdentiteDeck()`. Une ligne pleine largeur au-dessus de
      « Construire » : on nomme, puis on construit. */
  /*  La ligne se collait a la barre des onglets posee juste au-dessus de la
      feuille : deux barres l'une sur l'autre, sans rien pour dire ou finit
      l'une. Elle prend de l'air et un filet. */
  .dk-ident-feuille {
    display: flex; flex-direction: row; align-items: center; gap: 8px;
    width: 100%; margin: 6px 0 10px; padding: 0 0 10px;
    border-bottom: 1px solid rgba(201, 162, 70, .18);
  }
  .dk-ident-feuille .dk-mes { flex: none; }
  .dk-ident-feuille .dk-liste-btn { min-height: 40px; padding: 0 12px; }
  .dk-ident-feuille .dk-nom { flex: 1 1 auto; min-width: 0; }
  .dk-ident-feuille .deck-name { width: 100%; min-height: 40px; font-size: 14px; }
}

/* ══════════════════════════════════════════════════════════════════════════
 *  LE CREUSET, AU TELEPHONE
 *
 *  L'autel place ses dix emplacements en ABSOLU, a des pourcentages calcules
 *  pour une table large : sur 467 px, les cartes se chevauchaient, passaient
 *  par-dessus la carte a forger et sortaient du cadre des deux cotes.
 *  Ici, il n'y a pas de table : il y a une colonne. La cible en haut, les dix
 *  consommables en deux rangees de cinq, et plus rien qui se recouvre.
 *
 *  ET ON NE DIT QUE CE QUI S'APPREND. Le titre « Forge » repete l'onglet
 *  allume ; « -10 consommees · +1 forgee » repete les dix emplacements et la
 *  case du haut ; « Pret. » repete le bouton allume. Trois lignes rendues au
 *  visuel, qui est la seule chose qu'on ne peut pas deviner.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  #view-forge .cartable-tete { display: none; }
  .fg-solde { display: none; }
  .fg-pourquoi { font-size: 11.5px; margin: 5px 0 0; }
  .fg-pourquoi[hidden] { display: none; }

  .fg-autel { padding: 10px; overflow: hidden auto; }

  /*  CREUSET VIDE : rien d'autre a montrer, l'invite prend le milieu. */
  .fg-autel:not(.a-cible) { display: flex; align-items: center; justify-content: center; }
  .fg-autel:not(.a-cible) .fg-creuset {
    position: static; transform: none; flex-direction: column; gap: 10px;
  }
  .fg-autel:not(.a-cible) .fg-creuset-case { width: clamp(132px, 44vw, 190px); }

  /*  CREUSET ARME : la cible en haut, les consommables en rangees egales.
      Le nombre de colonnes vient de `--fentes-cols`, pose par forge_vue.js --
      il etait fige a 5, le compte d'une Commune, et toutes les autres raretes
      finissaient avec une derniere rangee tassee a gauche. */
  /*  DE L'AIR ENTRE LES DEUX RANGEES. Collees, elles formaient un bloc de
      dix vignettes ; ecartees, les filaments de lumiere qui montent des
      cartes vers le creuset passent entre elles -- c'est l'effet qu'on a sur
      l'ecran large, ou les cartes sont posees en arc. */
  /*  Les colonnes font la largeur calculee par `ajusterFentes`, et non une
      fraction de la place disponible : une colonne en `1fr` prend toute la
      largeur et laisse la hauteur deborder, ce qui ramenait le defilement
      des que le ratio passait sous dix. */
  .fg-autel.a-cible {
    display: grid;
    grid-template-columns: repeat(var(--fentes-cols, 5), var(--fente-w));
    column-gap: 10px; row-gap: var(--fentes-ecart, 30px);
    /*  `safe` : si un ecran trop court faisait malgre tout deborder, un
        centrage normal rognerait le HAUT, donc le creuset, et il deviendrait
        inatteignable. Le mot-cle fait retomber sur un alignement au debut
        dans ce cas -- on perd le bas, qu'on peut encore atteindre. */
    align-content: safe center; justify-content: center;
  }
  /*  `position: relative` pour porter l'etiquette -- mais il faut alors
      neutraliser le `left: 50%` de la regle de base, qui servait a centrer un
      bloc ABSOLU et qui, en relatif, decale la carte d'une demi-largeur
      d'autel vers la droite. */
  .fg-autel.a-cible .fg-creuset {
    position: relative; left: auto; top: auto; transform: none;
    grid-column: 1 / -1;
    flex-direction: column; align-items: center; justify-content: flex-start;
    gap: 2px; margin-bottom: 12px;
  }
  /*  LE TITRE S'INSCRIT DANS LA CARTE. Pose a cote, il flottait dans le vide
      a gauche d'une carte centree ; il tient maintenant DANS la zone de la
      carte a produire, en haut, comme l'etiquette d'un emplacement. */
  .fg-autel.a-cible .fg-creuset-case {
    --w: clamp(80px, 21.5vw, 104px);
    width: var(--w); height: calc(var(--w) * 1610 / 1024); aspect-ratio: auto; flex: none;
  }
  .fg-creuset-dit {
    position: static; transform: none; white-space: normal;
    align-items: center; text-align: center; font-size: 11px;
  }
  .fg-creuset-dit b { font-size: 13px; }

  /*  Les emplacements quittent l'absolu. Leurs `left`/`top` en ligne
      deviennent inertes ; la grille s'occupe du reste. */
  /*  La largeur vient de `--fente-w`, que `ajusterFentes` calcule en pesant
      la place restante en hauteur comme en largeur : c'est ce qui garde la
      Forge sur une seule page a toutes les raretes. Le centrage se fait par
      `justify-self` et NON par `margin-inline: auto` -- sur un element de
      grille, des marges automatiques annulent l'etirement. */
  .fg-fente {
    position: static; z-index: auto;
    height: auto; aspect-ratio: 1024 / 1610; margin: 0;
    width: var(--fente-w); justify-self: center;
  }
  /*  Le survol grossissait la carte x2,1 : sans souris, c'est le pouce qui
      declenche -- et la carte sortait du cadre. */
  .fg-fente.est-pleine:hover > .cf { transform: none; }

  /*  Les commandes tiennent sur une rangee, en boutons courts. */
  .fg-commandes {
    display: grid; grid-template-columns: 1fr 1fr 1.4fr; gap: 6px; align-items: center;
  }
  .fg-commandes button {
    min-height: 38px; padding: 0 6px; font-size: 12.5px; border-radius: 9px;
  }
  .fg-commandes .fg-go { width: 100%; justify-self: stretch; }
}
