/* =============================================================================
   BOUTIQUE (shop-screen.js, docs/shop-spec.md) : onglets et solde en haut, la grille du rayon à
   gauche (seule zone qui défile), l'essayage et le bouton d'achat à droite. Blocs unis séparés par
   des filets, jetons --screen-* seulement (AGENTS.md). Aussi : la case Boutique de MON PERSO et la
   modale d'ouverture.
   ============================================================================= */

.arcade-home-body #arcade-panel-shop .shop-screen {
  --shop-gap: clamp(10px, 2cqw, 20px);
  position: relative;
  display: grid; grid-template-rows: auto auto minmax(0, 1fr); gap: clamp(8px, 1.8cqh, 16px);
  width: 100%; overflow: clip; overflow-clip-margin: 8px;
}

/* ---- Onglets et solde ---- */
.shop-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--shop-gap); min-width: 0; padding-bottom: clamp(6px, 1.2cqh, 10px); border-bottom: 1px solid var(--screen-line); }
.shop-filters { display: flex; align-items: center; gap: clamp(2px, .8cqw, 8px); min-width: 0; }
.arcade-home-body .shop-filter {
  min-height: 34px; padding: 4px clamp(6px, 1.1cqw, 12px);
  border: 0; border-bottom: 3px solid transparent; border-radius: 0;
  background: none; box-shadow: none; color: var(--screen-muted);
  font: clamp(16px, 2.9cqh, 22px)/1 'Jersey 15', sans-serif; letter-spacing: .06em; text-transform: uppercase; cursor: pointer;
}
/* Le rayon actif n'a que son trait (les flèches changent de rayon : focus et rayon actif ne font
   qu'un). Le focus y épaissit le trait, sans viseur ni teinte. */
.arcade-home-body .shop-filter:is(:hover, .is-selected, :focus-visible) { outline: none; background: none; color: var(--screen-ink); }
.arcade-home-body .shop-filter[aria-selected='true'] { border-bottom-color: var(--screen-accent); color: var(--screen-accent); }
.arcade-home-body .shop-filter[aria-selected='true']:is(.is-selected, :focus-visible) { box-shadow: 0 2px var(--screen-accent); }

.shop-wallet {
  display: flex; align-items: center; gap: 9px; flex: none;
  min-height: 38px; padding: 4px 10px;
  border: 1px solid var(--screen-line); background: var(--screen-panel); color: var(--screen-muted);
  font: clamp(13px, 2.2cqh, 16px)/1 'Jersey 15', sans-serif; letter-spacing: .08em;
}
.shop-wallet strong { color: var(--screen-prestige-gold-ink); font: normal clamp(24px, 4.2cqh, 32px)/1 'Jersey 15', sans-serif; }

/* ---- Grille et essayage ---- */
.shop-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) clamp(230px, 31cqw, 320px);
  gap: var(--shop-gap); min-height: 0;
}

