/* File: market.css
   THE MARKET — the shelf, the seller's desk, the price history.

   Rewritten when the page moved to three views. The first version put the shelf, the
   filters, the seller's own listings and the price history on one screen and it read as
   clutter — so the layout lost its side column entirely and each view now gets the full
   width. Anything that only matters while SELLING lives in the SELLING view.

   Reuses .cards-subtabs / .cards-filter / .card-stat from cards.css rather than restating
   them: a filter pill and a stat chip must look the same everywhere in the app, and two
   copies drift apart within a month.

   Class names here are queried by market.js (.listing, .mkt-btn, .summary) — renaming one
   is a JS change, not just a style change. */

.market-body { padding: 0 0 40px; }
.market-tabs { margin-bottom: 18px; }
.market-view { min-height: 200px; }

/* ---------- toolbar ---------- */

.market-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin-bottom: 22px;
}
.market-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 220px;
  max-width: 300px;
}
.market-search svg {
  position: absolute;
  left: 11px;
  width: 14px;
  height: 14px;
  color: var(--text-dim);
  pointer-events: none;
}
.market-search input {
  width: 100%;
  padding: 8px 30px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
}
.market-search input:focus { outline: none; border-color: var(--accent); }
.market-search input::-webkit-search-cancel-button { display: none; }
.market-clear {
  position: absolute;
  right: 9px;
  width: 17px;
  height: 17px;
  border: 0;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
.market-clear:hover { color: var(--text); }

.market-filterbar { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.cards-filter.is-rar-common.is-active    { color: #9a9aa2; border-color: #9a9aa2; }
.cards-filter.is-rar-rare.is-active      { color: var(--success); border-color: var(--success); }
.cards-filter.is-rar-epic.is-active      { color: var(--neon-purple); border-color: var(--neon-purple); }
.cards-filter.is-rar-legendary.is-active { color: var(--accent); border-color: var(--accent); }

/* ---------- blocks ---------- */

.market-block { margin-bottom: 30px; }
.market-block h3 {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 12px;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.market-hint {
  font-size: 9px;
  letter-spacing: 0.03em;
  color: var(--text-dim);
  opacity: 0.65;
  text-transform: none;
}

/* ---------- THE listing tile ----------
   One component for FEATURED, BEST DEALS, ON SALE and the seller's own rows. Three copies
   of "a card for sale" drifted apart within a day the first time. */

.listing-shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
  gap: 12px;
}
.listing {
  --rar: var(--text-dim);
  --rar-soft: rgba(154,154,162,0.14);
  /* Declara o card como container para o @container do rodape mais abaixo: e a LARGURA
     DELE que decide se o preco cabe ao lado do botao, e a mesma tela tem cards largos
     (FEATURED) e estreitos (prateleira) ao mesmo tempo. */
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  overflow: hidden;
  transition: transform 0.16s var(--ease-smooth), border-color 0.16s var(--ease-smooth);
}
.listing:hover { transform: translateY(-2px); border-color: var(--rar); }
.listing.is-common    { --rar: #9a9aa2; --rar-soft: rgba(154,154,162,0.14); }
.listing.is-rare      { --rar: var(--success); --rar-soft: rgba(79,180,119,0.16); }
.listing.is-epic      { --rar: var(--neon-purple); --rar-soft: rgba(139,92,246,0.18); }
.listing.is-legendary { --rar: var(--accent); --rar-soft: rgba(233,161,59,0.20); }
.listing.is-promoted { border-color: var(--accent); }
/* Your own card, sitting in the public shelf. Marked, because the first thing somebody
   does otherwise is try to buy it. */
.listing.is-mine { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-glow); }
.listing-seller b { color: var(--accent); font-weight: 600; }

.listing-art {
  position: relative;
  aspect-ratio: 4 / 3;
  background: linear-gradient(180deg, var(--rar-soft), transparent), var(--surface-2);
}
.listing-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.listing-noart { display: block; width: 100%; height: 100%; }
.listing-rarity {
  position: absolute;
  left: 6px;
  bottom: 6px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(0,0,0,0.64);
  color: var(--rar);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.12em;
}
.listing-flag,
.listing-deal {
  position: absolute;
  top: 6px;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.1em;
}
.listing-flag { left: 6px; background: var(--accent); color: #17110a; }
.listing-deal { right: 6px; background: var(--success); color: #06180e; }

.listing-head { padding: 9px 10px 0; }
.listing-head h4 { margin: 0; font-size: 12px; line-height: 1.25; }
.listing-sub {
  display: block;
  margin-top: 2px;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.listing-stats { display: flex; flex-wrap: wrap; gap: 3px; padding: 6px 10px 0; }

/* Who is selling it. A marketplace where every card comes from nobody in particular reads
   as a vending machine, not a market. */
.listing-seller {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 7px 10px 0;
  font-size: 9px;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.listing-seller b { color: var(--accent); }
.seller-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--rar);
  flex: 0 0 auto;
}

.listing-ref {
  margin: 4px 0 0;
  padding: 0 10px;
  font-size: 9px;
  color: var(--text-dim);
}
.listing-ref b { color: var(--text); }

/* O RODAPE: preco a esquerda, botao a direita — e o botao NUNCA pode ser espremido.
   ===================================================================================
   O preco e o botao dividem uma linha flex de ~156px uteis num tile de 176px. Sem as
   tres regras abaixo eles disputam essa largura, e quem perde e o botao: ele e
   empurrado para fora e o `overflow: hidden` do .listing corta o que passou. Medido
   com a Orbitron carregada, num tile de 176px:

       115         -> sobram 11px depois do botao
       250.000     -> sobram 11px
       1.250.000   -> sobram  2px      <- a um digito de quebrar

   Ou seja: nao e "as vezes bugado", e uma margem que encolhe com o tamanho do preco e
   que ja esta no fim. Basta um preco maior, uma coluna mais estreita ou uma fonte que
   renderize um pouco mais larga.

   E o sintoma tem uma explicacao que confunde: a prateleira abre ordenada por CHEAPEST,
   entao ROLAR PARA BAIXO e VER PRECOS MAIORES sao a mesma coisa. Parece que o problema
   vem da quantidade de cartas ou do scroll; vem do numero de digitos. Trocar a ordenacao
   para PRICIEST faz o mesmo defeito aparecer na PRIMEIRA linha.

   A correcao decide QUEM CEDE: o botao e a acao e tem largura fixa; o preco e texto.
     flex no botao  — nunca encolhe abaixo do proprio rotulo: "BUY" inteiro, sempre.
     min-width no preco — passa a ceder o espaco que sobra (o padrao de um item flex e
                  se recusar a encolher abaixo do proprio conteudo, e e esse padrao que
                  empurrava o botao para fora).

   MAS CEDER NAO BASTA QUANDO NAO CABE, e foi aqui que a primeira tentativa errou.
   Medido, com a Orbitron, o que cada peca ocupa:

       botao 58 + gap 8 + padding 20 = 86px    ->  sobram (card - 86) para o preco
       "1.000.000" SO O NUMERO ................ 97px
       "1.000.000 $CAZH" ..................... 135px

   Num card de 176px (o minimo da grade) sobram 90px, e o numero sozinho precisa de 97.
   Nao cabe de jeito nenhum lado a lado — nem quebrando na linha. A primeira versao
   disto usava `overflow-wrap: anywhere` como rede, e a rede virou o problema: o preco
   passou a quebrar DENTRO do numero e dentro da palavra ("69" / "0", "$CAZ" / "H").
   Um preco partido ao meio e pior que um botao cortado.

   EMPILHAR e o que resolve, porque muda a conta: sem o botao ao lado o preco recebe
   (card - 20) = 156px num card de 176, e "1.000.000 $CAZH" inteiro cabe em UMA linha.
   O botao vai para baixo em largura total, que de quebra e um alvo de toque maior.

   O gatilho e a largura do CARD, nao a da tela — a mesma tela tem cards largos no
   FEATURED e estreitos na prateleira — entao e container query, nao media query. O
   corte em 200px vem da medicao: acima disso sobram >=114px para o preco, e o pior
   caso realista (o teto de 1.000.000 do maxListingPrice) pede 97.

   NAO troque isto por flex-wrap: testado, ele corrige o corte mas manda o botao para
   uma segunda linha em quase todo card (o preco pede max-content antes de aceitar
   quebrar), mudando a prateleira inteira para resolver o caso estreito. */
.listing-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: auto;
  padding: 10px;
}
.listing-foot > .listing-price { min-width: 0; }
.listing-foot > .mkt-btn { flex: 0 0 auto; }

@container (max-width: 200px) {
  .listing-foot {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .listing-foot > .mkt-btn { width: 100%; }
}
/* Two buttons do not fit beside a price on a 176px tile — CANCEL was rendering past the
   card's own border. They get their own row and split it evenly instead of each demanding
   its natural width. */
.listing-foot.is-split {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.listing-actions { display: flex; gap: 6px; }
.listing-actions .mkt-btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 6px 2px;
  font-size: 9px;
  letter-spacing: 0.08em;
  text-align: center;
}
/* An explicit class rather than :has() — layout that silently collapses on a browser
   without :has() is not worth the cleverness. */
.listing-foot.is-stacked {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.listing-price { font-size: 9px; letter-spacing: 0.08em; color: var(--text-dim); }
.listing-price b {
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--accent);
  margin-right: 3px;
}

/* ---------- ONE button, everywhere money is involved ----------
   BUY, CONFIRM, PROMOTE and CANCEL were four different shapes across three files. They are
   one now, and the variant only changes the colour. */

.mkt-btn {
  padding: 6px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.mkt-btn:hover:not(:disabled) { color: var(--text); border-color: var(--text-dim); }
.mkt-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.mkt-btn.is-buy { border-color: var(--accent); background: var(--accent); color: #17110a; }
.mkt-btn.is-buy:hover:not(:disabled) { filter: brightness(1.08); color: #17110a; }
.mkt-btn.is-ghost:hover:not(:disabled) { color: var(--danger); border-color: var(--danger); }
/* A single action that has to say more than one word — "CANCEL LISTING" on the seller's
   own tile in the shelf. It takes the whole row rather than being truncated. */
.mkt-btn.is-wide {
  width: 100%;
  padding: 6px 6px;
  font-size: 9px;
}
.mkt-btn.is-flagged {
  border-color: var(--accent);
  color: var(--accent);
  cursor: default;
}

/* ---------- SELLING ---------- */

.selling-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.sell-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 22px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--accent);
  color: #17110a;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.14em;
  cursor: pointer;
  transition: filter 0.15s;
}
.sell-cta:hover:not(:disabled) { filter: brightness(1.08); }
.sell-cta:disabled { opacity: 0.4; cursor: not-allowed; }
.sell-cta svg { width: 14px; height: 14px; }

.selling-stats { display: flex; flex-wrap: wrap; gap: 18px; }
.selling-stats span { font-size: 10px; letter-spacing: 0.08em; color: var(--text-dim); }
.selling-stats b { font-family: var(--font-display); font-size: 14px; color: var(--accent); }

/* ---------- ACTIVITY ---------- */

.activity-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}
.activity-table th {
  padding: 0 10px 8px;
  border-bottom: 1px solid var(--border);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--text-dim);
  text-align: left;
}
.activity-table td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
}
.activity-table tbody tr { --rar: var(--text-dim); }
.activity-table tbody tr.is-common    { --rar: #9a9aa2; }
.activity-table tbody tr.is-rare      { --rar: var(--success); }
.activity-table tbody tr.is-epic      { --rar: var(--neon-purple); }
.activity-table tbody tr.is-legendary { --rar: var(--accent); }
.activity-table td:first-child { color: var(--text); }
.activity-table td em {
  margin-left: 4px;
  font-style: normal;
  font-size: 9px;
  color: var(--text-dim);
}
.activity-table .is-num {
  text-align: right;
  font-family: var(--font-display);
  color: var(--accent);
}
@media (max-width: 700px) {
  /* The two columns that are context rather than content. */
  .activity-table th:nth-child(2), .activity-table td:nth-child(2),
  .activity-table th:nth-child(4), .activity-table td:nth-child(4) { display: none; }
}

/* ---------- sold list (SELLING view) ---------- */

.sale-list { list-style: none; margin: 0; padding: 0; }
.sale-row {
  --rar: var(--border-strong);
  display: grid;
  grid-template-columns: 6px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 2px;
  border-bottom: 1px solid var(--border);
}
.sale-row:last-child { border-bottom: 0; }
.sale-row.is-common    { --rar: #9a9aa2; }
.sale-row.is-rare      { --rar: var(--success); }
.sale-row.is-epic      { --rar: var(--neon-purple); }
.sale-row.is-legendary { --rar: var(--accent); }
.sale-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--rar);
  box-shadow: 0 0 6px -1px var(--rar);
}
.sale-name { font-size: 11px; line-height: 1.2; }
.sale-name em {
  display: block;
  font-size: 8px;
  font-style: normal;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.sale-price { font-family: var(--font-display); font-size: 12px; color: var(--success); }

/* ---------- dialogs ---------- */

.sell-dialog.is-open {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 165;
  align-items: center;
  justify-content: center;
  animation: stage-in 0.18s var(--ease-smooth);
}
.sell-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 6, 9, 0.84);
  backdrop-filter: blur(5px);
}
.sell-box {
  position: relative;
  z-index: 2;
  width: min(92vw, 400px);
  padding: 18px;
  border: 1px solid var(--border-strong);
  border-radius: 16px;
  background: var(--surface);
  box-shadow: 0 30px 70px -20px rgba(0,0,0,0.8);
}
.sell-box.is-wide { width: min(94vw, 700px); max-height: 86vh; display: flex; flex-direction: column; }

/* The card at the top of every confirmation — one component, so a summary cannot look like
   a different product from the tile it was opened from. */
.summary-card {
  --rar: var(--border-strong);
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 14px;
  padding: 10px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--rar);
  border-radius: 11px;
  background: var(--bg-deep);
}
.summary-card.is-common    { --rar: #9a9aa2; }
.summary-card.is-rare      { --rar: var(--success); }
.summary-card.is-epic      { --rar: var(--neon-purple); }
.summary-card.is-legendary { --rar: var(--accent); }
.summary-card img,
.summary-card .listing-noart {
  width: 78px;
  height: 58px;
  border-radius: 7px;
  object-fit: cover;
  background: var(--surface-2);
  flex: 0 0 auto;
}
.summary-card b { display: block; font-size: 13px; }
.summary-card span { display: block; font-size: 9px; letter-spacing: 0.08em; color: var(--text-dim); }
.summary-stats { display: flex !important; flex-wrap: wrap; gap: 3px; margin-top: 5px; }

/* The numbers, written out. */
.summary { margin: 0 0 12px; }
.summary > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 5px 0;
  font-size: 11px;
}
.summary dt { color: var(--text-dim); margin: 0; }
.summary dd { margin: 0; color: var(--text); }
.summary dd.is-out { color: var(--danger); }
.summary .is-total {
  margin-top: 4px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
}
.summary .is-total dt { color: var(--text); }
.summary .is-total dd {
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--accent);
}
.summary .is-total dd.is-short { color: var(--danger); }
.summary-note {
  margin: 0 0 14px;
  font-size: 9px;
  line-height: 1.6;
  color: var(--text-dim);
  opacity: 0.85;
}

.sell-warn {
  margin: 0 0 12px;
  padding: 8px 10px;
  border: 1px solid rgba(199, 68, 54, 0.5);
  border-radius: 9px;
  font-size: 10px;
  line-height: 1.5;
  color: var(--text-dim);
}
.sell-warn b { color: var(--danger); }

.sell-price { display: block; margin-bottom: 8px; }
.sell-price span {
  display: block;
  margin-bottom: 4px;
  font-size: 9px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.sell-price input {
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-deep);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 16px;
}
.sell-price input:focus { outline: none; border-color: var(--accent); }
.sell-quote { margin: 0 0 14px; font-size: 10px; line-height: 1.6; color: var(--text-dim); }
.sell-quote b { color: var(--text); }
.sell-quote .sell-net { color: var(--accent); font-size: 12px; }

.sell-actions { display: flex; gap: 8px; justify-content: flex-end; }
.sell-listprice { display: block; margin-top: 2px; font-size: 10px; color: var(--accent); }

.promote-copy { margin: 0 0 8px; font-size: 11px; line-height: 1.6; color: var(--text-dim); }
.promote-copy b { color: var(--accent); }
.promote-slots {
  margin: 0 0 10px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
.promote-slots.is-full { border-color: var(--danger); color: var(--danger); }
.promote-fine { margin: 0 0 14px; font-size: 9px; line-height: 1.6; color: var(--text-dim); opacity: 0.85; }

/* ---------- the picker ---------- */

.picker-filters { margin-bottom: 12px; }
.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px;
  overflow-y: auto;
  padding-right: 4px;
  min-height: 0;
  /* AS DUAS LINHAS ABAIXO SAO O QUE IMPEDE A GRADE DE ESMAGAR AS CARTAS.
     Sem elas o seletor funciona com pouca carta e QUEBRA com muita, que e a pior forma
     de um bug aparecer: passa em todo teste manual de quem tem 10 cartas e chega ao
     holder que tem 500.

     O mecanismo, medido no navegador com o CSS real:
       .picker-grid e um item flex dentro de .sell-box.is-wide, que e uma coluna com
       max-height:86vh. Com 500 cartas a altura natural da grade passa de 22.000px, o
       flex a encolhe para os ~683px da caixa, e a altura passa a ser DEFINIDA. Ai as
       linhas implicitas (`auto`) com align-content `normal` deixam de ser do tamanho do
       conteudo e passam a dividir essa altura entre si. E como .picker-card tem
       overflow:hidden, a carta nao protesta: ela simplesmente e cortada.
       Medido: com 8 cartas o tile tem 172px; com 500, 9px. Sobrava uma tira da arte, e
       o usuario concluia — com razao — que estava vendo um bug.

     max-content faz cada linha valer o que a carta precisa; start impede a distribuicao.
     A grade volta a rolar, que e o que ela deveria fazer desde o inicio.

     Isto ja existia dentro do @media (max-width:700px) e so ali, entao o celular estava
     certo e o desktop errado. Vive aqui agora: e uma regra do componente, nao do
     tamanho da tela. */
  grid-auto-rows: max-content;
  align-content: start;
}
.picker-card {
  --rar: var(--border-strong);
  display: flex;
  flex-direction: column;
  padding-bottom: 7px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--rar);
  border-radius: 10px;
  background: var(--surface-2);
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.15s var(--ease-smooth), border-color 0.15s;
}
.picker-card:hover { transform: translateY(-2px); border-color: var(--accent); }
.picker-card.is-common    { --rar: #9a9aa2; }
.picker-card.is-rare      { --rar: var(--success); }
.picker-card.is-epic      { --rar: var(--neon-purple); }
.picker-card.is-legendary { --rar: var(--accent); }
.picker-art { position: relative; aspect-ratio: 4 / 3; background: var(--bg-deep); }
.picker-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.picker-art > span:not(.listing-rarity):not(.picker-fitted) { display: block; width: 100%; height: 100%; }
.picker-fitted {
  position: absolute;
  top: 5px;
  right: 5px;
  padding: 1px 5px;
  border-radius: 999px;
  background: rgba(0,0,0,0.7);
  color: var(--accent);
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.picker-card b { padding: 6px 8px 0; font-size: 11px; line-height: 1.2; }
.picker-slot { padding: 0 8px; font-size: 8px; letter-spacing: 0.08em; color: var(--text-dim); }
.picker-card .card-stats { padding: 4px 8px 0; }

/* ---------- gifting ---------- */

.sell-cta.is-gift {
  background: transparent;
  color: var(--accent);
}
.sell-cta.is-gift:hover:not(:disabled) { background: var(--accent); color: #17110a; filter: none; }

/* ---------- selection mode ----------
   Cancelling one listing at a time cost a request each and walked into the rate limiter.
   Picking several and removing them in one call is the fix; this is its UI. */

.mkt-btn.is-tiny { padding: 3px 10px; font-size: 9px; letter-spacing: 0.1em; }
.market-block h3 .mkt-btn.is-tiny { margin-left: auto; }

.select-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  padding: 9px 12px;
  border: 1px solid var(--accent-glow);
  border-radius: 10px;
  background: linear-gradient(90deg, rgba(233,161,59,0.08), transparent);
}
.select-count {
  margin-right: auto;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
}

.listing.is-selectable { cursor: pointer; }
.listing.is-picked {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-glow);
}
.select-tick {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: rgba(6,6,9,0.78);
  color: transparent;
  font-size: 12px;
  font-weight: 700;
}
.select-tick.is-on {
  border-color: var(--accent);
  background: var(--accent);
  color: #17110a;
}

/* ---------- bulk confirmation list ---------- */

.bulk-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  max-height: 190px;
  overflow-y: auto;
}
.bulk-list li {
  --rar: var(--border-strong);
  display: grid;
  grid-template-columns: 6px 1fr auto;
  align-items: center;
  gap: 9px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
}
.bulk-list li:last-child { border-bottom: 0; }
.bulk-list li.is-common    { --rar: #9a9aa2; }
.bulk-list li.is-rare      { --rar: var(--success); }
.bulk-list li.is-epic      { --rar: var(--neon-purple); }
.bulk-list li.is-legendary { --rar: var(--accent); }
.bulk-list em { font-style: normal; font-size: 9px; color: var(--text-dim); }
.bulk-list b { font-family: var(--font-display); color: var(--accent); }

/* A stack when the second action is an alternative rather than a cancel — "remove several"
   is not a lesser version of "remove this one", so it does not sit beside it as a ghost. */
.sell-actions.is-stack { flex-direction: column; }
.sell-actions.is-stack .mkt-btn { width: 100%; }

/* ==========================================================================
   MOBILE — MARKET
   ==========================================================================
   A barra de abas, o saldo e os chips de filtro sao corrigidos em cards.css, que
   e onde essas classes nascem e de onde as duas paginas as herdam. Aqui fica so o
   que e do mercado.

   O problema de layout: .listing-shelf pede colunas de no minimo 176px, e a 375px
   sobram ~343px de largura util — 2x176+12 = 364, entao a prateleira caia para UMA
   coluna e cada anuncio virava um card de ~450px. Um anuncio por tela, num lugar
   cujo trabalho e deixar comparar precos. Baixar o minimo devolve as duas colunas
   e ainda cai sozinho para uma coluna abaixo de ~330px, onde duas realmente nao
   cabem.                                                                       */

@media (max-width: 700px) {
  /* Mesma armadilha do min-width:auto que a faixa de filtros tem em cards.css: a
     barra crescia para caber o conteudo e vazava para fora da tela. */
  .market-filterbar { min-width: 0; max-width: 100%; }

  .listing-shelf {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
  }

  /* Duas colunas significam ~150px por card: a arte 4/3 tomava 112px so dela, e
     tudo abaixo dela ficava apertado. 16/9 devolve essa altura para o conteudo. */
  .listing-art { aspect-ratio: 16 / 9; }
  .listing-head h4 { font-size: 12px; line-height: 1.25; }
  .listing-sub, .listing-seller, .listing-rarity { font-size: 10px; }
  .listing-price b { font-size: 15px; }

  /* O rodape do card empilha: preco e botao lado a lado a 150px sobram 60px para
     o botao, que e menos do que um dedo. */
  .listing-foot {
    flex-direction: column;
    align-items: stretch;
    gap: 7px;
  }
  .listing-foot .mkt-btn { width: 100%; min-height: 40px; }
  .listing-price { text-align: center; }

  /* Caixas de dialogo (vender, presentear, promover, remover em lote) coladas no
     rodape em vez de centralizadas — e onde o polegar alcanca, e evita que uma
     caixa alta demais fique com o botao de confirmar fora da tela. */
  .sell-dialog.is-open { align-items: flex-end; }
  .sell-box {
    width: 100%;
    max-height: 88vh;
    overflow-y: auto;
    border-radius: 16px 16px 0 0;
    padding: 16px 14px calc(16px + env(safe-area-inset-bottom));
  }
  .sell-box.is-wide { width: 100%; }
  .sell-actions { flex-direction: column-reverse; }
  .sell-actions .mkt-btn { width: 100%; min-height: 44px; }
  /* A FAIXA DE FILTROS DENTRO DO DIALOGO.
     Regressao que EU causei no passe anterior: ao virar uma faixa que rola na
     horizontal, ela ganhou `overflow-x: auto`, e o CSS entao promove o outro eixo de
     `visible` para `auto` — a faixa passou a cortar na VERTICAL tambem. Dentro do
     dialogo ela e um item flex numa coluna de altura limitada, com flex-shrink:1
     padrao, entao a grade de cartas a espremia de 36px para 22px e os chips de 34px
     ficavam cortados pela metade: sobrava uma tira de ALL/CHASSIS/ENGINE ilegivel.
     Na pagina isso nao acontecia, porque la a faixa nao vive dentro de uma coluna
     com altura definida. Nao encolher e a correcao inteira. */
  .picker-filters { flex: 0 0 auto; }

  /* O SELETOR DE CARTAS: so as colunas mais estreitas.
     O `grid-auto-rows: max-content` + `align-content: start` que moravam aqui subiram
     para a regra base de .picker-grid — eles nunca foram uma correcao de celular, e
     deixa-los so aqui era o motivo de o desktop continuar esmagando as cartas. A
     explicacao inteira do mecanismo esta la em cima, junto das duas linhas. */
  .picker-grid {
    grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  }

  /* A busca e o unico campo digitavel da pagina: 16px impede o zoom automatico do
     Safari ao focar, que desalinha a pagina inteira e nao volta sozinho. */
  .market-search input { font-size: 16px; min-height: 44px; }
}

/* ==========================================================================
   A TROCA DE CATEGORIA NO SELETOR DE CARTAS
   ==========================================================================
   Clicar de CHASSIS para ENGINE fazia a tela PISCAR: o handler chamava
   renderMarketDialogs(), que reescreve o innerHTML da camada inteira de dialogos, e
   com isso a caixa era destruida e recriada — re-executando o `stage-in` de ABERTURA
   do dialogo a cada clique num filtro. Isso agora e um repinte so da grade
   (repaintPickerPool em market.js), entao nao ha mais animacao de abertura repetindo.

   O que sobra e o que a troca deveria ter tido desde o inicio: as cartas novas
   entrando. Curta de proposito — 160ms com um escalonamento minimo. Uma cascata longa
   num seletor e bonita na primeira vez e cansativa na decima, e quem esta filtrando
   quer VER o resultado, nao assistir a ele chegar.                             */

.picker-grid > .picker-card {
  animation: picker-card-in 0.16s var(--ease-smooth) both;
}
/* O escalonamento para na oitava carta: depois disso ja esta fora da area visivel na
   maioria das telas, e atrasar o que ninguem ve so adia o fim da animacao. */
.picker-grid > .picker-card:nth-child(2)  { animation-delay: 0.02s; }
.picker-grid > .picker-card:nth-child(3)  { animation-delay: 0.04s; }
.picker-grid > .picker-card:nth-child(4)  { animation-delay: 0.06s; }
.picker-grid > .picker-card:nth-child(5)  { animation-delay: 0.08s; }
.picker-grid > .picker-card:nth-child(6)  { animation-delay: 0.10s; }
.picker-grid > .picker-card:nth-child(7)  { animation-delay: 0.12s; }
.picker-grid > .picker-card:nth-child(n+8) { animation-delay: 0.14s; }

@keyframes picker-card-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* A frase que substitui a grade quando o slot esta vazio entra do mesmo jeito, senao
   filtrar para uma categoria vazia e a unica transicao que continua sendo um corte. */
.sell-box .cards-empty { animation: picker-card-in 0.16s var(--ease-smooth) both; }

@media (prefers-reduced-motion: reduce) {
  .picker-grid > .picker-card,
  .sell-box .cards-empty { animation: none; }
}