.shop-catalog {
  --shop-row-gap: clamp(10px, 1.8cqh, 16px);
  /* Une page = deux rangées entières (shop-screen.js pagesOf) : jamais de carte coupée, la
     pagination dit la suite. Le viseur déborde de 11px : rogné plus loin, sans zone qui défile. */
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr));
  align-content: stretch; align-items: stretch; gap: var(--shop-row-gap) clamp(10px, 1.6cqw, 16px);
  flex: 1; min-height: 0; margin: 0; padding: 12px; box-sizing: border-box;
  list-style: none; overflow: clip; overflow-clip-margin: 14px;
}
/* Le rayon : la grille et, dessous, sa pagination. */
.shop-aisle { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.shop-pager {
  display: flex; align-items: center; justify-content: center; gap: clamp(10px, 1.8cqw, 18px);
  flex: none; min-height: clamp(34px, 6cqh, 44px); padding-top: 4px; color: var(--screen-ink);
  font: clamp(18px, 3cqh, 24px)/1 'Jersey 15', sans-serif; letter-spacing: .08em;
}
.shop-pager[hidden] { display: none; }
.shop-pager-label { display: inline-flex; align-items: baseline; gap: 10px; text-transform: uppercase; }
.shop-pager-title { color: var(--screen-mint); }
.shop-pager-title:empty, .shop-pager-count:empty { display: none; }
.shop-pager-dots { display: inline-flex; gap: 6px; }
.shop-pager-dots > span { width: 8px; height: 8px; background: var(--screen-line); }
.shop-pager-dots > span.is-current { background: var(--screen-accent); }
/* Les flèches pixel du carrousel de MON PERSO (.look-pixel-arrow), dans une case cliquable. */
.arcade-home-body .shop-pager-step {
  display: grid; place-items: center; width: clamp(30px, 5.6cqh, 40px); aspect-ratio: 1; padding: 0;
  border: 2px solid var(--screen-line); border-radius: 0; background: var(--screen-bg); box-shadow: 0 3px var(--screen-shadow);
  cursor: pointer;
}
.arcade-home-body .shop-pager-step .look-pixel-arrow { background: var(--screen-ink); }
.arcade-home-body .shop-pager-step:hover { border-color: var(--screen-accent); background: var(--screen-tint); }
.arcade-home-body .shop-pager-step:hover .look-pixel-arrow { background: var(--screen-accent); }
.arcade-home-body .shop-pager-step:active { translate: 0 2px; box-shadow: 0 1px var(--screen-shadow); }
.arcade-home-body .shop-pager-step:disabled { opacity: .3; cursor: default; translate: none; border-color: var(--screen-line); background: var(--screen-bg); }
.arcade-home-body .shop-pager-step:disabled .look-pixel-arrow { background: var(--screen-muted); }
.shop-pager-step[hidden] { display: none; }
/* La grille glisse d'un cran vers la page suivante, en pas francs comme un sprite. */
/* Changement de page : les cartes arrivent une à une (--i, posé par shop-screen.js) en sautant comme
   des Plops, depuis le côté où l'on va, et se posent avec un petit tassement. Pas francs (steps), comme
   les sprites ; seules les cartes bougent, jamais à l'échelle. */
.shop-catalog:is(.is-paging-next, .is-paging-prev) > li {
  animation: shop-card-hop-next 340ms steps(7) both; animation-delay: calc(var(--i, 0) * 45ms);
}
.shop-catalog.is-paging-prev > li { animation-name: shop-card-hop-prev; }
@keyframes shop-card-hop-next {
  0% { translate: 48px 6px; opacity: 0; }
  35% { translate: 18px -14px; opacity: 1; }
  70% { translate: 0 -4px; }
  85% { translate: 0 2px; }
  100% { translate: 0 0; }
}
@keyframes shop-card-hop-prev {
  0% { translate: -48px 6px; opacity: 0; }
  35% { translate: -18px -14px; opacity: 1; }
  70% { translate: 0 -4px; }
  85% { translate: 0 2px; }
  100% { translate: 0 0; }
}
/* Changement de rayon : une chute courte depuis le haut, plus rapide que le changement de page, pour
   ne pas ralentir quand on fait défiler les onglets. */
.shop-catalog.is-entering > li { animation: shop-card-drop 200ms steps(4) both; animation-delay: calc(var(--i, 0) * 25ms); }
@keyframes shop-card-drop {
  0% { translate: 0 -18px; opacity: 0; }
  60% { translate: 0 2px; opacity: 1; }
  100% { translate: 0 0; }
}
/* La flèche utilisée donne un coup dans son sens, les points suivent d'un cran. */
.shop-pager-step.is-paging-next .look-pixel-arrow { animation: shop-arrow-kick-next 200ms steps(2) both; }
.shop-pager-step.is-paging-prev .look-pixel-arrow { animation: shop-arrow-kick-prev 200ms steps(2) both; }
@keyframes shop-arrow-kick-next { 50% { translate: 4px 0; } }
@keyframes shop-arrow-kick-prev { 50% { translate: -4px 0; } }
.shop-pager-dots.is-paging-next > .is-current { animation: shop-dot-in-next 220ms steps(3) both; }
.shop-pager-dots.is-paging-prev > .is-current { animation: shop-dot-in-prev 220ms steps(3) both; }
@keyframes shop-dot-in-next { from { translate: -14px 0; } }
@keyframes shop-dot-in-prev { from { translate: 14px 0; } }
@media (prefers-reduced-motion: reduce) {
  .shop-catalog:is(.is-paging-next, .is-paging-prev, .is-entering) > li,
  .shop-pager-step .look-pixel-arrow, .shop-pager-dots > .is-current { animation: none; }
}
.shop-catalog > li { display: flex; min-width: 0; margin: 0; padding: 0; }

.arcade-home-body .shop-item {
  --cursor-gap: -3px;
  --shop-card-bg: var(--screen-panel);
  /* La rangée mesure tout le contenu : aucun enfant ne déborde dans son espacement. */
  display: flex; flex-direction: column; flex: 1 1 auto;
  align-items: stretch; min-width: 0; min-height: auto; height: auto; margin: 0; padding: 0;
  /* La rareté se lit d'un coup d'œil : une barre de sa couleur au pied de la carte. */
  --shop-rarity: var(--screen-mint);
  overflow: visible; border: 1px solid transparent; border-radius: 0;
  box-shadow: inset 0 -4px color-mix(in srgb, var(--shop-rarity) 85%, transparent);
  background: var(--shop-card-bg); color: var(--screen-ink); text-align: left; cursor: pointer;
}
.arcade-home-body .shop-item:is(:hover, .is-selected, :focus-visible) { outline: none; background: color-mix(in srgb, var(--screen-accent) 16%, var(--shop-card-bg)); }
/* L'objet choisi (shop-screen.js) : liseré d'accent, même quand le curseur est sur Acheter. */
.arcade-home-body .shop-item.is-current { border-color: var(--screen-accent); }
.arcade-home-body .shop-item[data-rarity='rare'] { --shop-rarity: var(--screen-prestige-diamond); }
.arcade-home-body .shop-item[data-rarity='epic'] { --shop-rarity: var(--screen-prestige-legend); }
.arcade-home-body .shop-item[data-rarity='prestige'] { --shop-rarity: var(--screen-prestige-gold); }

.shop-item-art {
  --shop-blob-size: clamp(76px, 15.5cqh, 124px);
  position: relative; display: grid; place-items: center; flex: 0 0 auto;
  height: calc(var(--shop-blob-size) * .94); min-height: min-content; padding: 8px;
  overflow: hidden; border: 0; background: none;
}
/* Même ombre douce sous tous les personnages, sans ligne de sol flottante. Sur une carte, elle suit
   la taille du blob : les pieds du sprite (120 px) touchent la ligne 117, l'ombre se centre juste
   au-dessus, aussi large que le corps, comme sous la collection de MON PERSO. */
.shop-item-art:has(> .shop-blob)::before {
  content: ''; grid-area: 1 / 1; width: calc(var(--shop-blob-size) * .7); height: calc(var(--shop-blob-size) * .09);
  border-radius: 50%; background: color-mix(in srgb, var(--screen-shadow) 35%, transparent);
  transform: translateY(calc(var(--shop-blob-size) * .35));
}
.shop-detail-stage:has(> .shop-blob)::before {
  content: ''; grid-area: 1 / 1; width: 54%; max-width: 90px; height: 9px;
  border-radius: 50%; background: color-mix(in srgb, var(--screen-shadow) 35%, transparent);
  transform: translateY(clamp(28px, 5.5cqh, 44px));
}
.shop-item-art > .shop-blob, .shop-detail-stage > .shop-blob { grid-area: 1 / 1; }
.shop-detail-stage:has(> .shop-blob)::before {
  max-width: 130px; height: 12px; transform: translateY(clamp(44px, 9.5cqh, 76px));
}
.shop-item-art > * { z-index: 1; }
.shop-item-art > .shop-blob { position: relative; }
/* Le sprite garde 30 % de vide au-dessus de la tête : le perso (et son ombre, plus haut) remonte d'un
   cran pour que la carte respire autant en haut qu'en bas. */
.shop-item-art > .shop-blob { translate: 0 -10%; }
/* Pas de plancher « contenu + padding » : la zone suit la taille du blob, le vide du sprite suffit. */
.shop-item-art:has(> .shop-blob) { min-height: 0; padding-block: 0; }
.shop-item-art > .shop-emote-bubble { translate: 0 clamp(-8px, -1cqh, -3px); }
.shop-blob { width: var(--shop-blob-size, clamp(72px, 14cqh, 112px)); height: var(--shop-blob-size, clamp(72px, 14cqh, 112px)); max-width: 100%; object-fit: contain; image-rendering: pixelated; }
.shop-blob.is-silhouette { filter: brightness(0) opacity(.55); }
.shop-art-icon {
  position: absolute; top: 6px; right: 7px; color: var(--screen-accent);
  font-size: clamp(13px, 2.4cqh, 18px); text-shadow: 0 2px var(--screen-shadow);
}

.shop-item-copy {
  display: flex; flex-direction: column; flex: 1 0 auto; gap: 6px;
  padding: clamp(10px, 1.7cqh, 14px) clamp(10px, 1.7cqh, 14px) clamp(14px, 2.8cqh, 24px); min-width: 0; box-sizing: border-box;
}
.shop-item-copy > .shop-price { margin-top: auto; padding-top: 4px; }
/* Rayons : rareté, nom et prix centrés sous le perso (la vitrine « À la une » garde son affiche). */
.shop-panel:not(.is-featured) .shop-item-copy { align-items: center; text-align: center; }
.shop-panel:not(.is-featured) .shop-item-copy .shop-item-meta { justify-content: center; }
.shop-item-copy small {
  overflow: hidden; color: var(--screen-mint); text-overflow: ellipsis; white-space: nowrap;
  font: clamp(13px, 2.3cqh, 18px)/1 'Jersey 15', sans-serif; letter-spacing: .08em;
}
.shop-item-copy .shop-item-meta { display: flex; flex-wrap: wrap; gap: 4px 6px; white-space: normal; line-height: 1.1; }
.shop-item-meta > span:first-child { color: var(--screen-muted); }
.shop-item-meta > span + span::before { content: '·'; margin-right: 6px; color: var(--screen-muted); }
.shop-item[data-rarity='rare'] .shop-item-copy small { color: var(--screen-prestige-diamond-ink); }
.shop-item[data-rarity='epic'] .shop-item-copy small { color: var(--screen-prestige-legend-ink); }
.shop-item[data-rarity='prestige'] .shop-item-copy small { color: var(--screen-prestige-gold-ink); }
.shop-item-copy > strong {
  color: var(--screen-ink); white-space: normal; overflow-wrap: break-word; text-wrap: balance;
  font: normal clamp(19px, 3.8cqh, 30px)/1.1 'Jersey 15', sans-serif; letter-spacing: .03em;
}

.shop-price { display: inline-flex; align-items: center; gap: 7px; color: var(--screen-accent); font: clamp(15px, 2.6cqh, 20px)/1 'Jersey 15', sans-serif; letter-spacing: .04em; }
.shop-price b { font-weight: normal; }
/* Prix d'une carte : en grand, avec la grande pièce (coins.css), lisible d'un coup d'œil. */
.shop-item-copy > .shop-price { gap: 9px; font-size: clamp(20px, 3.8cqh, 30px); }
.shop-price.is-owned { color: var(--screen-clear); }
/* La gemme des défis réussis (arcade-ui.css), de la taille de la pièce qu'elle remplace : 16 px
   (petite pièce), 26 px sur une carte (la grande pièce de 32 px a 3 px de vide autour du disque). */
.shop-price .shop-owned-badge { --cdb-px: calc(16px / 11); filter: drop-shadow(0 2px var(--screen-shadow)); }
/* Sur une carte, « POSSÉDÉ » est un état, pas un prix : plus discret, gemme de 18 px (comme au HUD des défis). */
.shop-item-copy > .shop-price.is-owned { gap: 6px; font-size: clamp(16px, 2.8cqh, 21px); letter-spacing: .06em; }
.shop-item-copy > .shop-price .shop-owned-badge { --cdb-px: calc(18px / 11); }
.shop-price.is-prestige { color: var(--screen-muted); }
.shop-price.is-expensive { color: var(--screen-muted); }
.shop-price.is-expensive .coin-icon { filter: grayscale(1); opacity: .6; }
/* Promo du jour : la remise en couleur promo, précédée de l'étoile de la vitrine, sans boîte (pas de
   cadre dans le cadre) ; le prix plein barré suit le prix soldé. */
.arcade-home-body .shop-item { position: relative; }
.shop-deal-tag {
  position: absolute; top: clamp(6px, 1.3cqh, 10px); left: clamp(8px, 1.6cqh, 12px); z-index: 2; color: var(--screen-warning);
  font: clamp(15px, 2.7cqh, 20px)/1 'Jersey 15', sans-serif; letter-spacing: .04em; pointer-events: none;
}
/* Dans un rayon, la carte est son propre conteneur : l'étiquette suit sa largeur. */
.shop-panel:not(.is-featured) .shop-deal-tag { font-size: clamp(15px, 11cqw, 20px); }
.shop-deal-tag::before { content: '✦ '; font-family: sans-serif; font-size: .8em; opacity: .8; }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-deal-tag {
  top: clamp(8px, 1.9cqh, 14px); left: clamp(10px, 2.2cqh, 16px); font-size: clamp(20px, 4cqh, 30px);
}
/* Promo du jour : le prix plein, barré, après le prix soldé. */
.shop-price .shop-price-full { color: var(--screen-muted); font-size: .8em; text-decoration-thickness: 2px; }
/* Un nombre ne se coupe jamais ; le prix barré passe dessous si la carte est étroite. */
.shop-price { flex-wrap: wrap; row-gap: 4px; }
.shop-price b, .shop-price .shop-price-full { white-space: nowrap; }

/* Bulle d'emote, comme au-dessus du blob en match. */
.shop-emote-bubble {
  /* Apparence fournie par .game-emote-bubble ; seuls le placement et la taille changent. */
  position: relative; left: auto; top: auto; max-width: 94%; margin-bottom: 8px;
  transform: none; animation: none; font-size: clamp(19px, 3.4cqh, 27px);
  color: var(--screen-bubble-ink); border-color: var(--screen-bubble-ink);
  background: linear-gradient(180deg, var(--screen-prestige-shine), var(--screen-bubble-bg) 46%);
  box-shadow: 0 4px 0 color-mix(in srgb, var(--screen-bubble-ink) 92%, transparent),
    0 14px 26px color-mix(in srgb, var(--screen-shadow) 24%, transparent);
}
.shop-emote-bubble::before { border-top-color: var(--screen-bubble-ink); }
.shop-emote-bubble::after { border-top-color: var(--screen-bubble-bg); }

/* ---- Cartes des rayons : chaque carte est un conteneur, le perso remplit ce que le texte laisse ---- */
.shop-panel:not(.is-featured) .shop-item { container: shop-card / size; }
.shop-panel:not(.is-featured) .shop-item-art { --shop-blob-size: min(66cqh, 92cqw); flex: 1 1 0; height: auto; min-height: 0; }
.shop-panel:not(.is-featured) .shop-item-art > .shop-emote-bubble { font-size: clamp(16px, 11cqw, 24px); }
/* Animation : canvas 120 × 150, pieds en bas ; un peu plus petit que les sprites des autres cartes
   pour garder ses effets (notes, nuage) dans la carte. */
.shop-panel:not(.is-featured) .shop-item-art > .shop-card-canvas {
  width: calc(var(--shop-blob-size) * .8); height: auto; max-width: none; max-height: none; align-self: end; margin-bottom: 4%;
}
.shop-panel:not(.is-featured) .shop-item-copy { flex: none; gap: 4px; padding: 2px 8px 14px; }
.shop-panel:not(.is-featured) .shop-item-copy small { font-size: 15px; }
.shop-panel:not(.is-featured) .shop-item-copy > strong { font-size: clamp(18px, 13cqw, 26px); line-height: 1; }
.shop-panel:not(.is-featured) .shop-item-copy > .shop-price { padding-top: 2px; font-size: clamp(19px, 13cqw, 26px); }
.shop-panel:not(.is-featured) .shop-item-copy > .shop-price.is-owned { font-size: 17px; }
/* Prix ou « possédé » : même hauteur de ligne, les textes restent alignés d'une carte à l'autre. */
.shop-panel:not(.is-featured) .shop-item-copy > .shop-price { min-height: 1.15em; box-sizing: content-box; }
.shop-panel:not(.is-featured) .shop-item-copy > .shop-price.is-owned { min-height: calc(clamp(19px, 13cqw, 26px) * 1.15); }
/* Carte basse (cadre 1024 × 640) : la barre de couleur dit déjà la rareté. */
@container shop-card (max-height: 210px) {
  .shop-panel:not(.is-featured) .shop-item-copy small { display: none; }
  .shop-panel:not(.is-featured) .shop-item-copy { gap: 2px; padding-bottom: 10px; }
  .shop-panel:not(.is-featured) .shop-item-copy > strong { font-size: 18px; }
  .shop-panel:not(.is-featured) .shop-item-copy > .shop-price { font-size: 19px; }
}

/* ---- L'étal : store, marchand derrière son comptoir, essayage devant, puis la fiche ---- */
.shop-detail {
  display: flex; flex-direction: column; min-height: 0; min-width: 0;
  border-left: 1px solid var(--screen-line); padding-left: var(--shop-gap);
}
.shop-counter { --shop-stripe: 18px; position: relative; flex: none; }
/* Store rayé aux couleurs du gilet du marchand, festonné : un feston par rayure. */
.shop-awning {
  height: clamp(18px, 3.4cqh, 26px);
  background: repeating-linear-gradient(90deg, var(--screen-sand-light) 0 var(--shop-stripe), var(--screen-sand) var(--shop-stripe) calc(var(--shop-stripe) * 2));
  -webkit-mask: radial-gradient(calc(var(--shop-stripe) / 2) at calc(var(--shop-stripe) / 2) 0, #000 97%, transparent) 0 100% / var(--shop-stripe) calc(var(--shop-stripe) / 2) repeat-x,
    linear-gradient(#000 0 0) top / 100% calc(100% - var(--shop-stripe) / 2) no-repeat;
  mask: radial-gradient(calc(var(--shop-stripe) / 2) at calc(var(--shop-stripe) / 2) 0, #000 97%, transparent) 0 100% / var(--shop-stripe) calc(var(--shop-stripe) / 2) repeat-x,
    linear-gradient(#000 0 0) top / 100% calc(100% - var(--shop-stripe) / 2) no-repeat;
}
.shop-merchant-row { display: flex; align-items: center; gap: 4px; min-width: 0; padding: 2px 0 0; }
/* Au fond de la scène, plus petit que le joueur. 96 px de canvas = 32 pixels d'art : affiché à
   96 px, chaque pixel d'art fait 3 px pile (4 px à 128, 2 px à 64). */
.shop-merchant-portrait {
  --shop-merchant-size: 96px;
  position: relative; display: block; flex: none; width: var(--shop-merchant-size); height: var(--shop-merchant-size);
  margin: 0 -4px -8px -6px; image-rendering: pixelated;
}
.shop-merchant-speech { position: relative; flex: 1; min-width: 0; align-self: stretch; display: flex; align-items: center; }
.shop-merchant-bubble {
  position: relative; display: inline-block; margin: 0 0 0 12px; max-width: calc(100% - 12px); box-sizing: border-box;
  padding: 7px 10px; font-size: clamp(16px, 2.7cqh, 21px); line-height: 1.05;
  text-wrap: balance; box-shadow: 0 3px 0 var(--screen-bubble-ink);
  animation: shop-merchant-bubble-in 420ms both; transform-origin: 0 50%;
}
/* La même gelée que les emotes de match, sans leur placement au-dessus de la tête. */
@keyframes shop-merchant-bubble-in {
  0% { opacity: 0; transform: scale(.2); animation-timing-function: steps(2, end); }
  25% { opacity: 1; transform: scale(1.2, .78); animation-timing-function: steps(2, end); }
  50% { transform: scale(.9, 1.12); animation-timing-function: steps(2, end); }
  75% { transform: scale(1.05, .96); animation-timing-function: steps(1, end); }
  100% { opacity: 1; transform: none; }
}
.shop-merchant-bubble[hidden] { display: none; }
/* La pointe vise le marchand, à gauche. */
.shop-merchant-bubble::before, .shop-merchant-bubble::after { top: 50%; bottom: auto; left: auto; transform: translateY(-50%); }
.shop-merchant-bubble::before { right: 100%; border: 9px solid transparent; border-left: 0; border-right: 13px solid var(--screen-bubble-ink); }
.shop-merchant-bubble::after { right: calc(100% - 3px); border: 6px solid transparent; border-left: 0; border-right: 9px solid var(--screen-bubble-bg); }
@media (prefers-reduced-motion: reduce) { .shop-merchant-bubble { animation: none; } }
/* Le comptoir en bois passe devant le bas du marchand. */
.shop-counter-top {
  position: relative; z-index: 1; height: 12px;
  background: var(--screen-sand-shade);
  box-shadow: inset 0 3px var(--screen-sand), 0 3px var(--screen-sand-shadow);
}
.shop-detail-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.shop-detail-badge {
  flex: none; min-height: 20px; padding: 3px 7px; box-sizing: border-box;
  background: var(--screen-mint); color: var(--screen-bg);
  font: 14px/1 'Jersey 15', sans-serif; letter-spacing: .1em;
}
.shop-detail-badge:empty { visibility: hidden; }
.shop-detail-badge[data-rarity='rare'] { background: var(--screen-prestige-diamond); color: var(--screen-prestige-outline); }
.shop-detail-badge[data-rarity='epic'] { background: var(--screen-prestige-legend); color: var(--screen-prestige-outline); }
.shop-detail-badge[data-rarity='prestige'] { background: var(--screen-prestige-gold); color: var(--screen-prestige-outline); }
/* Une scène en profondeur : le marchand au fond derrière son comptoir, le joueur au premier plan,
   plus grand, son îlot de sable devant le comptoir. */
.shop-scene {
  --shop-stage-overlap: clamp(24px, 9cqh, 76px);
  position: relative; display: flex; flex-direction: column; flex: 1; min-height: 0;
  margin-bottom: 8px; border-bottom: 1px solid var(--screen-line);
}
.shop-detail-stage {
  position: relative; z-index: 2; display: grid; place-items: center; flex: 1; min-height: 120px; overflow: visible;
  margin-top: calc(var(--shop-stage-overlap) * -1);
}
.shop-stage-anim { position: relative; display: grid; place-items: center; }
.shop-detail-stage .shop-blob { width: clamp(110px, 24cqh, 190px); height: clamp(110px, 24cqh, 190px); }
.shop-detail-stage .shop-emote-bubble { font-size: clamp(18px, 3.6cqh, 28px); padding: 8px 14px; }
.shop-stage-canvas { width: clamp(130px, 30cqh, 220px); height: auto; image-rendering: pixelated; }
.shop-card-canvas { display: block; width: 100%; height: 100%; max-width: 180px; min-width: 0; min-height: 0; object-fit: contain; image-rendering: pixelated; }
.shop-art-anim { min-height: 0; }
.shop-detail-meta > span:first-child { color: var(--screen-mint); font: clamp(12px, 2cqh, 15px)/1 'Jersey 15', sans-serif; letter-spacing: .1em; }
.shop-detail-copy h3 {
  margin: 4px 0 0; color: var(--screen-ink); white-space: normal; overflow-wrap: break-word; text-wrap: balance;
  font: normal clamp(24px, 4.6cqh, 36px)/1 'Jersey 15', sans-serif; letter-spacing: .03em;
}
.shop-detail:has(.shop-detail-stage[data-type='emote']) .shop-detail-copy h3 { font-size: clamp(20px, 3.5cqh, 28px); }

.arcade-home-body .shop-buy {
  --cursor-gap: -4px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; flex-shrink: 0; min-height: clamp(42px, 7.5cqh, 56px); margin-top: clamp(8px, 1.8cqh, 14px); padding: 7px 12px;
  border: 0; border-radius: 0; background: var(--screen-accent); color: var(--screen-accent-ink);
  box-shadow: inset -3px -3px color-mix(in srgb, var(--screen-accent) 60%, var(--screen-shadow)),
    inset 3px 3px color-mix(in srgb, var(--screen-accent) 70%, var(--screen-ink)), 0 4px var(--screen-shadow);
  font: clamp(20px, 3.6cqh, 27px)/1 'Jersey 15', sans-serif; letter-spacing: .06em; text-transform: uppercase; cursor: pointer;
}
.arcade-home-body .shop-buy:is(:hover, .is-selected, :focus-visible) { outline: none; filter: brightness(1.08); }
.shop-buy .shop-price { color: inherit; font-size: inherit; }
.shop-buy .shop-price[hidden] { display: none; }
.arcade-home-body .shop-buy.is-confirming { background: var(--screen-accent); color: var(--screen-accent-ink); }
.arcade-home-body .shop-buy.is-disabled { background: var(--screen-raised); color: var(--screen-muted); box-shadow: 0 3px var(--screen-shadow); cursor: default; filter: none; }
.shop-buy.is-disabled .coin-icon { filter: grayscale(1); opacity: .6; }
.shop-detail-status { min-height: 1em; margin: 8px 0 0; color: var(--screen-muted); font: clamp(14px, 2.4cqh, 18px)/1 'Jersey 15', sans-serif; text-align: center; }

/* Essayage sur l'îlot de sable de MON PERSO (blobby-stage.js) ; une emote en bulle au-dessus. */
/* La scène a la taille du podium : la bulle d'une emote se pose juste au-dessus de la tête. */
.shop-stage-scene { position: relative; width: clamp(150px, 38cqh, 270px); max-width: 100%; aspect-ratio: 1; }
.shop-stage-podium { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
/* Le podium garde du vide en haut du canvas pour le saut : le perso et son sable (lignes 49 à 145
   sur 152) tombaient 14 % sous le milieu de l'encart. On remonte la scène d'autant ; une emote
   garde sa place, sa bulle remplit le haut. Même décalage pour tous les objets : le perso ne
   bouge pas d'un objet à l'autre. */
.shop-detail-stage:not([data-type='emote']) .shop-stage-scene { translate: 0 -13%; }
/* Animation (end-animations.js) : son canvas 120 × 168 garde le haut pour les sauts ; même remontée,
   plus petite, et jamais plus haut que l'encart (la rangée de l'encart prend toute sa hauteur). */
.shop-detail-stage[data-type='anim'] { grid-template-rows: minmax(0, 1fr); }
.shop-detail-stage[data-type='anim'] .shop-stage-anim { translate: 0 -12.5%; }
.arcade-home-body .shop-stage-scene > .shop-emote-bubble {
  /* Placée comme en match (game.css) : « top » = bas de la bulle, pointe au-dessus de la tête (la
     plus haute coiffe touche la ligne 36 sur 152), et la même entrée en gelée à chaque emote choisie. */
  position: absolute; top: 17%; bottom: auto; left: 50%; max-width: none; margin: 0; white-space: nowrap;
  transform: translate(-50%, -100%); transform-origin: 50% calc(100% + .5rem);
  animation: game-emote-bubble-in 420ms both;
}
/* Plus petite et plus bas : la bulle tient sous le comptoir, le sable au-dessus du filet. */
.shop-detail-stage[data-type='emote'] .shop-stage-scene { width: clamp(130px, 28cqh, 210px); translate: 0 14%; }
/* Cadre bas (1024×640) : bulle et perso ne tiennent pas dans l'encart à la taille plancher du podium. */
@container (max-height: 480px) {
  .shop-detail-stage[data-type='emote'] .shop-stage-scene { width: 104px; }
}
@media (prefers-reduced-motion: reduce) {
  .arcade-home-body .shop-stage-scene > .shop-emote-bubble { animation: none; }
}

/* Moment de l'achat : pièces qui volent du porte-monnaie à l'objet, confettis pixel. */
.shop-fx { position: absolute; inset: 0; z-index: 5; overflow: visible; pointer-events: none; }
.shop-fly-coin { position: absolute; top: 0; left: 0; translate: -16px -16px; filter: drop-shadow(0 2px var(--screen-shadow)); }
.shop-confetti { position: absolute; image-rendering: pixelated; }

/* Achat réussi : la fiche clignote deux fois, comme un objet ramassé. */
.shop-screen.is-bought .shop-scene { animation: shop-bought 480ms steps(2) 2; }
@keyframes shop-bought { 50% { background: color-mix(in srgb, var(--screen-prestige-gold) 22%, var(--screen-bg)); } }
@media (prefers-reduced-motion: reduce) { .shop-screen.is-bought .shop-scene { animation: none; } }

/* ---- Cadre compact ---- */
@container (max-width: 780px) {
  .shop-catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .shop-layout { grid-template-columns: minmax(0, 1fr) 190px; }
  .shop-toolbar { gap: 6px; }
  .shop-filters { gap: 2px; }
  .arcade-home-body .shop-filter { padding-inline: 6px; letter-spacing: .03em; }
  .shop-wallet { gap: 5px; padding-inline: 7px; }
  .shop-wallet > span:last-child { display: none; }
}
@container (min-height: 700px) {
  .shop-merchant-portrait { --shop-merchant-size: 128px; margin: 0 -6px -10px -8px; }
}
@container (max-height: 560px) {
  .shop-scene { --shop-stage-overlap: 26px; margin-bottom: 5px; }
  .shop-stage-scene { width: 124px; }
  .shop-stage-canvas { width: 110px; }
  /* 64 px : 2 px par pixel d'art, toujours net ; l'essayage garde la place. */
  .shop-merchant-portrait { --shop-merchant-size: 64px; margin: 0 -2px -5px -4px; }
  .shop-counter { --shop-stripe: 12px; }
  .shop-awning { height: 13px; }
  .shop-merchant-bubble { padding: 4px 8px; font-size: 15px; }
  .shop-counter-top { height: 9px; }
  .shop-detail-stage { min-height: 100px; }
  .shop-detail-copy h3 { font-size: 24px; }
  .arcade-home-body .shop-buy { white-space: nowrap; font-size: 18px; letter-spacing: .03em; padding-inline: 10px; }
  .shop-detail-status { margin-top: 5px; }
}
@media (max-width: 760px) {
  .arcade-home-body #arcade-panel-shop .shop-screen { overflow: visible; }
  .shop-toolbar { flex-wrap: wrap; }
  .shop-filters { flex-wrap: wrap; }
  .shop-layout { grid-template-columns: 1fr; }
  .shop-catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); max-height: min(52svh, 420px); overflow-y: auto; }
  .shop-detail { border-left: 0; border-top: 1px solid var(--screen-line); padding: 14px 0 0; }
  .shop-detail-stage { flex: none; min-height: 120px; }
}

/* ---- À la une : une affiche vedette en largeur (perso à gauche, texte à droite) et quatre
   découvertes ; l'étal du marchand reste à droite ---- */
.shop-panel.is-featured .shop-catalog {
  grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: clamp(10px, 1.6cqw, 16px); padding: 5px; scrollbar-gutter: auto;
  /* Le viseur s'ouvre 11px au-delà de la carte : il ne doit pas créer de zone défilante. */
  overflow: clip; overflow-clip-margin: 14px;
}
.shop-panel.is-featured .shop-catalog > li:first-child { grid-column: span 2; }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item {
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); align-items: center;
}
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item-art { align-self: stretch; }
.shop-panel.is-featured .shop-item {
  position: relative; min-height: 0;
  border-color: transparent; display: grid; grid-template-rows: minmax(0, 1fr) auto;
}
.shop-panel.is-featured .shop-item-art { height: auto; min-height: 0; border: 0; padding: 2px 6px; background: none; }
.shop-panel.is-featured .shop-item-copy { gap: 3px; padding: clamp(8px, 1.6cqh, 14px); }
.shop-panel.is-featured .shop-item-copy > strong { min-height: 0; font-size: clamp(18px, 3cqh, 25px); }
.shop-panel.is-featured .shop-item-copy > .shop-price { padding-top: 3px; }
.shop-panel.is-featured .shop-item-meta { font-size: clamp(10px, 1.6cqh, 13px); }
.shop-panel.is-featured .shop-item-meta > span + span { display: none; }
.shop-panel.is-featured .shop-blob { width: clamp(90px, 19cqh, 150px); height: 100%; max-height: 100%; }
.shop-panel.is-featured .shop-card-canvas { max-width: 100%; }
.shop-panel.is-featured .shop-item-art::before { display: none; }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item { --shop-card-bg: color-mix(in srgb, var(--screen-mint) 19%, var(--screen-bg)); }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item::before {
  content: '✦'; position: absolute; top: 8%; right: 12%; color: var(--screen-mint);
  font: clamp(35px, 7cqh, 60px)/1 sans-serif; opacity: .45; transform: rotate(12deg); pointer-events: none;
}
.shop-panel.is-featured .shop-catalog > li:first-child .shop-blob { width: clamp(130px, 30cqh, 260px); }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item-copy { padding: clamp(14px, 3cqh, 26px); gap: 6px; }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item-copy > strong { font-size: clamp(36px, 7cqh, 58px); line-height: .9; text-transform: uppercase; }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item-meta { font-size: clamp(13px, 2.2cqh, 17px); }
.shop-panel.is-featured .shop-catalog > li:first-child .shop-item-meta > span + span { display: inline; }
.shop-panel.is-featured .shop-emote-bubble { font-size: clamp(16px, 2.6cqh, 23px); padding: .4em .55em; }
@media (max-width: 760px) {
  .shop-panel.is-featured .shop-catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: 240px; grid-auto-rows: 190px; max-height: none; overflow: visible; }
  .shop-panel.is-featured .shop-catalog > li:first-child { grid-row: auto; }
  .shop-panel.is-featured .shop-catalog > li:first-child .shop-item { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; align-items: center; }
  .shop-panel.is-featured .shop-catalog > li:first-child .shop-item-art { height: 180px; }
}

/* ---- MON PERSO : Le Marchand, une ligne pleine largeur sous le Look (solde à gauche, flèche à droite) ---- */
.arcade-home-body #arcade-panel-player .character-shop-link { grid-template-columns: minmax(0, 1fr) auto; }
.character-shop-balance { display: inline-flex; align-items: center; gap: 8px; color: var(--screen-ink); font: clamp(20px, 3.4cqh, 26px)/1 'Jersey 15', sans-serif; white-space: nowrap; }
.character-shop-balance strong { color: var(--screen-prestige-gold-ink); font-weight: normal; }
.character-shop-unit { color: var(--screen-muted); font-size: .7em; letter-spacing: .1em; }

/* ---- Modale d'ouverture ---- */
.arcade-home-body #arcade-panel-shop-launch .arcade-panel-body.shop-launch {
  display: grid; justify-items: center; align-content: center; gap: clamp(10px, 2.4cqh, 22px); text-align: center;
}
.shop-launch-title { margin: 0; color: var(--screen-accent); font: clamp(30px, 6.4cqh, 54px)/1 'Jersey 15', sans-serif; letter-spacing: .04em; }
.shop-launch-copy { margin: 0; color: var(--screen-ink); font: clamp(18px, 3.4cqh, 28px)/1.1 'Jersey 15', sans-serif; }
.shop-launch-gift { display: inline-flex; align-items: center; gap: 12px; margin: 0; color: var(--screen-prestige-gold); font: clamp(36px, 8cqh, 68px)/1 'Jersey 15', sans-serif; }
.shop-launch-gift strong { font-weight: normal; }
.shop-launch-gift span:last-child { color: var(--screen-muted); font-size: .4em; letter-spacing: .1em; }
.arcade-home-body .shop-launch-go {
  min-height: 48px; padding: 8px 22px; border: 0; border-radius: 0;
  background: var(--screen-accent); color: var(--screen-accent-ink);
  font: clamp(20px, 3.6cqh, 28px)/1 'Jersey 15', sans-serif; letter-spacing: .06em; text-transform: uppercase; cursor: pointer;
}

/* Let the featured artwork shrink with the space left above its caption. */
.shop-panel.is-featured .shop-item-art > .shop-blob,
.shop-panel.is-featured .shop-item-art > .shop-card-canvas {
  position: absolute; inset: 0; margin: auto; width: 100%; height: 100%;
  max-width: 100%; max-height: 100%; object-fit: contain; translate: none;
}
@media (min-width: 761px) {
  /* Cadre bas : les cartes restent empilées (perso au-dessus, texte dessous), en plus serré. */
  @container (max-height: 560px) {
    .shop-panel.is-featured .shop-item-copy { padding: 4px 7px 9px; gap: 1px; }
    .shop-panel.is-featured .shop-item-copy > .shop-price { padding-top: 1px; font-size: 17px; gap: 4px; }
    .shop-panel.is-featured .shop-item-copy > strong { font-size: 16px; }
    .shop-panel.is-featured .shop-item-meta { display: none; }
    .shop-panel.is-featured .shop-catalog > li:first-child .shop-item-copy { padding: 8px 10px 12px; }
    .shop-panel.is-featured .shop-catalog > li:first-child .shop-item-copy > strong { font-size: 30px; }
    .shop-panel.is-featured .shop-item-art > .shop-emote-bubble { font-size: 13px; padding: 3px 6px; margin: 0; translate: none; }
    .shop-panel.is-featured .shop-art-icon { font-size: 11px; top: 3px; right: 3px; }
  }
}
/* On phones the shop extends the console vertically, and the page itself scrolls. */
@media (max-width: 760px) {
  body.arcade-home-body:has(#arcade-panel-shop:not([hidden])) { overflow-y: auto; }
  .arcade-home-body .arcade-cabinet:has(#arcade-panel-shop:not([hidden])) { display: block; height: auto; min-height: 100dvh; overflow: visible; }
  .arcade-home-body .arcade-screen:has(#arcade-panel-shop:not([hidden])) {
    display: block; container-type: inline-size; min-height: 100dvh; height: auto;
    padding: 32px 16px 72px; overflow: visible; box-sizing: border-box;
  }
  .arcade-home-body #arcade-panel-shop:not([hidden]) {
    position: relative; inset: auto; transform: none; width: 100%; height: auto;
    max-height: none; aspect-ratio: auto; container-type: inline-size;
    border-radius: var(--arcade-screen-radius); box-shadow: var(--arcade-bezel);
  }
  .arcade-home-body .arcade-screen:has(#arcade-panel-shop:not([hidden])) > .arcade-bezel { display: none; }
  .arcade-home-body #arcade-panel-shop .shop-screen { height: auto; grid-template-rows: auto auto auto auto; }
  .shop-panel.is-featured .shop-catalog { grid-template-rows: 190px; grid-auto-rows: 170px; }
  .shop-panel.is-featured .shop-catalog > li:first-child .shop-item-copy { padding: 8px; }
  .shop-panel.is-featured .shop-catalog > li:first-child .shop-item-copy > strong { font-size: 32px; }
}
@media (max-width: 760px) {
  .arcade-home-body .arcade-attract:has(#arcade-panel-shop:not([hidden])) {
    position: relative; inset: auto; transform: none; display: block;
    width: 100%; height: auto; min-height: 0; aspect-ratio: auto;
    padding: 0; overflow: visible; container-type: inline-size;
  }
}
@media (max-width: 760px) {
  .arcade-home-body .arcade-attract:has(#arcade-panel-shop:not([hidden])) > :not(#arcade-panel-shop) { display: none; }
  .arcade-home-body .arcade-screen:has(#arcade-panel-shop:not([hidden])) { overflow-x: clip; }
}
