/* ---------- Design tokens ----------
   Preset "flash" fechado via sandbox em /design. Um único tema agora.

   Princípios:
     - 1 fonte (Nunito) em vários pesos
     - 1 stroke (--ww-line-width) em todas as bordas
     - 2 radius: --ww-radius pra painéis, --ww-card-radius pra cards do mundo
     - 1 sombra chapada preta deslocada (--ww-shadow)
     - paleta compacta: canvas, raised, sunken, line, accent, 2 de texto
*/
:root {
  /* Fonte — stack com fallback de emoji sempre presente pra emoji render. */
  --ww-font-body: 'Nunito', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', system-ui, sans-serif;
  --ww-font-display: 'Nunito', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', system-ui, sans-serif;

  /* Superfície */
  --ww-stage-bg: #3fbfa8;           /* palco teal chapado */
  --ww-surface-raised: #eafaf5;     /* painéis, modais, tooltip */
  --ww-surface-sunken: #2fa38c;     /* áreas "dentro" (inputs, tracks) */

  /* Linha */
  --ww-line: #111;
  --ww-line-width: 3px;

  /* Acento */
  --ww-accent: #f2811d;
  --ww-accent-dim: #c05f08;

  /* Texto */
  --ww-text-primary: #111;
  --ww-text-muted: #3f5f57;

  /* Geometria */
  --ww-radius: 8px;
  --ww-card-radius: 6px;
  --ww-shadow: 0 4px 0 var(--ww-line);

}

/* Palco é desenhado pelo Phaser (TileSprite no worldLayer — responde a
   pan/zoom como mesa). Body fica neutro; stage-bg é fallback visual pra
   qualquer fração de segundo antes do canvas ligar. */
body { background: var(--ww-stage-bg); }
#game canvas { background: transparent; }


/* ═══════════════════════════════════════════════════════════════════════
   PRIMITIVAS FLASH
   ───────────────────────────────────────────────────────────────────────
   Tudo no jogo deve compor estas classes ao invés de estilar do zero.
   Blocos novos (store modal, menu, pause, gameover, confirm) usam estas.
   Blocos legados (.ww-hud__*, .ww-store-modal__*) devem ser migrados pra cá.

   Regras de uso:
     - 1 painel = 1 .ww-panel (nunca reinventar fundo+border+radius+shadow)
     - 1 botão = 1 .ww-button (nunca <button> sem classe, nunca filter/gradient)
     - 1 input = 1 .ww-input (nunca <input> estilo sistema)
     - Tipografia = 1 de (.ww-heading | .ww-label | .ww-body)
     - Estado "quente" = modificador --accent, não chrome adicional
═══════════════════════════════════════════════════════════════════════ */

/* --- Painel: geometria base (carta, card, modal, HUD painel). --- */
.ww-panel {
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  color: var(--ww-text-primary);
  padding: 12px 14px;
}
.ww-panel--accent {
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
}
.ww-panel--sunken {
  background: var(--ww-surface-sunken);
  box-shadow: none;
}
.ww-panel--flush { padding: 0; }

/* --- Botão: pressable com sombra chapada. Hover sobe, active afunda.
       Nunca usar filter/gradient. Estados via modificador. --- */
.ww-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--ww-font-body);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.3px;
  color: var(--ww-text-primary);
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 8px 16px;
  cursor: pointer;
  user-select: none;
  /* Só transform e box-shadow chapada — zero filter, zero repaint pesado. */
  transition: transform 0.08s ease, box-shadow 0.08s ease, background-color 0.1s linear, color 0.1s linear;
}
.ww-button:hover:not(:disabled) {
  transform: translate(-1px, -1px);
  box-shadow: 0 6px 0 var(--ww-line);
}
.ww-button:active:not(:disabled) {
  transform: translate(0, 2px);
  box-shadow: 0 2px 0 var(--ww-line);
}
.ww-button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.ww-button--primary,
.ww-button.is-active {
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
}
.ww-button--ghost {
  background: transparent;
  box-shadow: none;
}
.ww-button--ghost:hover:not(:disabled) {
  background: var(--ww-surface-raised);
  box-shadow: var(--ww-shadow);
}
.ww-button--small {
  font-size: 12px;
  padding: 6px 12px;
}
.ww-button--icon {
  width: 36px;
  height: 36px;
  padding: 0;
}

/* --- Input: text input com a mesma geometria do painel sunken. --- */
.ww-input {
  font-family: var(--ww-font-body);
  font-size: 14px;
  font-weight: 700;
  color: var(--ww-text-primary);
  background: var(--ww-surface-sunken);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  padding: 8px 12px;
  outline: none;
}
.ww-input::placeholder { color: var(--ww-text-muted); opacity: 0.7; }
.ww-input:focus { background: var(--ww-surface-raised); }

/* --- Tipografia: 3 níveis, Nunito, pesos firmes. --- */
.ww-heading {
  font-family: var(--ww-font-display);
  font-size: 24px;
  font-weight: 900;
  line-height: 1.1;
  color: var(--ww-text-primary);
  letter-spacing: -0.3px;
}
.ww-heading--hero { font-size: 40px; }
.ww-heading--small { font-size: 18px; }

.ww-label {
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ww-text-muted);
  line-height: 1;
}

.ww-body {
  font-family: var(--ww-font-body);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ww-text-primary);
}
.ww-body--muted { color: var(--ww-text-muted); }

/* --- Badge: sticker pequeno (tag, price, variant). --- */
.ww-badge {
  display: inline-block;
  font-family: var(--ww-font-body);
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 2px 8px;
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: calc(var(--ww-radius) - 4px);
  background: var(--ww-surface-raised);
  color: var(--ww-text-primary);
  line-height: 1.4;
}
.ww-badge--accent { background: var(--ww-accent); color: var(--ww-surface-raised); }

/* --- Divisor horizontal com o stroke preto. --- */
.ww-divider {
  border: none;
  border-top: var(--ww-line-width) solid var(--ww-line);
  margin: 0;
}

/* --- Select custom — NUNCA usar <select> nativo. Trigger é .ww-button. --- */
.ww-select {
  position: relative;
  display: inline-flex;
  flex: 1;
}
.ww-select__trigger {
  flex: 1;
  justify-content: space-between;
  gap: 8px;
  font-weight: 700;
}
.ww-select__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ww-select__caret {
  font-size: 10px;
  opacity: 0.7;
  transition: transform 0.15s ease;
}
.ww-select.is-open .ww-select__caret { transform: rotate(180deg); }
.ww-select__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  max-height: 240px;
  padding: 4px;
  display: none;
  flex-direction: column;
  gap: 2px;
  z-index: 60;
}
.ww-select.is-open .ww-select__menu { display: flex; }
.ww-select__item {
  background: transparent;
  border: none;
  color: var(--ww-text-primary);
  font-family: var(--ww-font-body);
  font-size: 13px;
  font-weight: 700;
  text-align: left;
  padding: 6px 10px;
  cursor: pointer;
  border-radius: calc(var(--ww-radius) - 4px);
}
.ww-select__item:hover { background: var(--ww-surface-sunken); }
.ww-select__item.is-active {
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
}

/* --- Scrollbar custom (regra global: zero scrollbar do sistema). --- */
.ww-scroll { overflow: auto; scrollbar-gutter: stable; }
.ww-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
.ww-scroll::-webkit-scrollbar-track {
  background: var(--ww-surface-sunken);
  border-radius: var(--ww-radius);
}
.ww-scroll::-webkit-scrollbar-thumb {
  background: var(--ww-line);
  border-radius: var(--ww-radius);
  border: 2px solid var(--ww-surface-sunken);
}


/* ═══════════════════════════════════════════════════════════════════════
   Atalho legado: .ww-btn ainda é referenciado em blocos antigos.
   Aponta pra .ww-button. Remover depois da migração total.
═══════════════════════════════════════════════════════════════════════ */
.ww-btn {
  font-family: var(--ww-font-body);
  font-size: 14px;
  font-weight: 800;
  color: var(--ww-text-primary);
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 8px 16px;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.08s ease, background-color 0.1s linear, color 0.1s linear;
}
.ww-btn:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: 0 6px 0 var(--ww-line); }
.ww-btn:active:not(:disabled) { transform: translate(0, 2px); box-shadow: 0 2px 0 var(--ww-line); }
.ww-btn.active { background: var(--ww-accent); color: var(--ww-surface-raised); }

/* ---------- Scrollbar custom global ----------
   REGRA: nenhum elemento do projeto pode usar scrollbar padrão do sistema.
   Todo container com overflow deve ter a classe `ww-scroll` OU seu próprio
   ::-webkit-scrollbar definido. Scroll nativo é proibido por padrão visual.
   Veja: memory/feedback_no_system_scroll.md */
.ww-scroll {
  scrollbar-width: thin;                 /* Firefox */
  scrollbar-color: #3a2a1c transparent;  /* Firefox: thumb track */
}
.ww-scroll::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.ww-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.ww-scroll::-webkit-scrollbar-thumb {
  background: #3a2a1c;
  border-radius: 4px;
}
.ww-scroll::-webkit-scrollbar-thumb:hover {
  background: #5a4228;
}
.ww-scroll::-webkit-scrollbar-corner {
  background: transparent;
}

#card-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  font-family: var(--ww-font-body);
  z-index: 10;
}

#card-overlay__world {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  will-change: transform;
}

/*
 * Carta = 2 níveis:
 *   .ww-card        → posição no mundo + sombra fixa no chão (não sobe com o pulo).
 *   .ww-card__inner → visual da carta; recebe o transform do ciclo de passo
 *                     (squash/stretch/pulo) sem afetar a sombra.
 */
.ww-card {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: center center;
  user-select: none;
  will-change: transform;
}
.ww-card::after {
  /* Sem sombra radial no piso — o preset flash não usa sombra difusa.
     A sombra da carta vem do box-shadow chapado no __inner. Mantemos
     o ::after como pseudo vazio pra não quebrar regras de step/drag. */
  content: '';
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: -6px;
  height: 10px;
  background: transparent;
  z-index: -1;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.ww-card__inner {
  position: absolute;
  inset: 0;
  border-radius: var(--ww-card-radius);
  /* Sombra chapada preta pra baixo (look flash-era). */
  box-shadow: 0 4px 0 var(--ww-line);
  border: var(--ww-line-width) solid var(--ww-line);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 6px;
  box-sizing: border-box;
  color: var(--ww-text-primary);
  overflow: hidden;
  transform-origin: center bottom;
  will-change: transform;
  transition: box-shadow 0.12s ease, background 0.2s ease;
  /* Cor da carta vem por --ww-card-color inline (CardDOMRenderer). Fundo
     default é chapado; a variante `.ww-card__inner--battery` sobrescreve
     com gradient que visualiza bateria. */
  background: var(--ww-card-color, #888);
}

/* Cartas com bateria: o fundo VIRA o indicador de energia.
   - pct = 1  → carta totalmente colorida (cor do tipo).
   - pct = 0  → carta totalmente cinza "descarregada".
   - parcial → cinza em cima, cor embaixo, com corte duro (não blend) em
     pct*100% de baixo. Parece uma barra vertical ocupando a carta inteira.
   --ww-battery-pct é setada inline pelo renderer. --ww-card-empty é a
     cor "desligada" — cinza médio, neutro. */
.ww-card__inner--battery {
  --ww-card-empty: #9a958c;
  background: linear-gradient(
    to top,
    var(--ww-card-color, #888) 0%,
    var(--ww-card-color, #888) calc(var(--ww-battery-pct, 1) * 100%),
    var(--ww-card-empty) calc(var(--ww-battery-pct, 1) * 100%),
    var(--ww-card-empty) 100%
  );
}

/* Aura decorativa pra cartas imóveis. Sempre presente no DOM (como irmã
   do __inner), mas só pinta quando a carta tem .ww-card--immovable. Mesma
   forma da carta + margem extra em volta, preenchida com a cor da carta
   em opacidade baixa. A tag "immovable" fica no topo, colada na borda
   superior da aura. Zero pointer-events — nunca atrapalha click/drag. */
.ww-card__aura {
  display: none;
  position: absolute;
  inset: calc(-1 * var(--ww-aura-inset, 10px));
  border-radius: calc(var(--ww-card-radius) + var(--ww-aura-inset, 10px));
  background: var(--ww-card-color, #888);
  opacity: 0.35;
  pointer-events: none;
  z-index: -1;
}
.ww-card--immovable .ww-card__aura {
  display: block;
}
/* Tags da aura — badges pequenos contornados, empilhados lado a lado
   logo acima da carta (fora do bounds visual dela, dentro da faixa que
   a aura criou com inset negativo). Convenção extensível: no futuro
   outras tags (ex: "static", "fragile") entram como irmãs e se alinham
   horizontalmente via flex. Sempre pointer-events:none. */
.ww-card__aura-tags {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  gap: 4px;
  pointer-events: none;
}
.ww-card__aura-label {
  font-family: var(--ww-font-body);
  font-size: 7px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--ww-text-primary);
  background: var(--ww-surface-raised);
  border: 1.5px solid var(--ww-line);
  border-radius: 3px;
  padding: 1px 5px;
  white-space: nowrap;
  line-height: 1.2;
}

/* Blur de cartas imóveis — FIX real.
   Causa: o pai `#card-overlay__world` leva `scale(zoom)` fracionário. Cartas
   "vivas" tinham `animation` no inner (ww-idle-breath) que força camada GPU e
   re-rasterização a cada frame, ficando nítidas. Cartas imóveis não tinham
   nada no inner — o browser rasterizava o conteúdo no tamanho natural e
   ESCALAVA O BITMAP, deixando texto/sprite borrados.
   Fix: aplicamos uma animation permanente e invisível (scale 1→1) só pra
   forçar camada GPU. Em cartas alive o `:not(.ww-card--alive)` desabilita
   esta (pra não competir com idle-breath). */
.ww-card:not(.ww-card--alive) .ww-card__inner {
  animation: ww-card-static-layer 10s linear infinite;
}
@keyframes ww-card-static-layer {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.0001); }
}

.ww-card.dragging .ww-card__inner {
  /* Drag: sombra chapada fica mais pronunciada pra dar lift visual. */
  box-shadow: 0 10px 0 var(--ww-line);
}
.ww-card.dragging::after {
  opacity: 0;
}

.ww-card--immovable .ww-card__inner {
  /* Borda dashed (não sólida) sinaliza "imóvel". Mantém largura do preset. */
  border: var(--ww-line-width) dashed var(--ww-line);
  cursor: pointer;
}
.ww-card--clickable { cursor: pointer; }

/* Unplaced = ainda não colocada (comprada). Diferenciação via cor accent (em vez
   de pulse de shadow animado — antipadrão). Pulso sutil de scale composited. */
.ww-card--unplaced .ww-card__inner {
  border-color: var(--ww-accent);
  animation: ww-unplaced-pulse 1.2s ease-in-out infinite;
}
@keyframes ww-unplaced-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* Ciclo de passo — aplicado no inner, sombra permanece no chão.
   Skew + squash + micropulo em 360ms. Carta vai pra direita por padrão;
   a classe `.ww-card--stepping-left` espelha horizontalmente o skew.
   `transform-origin: center bottom` pro squash/stretch "pousar" no chão. */
.ww-card--stepping .ww-card__inner {
  animation: ww-step 360ms ease-in-out infinite;
}
.ww-card--stepping.ww-card--stepping-left .ww-card__inner {
  animation-name: ww-step-left;
}
@keyframes ww-step {
  0%   { transform: skewX(0deg) scaleX(1) scaleY(1) translateY(0); }
  22%  { transform: skewX(6deg)  scaleX(1.06) scaleY(0.92) translateY(0); }
  55%  { transform: skewX(-8deg) scaleX(0.94) scaleY(1.08) translateY(-8px); }
  85%  { transform: skewX(0deg)  scaleX(1)    scaleY(1)    translateY(0); }
  100% { transform: skewX(0deg)  scaleX(1)    scaleY(1)    translateY(0); }
}
@keyframes ww-step-left {
  0%   { transform: skewX(0deg)  scaleX(1) scaleY(1) translateY(0); }
  22%  { transform: skewX(-6deg) scaleX(1.06) scaleY(0.92) translateY(0); }
  55%  { transform: skewX(8deg)  scaleX(0.94) scaleY(1.08) translateY(-8px); }
  85%  { transform: skewX(0deg)  scaleX(1)    scaleY(1)    translateY(0); }
  100% { transform: skewX(0deg)  scaleX(1)    scaleY(1)    translateY(0); }
}
/* A sombra reage ao pulo: afina e escurece menos no pico da animação.
   Não sobe — fica no chão. */
.ww-card--stepping::after {
  animation: ww-step-shadow 360ms ease-in-out infinite;
}
@keyframes ww-step-shadow {
  0%, 100% { opacity: 1;   transform: scale(1); }
  55%      { opacity: 0.6; transform: scale(0.85); }
}

/* Respiração sutil pra cartas "vivas" que não estão andando e não são estáticas.
   Idle sai de cena assim que o step-cycle entra (step override via cascade).
   Cartas em deck não respiram — a pilha inteira ficava oscilando fora de
   fase, quebrando a leitura de "é um conjunto agora". */
.ww-card--alive:not(.ww-card--stepping):not(.dragging):not(.ww-card--in-deck) .ww-card__inner {
  animation: ww-idle-breath 1.8s ease-in-out infinite;
}
@keyframes ww-idle-breath {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.015); }
}

/* Decay aplica scale adicional no inner. Sobrescreve o transform da idle/step
   com !important porque essas vêm de animation. Como decay é terminal
   (carta vai morrer), perder a anim é aceitável. */
.ww-card--decaying .ww-card__inner {
  animation: none;
  transform: scale(var(--decay-scale, 1));
}

/* ---------- Dev panel ---------- */
/* ═══════════════════════════════════════════════════════════════════════
   Dev panel — layout; pintura pelas primitivas.
   Ferramenta interna (Ctrl+Shift+D), não é vista por jogador final.
═══════════════════════════════════════════════════════════════════════ */

.ww-dev-panel {
  position: fixed;
  top: 10px;
  right: 10px;
  width: 340px;
  max-height: calc(100vh - 20px);
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  color: var(--ww-text-primary);
  font-family: var(--ww-font-body);
  font-size: 12px;
  z-index: 500;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  pointer-events: auto;
}
.ww-dev-panel.hidden { display: none; }

.ww-dev-panel__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
  background: var(--ww-surface-sunken);
}
.ww-dev-panel__title { margin: 0; }

.ww-dev-panel__active {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 0;
  box-shadow: none;
  border-top: none;
  border-left: none;
  border-right: none;
}
.ww-dev-panel__active-label { flex: 0 0 auto; }
.ww-dev-panel__active-name {
  flex: 1;
  font-weight: 900;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ww-dev-panel__section {
  padding: 10px 12px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
  overflow-y: auto;
}
.ww-dev-panel__section:last-child { border-bottom: none; }

.ww-dev-panel__section-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}
.ww-dev-panel__inline-btn {
  padding: 4px 10px;
}

.ww-dev-panel__list { display: flex; flex-direction: column; gap: 6px; }
.ww-dev-panel__empty {
  font-style: italic;
  padding: 6px 0;
  font-size: 11px;
}

.ww-dev-panel__item {
  display: flex;
  gap: 8px;
  padding: 8px 10px;
  align-items: center;
}
.ww-dev-panel__item.broken { border-color: var(--ww-accent); }
.ww-dev-panel__item-body { flex: 1; min-width: 0; }
.ww-dev-panel__item-name {
  font-weight: 800;
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ww-dev-panel__item-desc {
  font-size: 11px;
  margin-top: 2px;
}
.ww-dev-panel__item-actions { display: flex; gap: 4px; }

.ww-dev-panel__tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.ww-dev-panel__tag {
  font-size: 10px;
  font-weight: 700;
  color: var(--ww-surface-raised);
  background: var(--ww-text-primary);
  padding: 1px 6px;
  border-radius: 3px;
}

.ww-dev-panel__util-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ww-dev-panel__util-grid label {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ww-dev-panel__util-grid .ww-input {
  width: 100%;
  font-size: 13px;
}

.ww-dev-panel__util-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin-top: 8px;
}

.ww-dev-panel__util-spawn {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: var(--ww-line-width) solid var(--ww-line);
}
.ww-dev-panel__util-spawn label {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Badge persistente no HUD indicando modo dev/cenário ativo. */
.ww-dev-badge {
  position: fixed;
  top: 10px;
  left: 10px;
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: calc(var(--ww-radius) - 2px);
  font-family: var(--ww-font-body);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 1px;
  padding: 4px 10px;
  z-index: 400;
  pointer-events: none;
  box-shadow: var(--ww-shadow);
}
.ww-dev-badge__name {
  font-weight: 700;
  margin-left: 6px;
  opacity: 0.9;
}

/* Telegraph de dropzone — dois níveis:
   - `.ww-card--dropzone`        → empilhamento possível (sempre que há target).
                                   Borda pontilhada sutil estática, sem pulso.
   - `.ww-card--dropzone-recipe` → empilhamento dispara receita. Soma-se ao
                                   estilo base com marching ants dourado
                                   e glow pulsante pra chamar atenção.
*/
/* Dropzone base: sinaliza alvo com marching ants EXTERNOS (via ::after com
   inset:-2px). Não engrossamos o border — isso come 2px do conteúdo em
   box-sizing:border-box e fica pior em cartas imóveis (com sprite grande)
   ou em pilhas. Aqui: zero mudança de layout ao entrar em dropzone. */
.ww-card--dropzone .ww-card__inner::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: calc(var(--ww-card-radius) + 2px);
  background:
    linear-gradient(90deg, var(--ww-line) 50%, transparent 50%) top/8px 2px repeat-x,
    linear-gradient(90deg, var(--ww-line) 50%, transparent 50%) bottom/8px 2px repeat-x,
    linear-gradient(0deg,  var(--ww-line) 50%, transparent 50%) left/2px 8px repeat-y,
    linear-gradient(0deg,  var(--ww-line) 50%, transparent 50%) right/2px 8px repeat-y;
  pointer-events: none;
}

/* Dropzone de receita: marching ants accent + pulse de scale (composited). */
.ww-card--dropzone-recipe .ww-card__inner {
  border-color: var(--ww-accent);
  animation: ww-dropzone-pulse 0.6s ease-in-out infinite;
}
.ww-card--dropzone-recipe .ww-card__inner::after {
  background:
    linear-gradient(90deg, var(--ww-accent) 50%, transparent 50%) top/10px 2px repeat-x,
    linear-gradient(90deg, var(--ww-accent) 50%, transparent 50%) bottom/10px 2px repeat-x,
    linear-gradient(0deg,  var(--ww-accent) 50%, transparent 50%) left/2px 10px repeat-y,
    linear-gradient(0deg,  var(--ww-accent) 50%, transparent 50%) right/2px 10px repeat-y;
  animation: ww-dropzone-march 0.4s linear infinite;
}
@keyframes ww-dropzone-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.03); }
}
@keyframes ww-dropzone-march {
  from { background-position: 0 0, 0 100%, 0 0, 100% 0; }
  to   { background-position: 10px 0, -10px 100%, 0 10px, 100% -10px; }
}

/* Pulse na carta-alvo no momento do snap. Confirma o encaixe. */
.ww-card__inner.ww-card--snap-pulse {
  animation: ww-snap-pulse 150ms ease-out;
}
@keyframes ww-snap-pulse {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}

/* Barra de progresso de recipe — posicionada sobre a carta do topo da pilha
   via transform em `#recipe-progress-bars`. Cor base verde (mesma do ring
   antigo pra manter continuidade visual). */
.ww-recipe-bar {
  position: absolute;
  left: 0;
  top: 0;
  height: 6px;
  background: var(--ww-surface-sunken);
  border: 2px solid var(--ww-line);
  border-radius: calc(var(--ww-card-radius) - 2px);
  overflow: hidden;
  will-change: transform;
}
.ww-recipe-bar__fill {
  height: 100%;
  width: 0%;
  background: var(--ww-line);
  transition: width 0.08s ease-out;
}
.ww-recipe-bar--flash {
  animation: ww-recipe-bar-flash 180ms ease-out forwards;
}
@keyframes ww-recipe-bar-flash {
  0%   { background: var(--ww-accent); transform: scaleY(1.6); }
  60%  { background: var(--ww-accent); }
  100% { background: transparent; opacity: 0; transform: scaleY(1); }
}
.ww-recipe-bar--cancel {
  animation: ww-recipe-bar-cancel 220ms ease-out forwards;
}
@keyframes ww-recipe-bar-cancel {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Scale-punch na carta envolvida num recipe complete. Marca "algo aconteceu". */
.ww-card__inner.ww-card--recipe-punch {
  animation: ww-recipe-punch 150ms ease-out;
}
@keyframes ww-recipe-punch {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* "Thud" ao soltar uma carta. Vem do scale 1.06 (drag) pra 1, passando por
   scaleY 0.92 (o impacto) e voltando com back-easing. Sensação de peso. */
.ww-card__inner.ww-card--thud {
  animation: ww-card-thud 200ms cubic-bezier(.22, 1.4, .32, 1);
}
@keyframes ww-card-thud {
  0%   { transform: scale(1.06); }
  40%  { transform: scale(1.04, 0.92); }
  100% { transform: scale(1, 1); }
}

/* Thud pesado: primeira vez que uma carta immovable é posicionada. Mais
   afundado, oscilação maior, duração estendida — sensação de "pousou firme". */
.ww-card__inner.ww-card--thud-heavy {
  animation: ww-card-thud-heavy 420ms cubic-bezier(.22, 1.4, .32, 1);
}
@keyframes ww-card-thud-heavy {
  0%   { transform: scale(1.10, 1.10); }
  25%  { transform: scale(1.14, 0.82); }
  55%  { transform: scale(0.96, 1.06); }
  78%  { transform: scale(1.02, 0.98); }
  100% { transform: scale(1, 1); }
}

/* Fold line — dupla função:
   (1) marca o limite visual do cabeçalho (texto do nome é cortado acima);
   (2) é o alvo de snap: o topo da próxima carta empilhada encosta nela.
   --ww-header-height vem do CardDOMRenderer, ancorada em CARD_HEADER_HEIGHT
   (core/deck.js) — fonte única. Zero animação: é guia permanente, não
   destaque. Posição em coord do __inner (que tem border-box, inset:0),
   então `top: var(--ww-header-height)` mede do topo da carta. */
.ww-card__fold {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--ww-header-height, 30px);
  height: 0;
  border-top: 1px dashed rgba(17, 17, 17, 0.35);
  pointer-events: none;
  z-index: 0;
}

.ww-card__name {
  /* Caixa de altura fixa = header − border top − padding top. Texto que
     não couber é cortado por overflow. Centraliza verticalmente pra ficar
     confortável quando o nome cabe numa linha. */
  height: calc(var(--ww-header-height, 30px) - var(--ww-line-width) - 8px);
  width: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 800;
  line-height: 1.1;
  text-align: center;
  letter-spacing: -0.1px;
  color: var(--ww-text-primary);
}

.ww-card__emoji {
  font-size: 44px;
  line-height: 1;
  margin: 4px 0;
  font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', system-ui, sans-serif;
}

.ww-card__sprite {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  max-height: 100%;
  object-fit: contain;
  margin: 4px 0;
  pointer-events: none;
  /* IMPORTANTE: não forçar `image-rendering: pixelated`.
     As artes chegam em alta resolução (244×274, 332×339) e são DOWNSCALED
     pra caber na carta (~60×60). Nearest-neighbor em downscale joga pixels
     fora aleatoriamente e causa aquele aspecto "estourado/serrilhado" que
     víamos (principalmente no charger-node). O default do navegador (smooth)
     lida bem com arte chapada de poucas cores — fica limpo sem artefato.
     Se voltar a querer pixel art nítida, o caminho é exportar em resolução
     baixa (ex: 64×64 ou 128×128) e reativar pixelated SÓ nesse caso. */
  image-rendering: auto;
}

/* Barra inferior de selos de status. NUNCA carrega texto — só ícones
   redondos, alinhados da esquerda pra direita. Detalhes numéricos e
   nomes ficam no tooltip (mouseover da carta). */
.ww-card__badges {
  margin-top: auto;
  display: flex;
  gap: 3px;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  overflow: hidden;
  min-height: 20px;
  padding: 0 2px;
}

.ww-card__badge {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 0 0 1px rgba(0, 0, 0, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  line-height: 1;
  font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', system-ui, sans-serif;
  user-select: none;
  pointer-events: none;
}
/* Badge de alerta — pulsa devagar pra chamar atenção que a máquina não está
   funcionando. Tooltip nativo (title=) revela o motivo. */
.ww-card__badge--alert {
  background: #ffd2d2;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 0 0 1px #c0392b;
  pointer-events: auto;
  animation: ww-badge-alert-pulse 1.6s ease-in-out infinite;
}
@keyframes ww-badge-alert-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.15); }
}

/* Bateria antiga (.ww-card__battery / __battery-fill) substituída por
   gradient no fundo do __inner. Ver `.ww-card__inner--battery` acima. */

.ww-hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  font-family: var(--ww-font-body);
  color: var(--ww-text-primary);
  z-index: 20;
}

/* Painel HUD base — mesma geometria da carta (raised + border 3px + radius + shadow chapada).
   Aplicada nos painéis money/clock/bill. Debt herda também mas com fill accent. */
.ww-hud__panel {
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 10px 12px;
}

.ww-hud__label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ww-text-muted);
  margin-top: 4px;
  line-height: 1;
}

/* Painel unificado de tempo: hora (grande) + dia (médio) + período (pequeno).
   Compõe .ww-panel pra herdar geometria. Panic troca o fill inteiro. */
.ww-hud__time-panel {
  position: absolute;
  top: 14px;
  left: 16px;
  width: 180px;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: background-color 0.15s linear, color 0.15s linear;
}
/* Arco do sol: substitui o relógio HH:MM. Track horizontal com 5 marquinhas
   (dawn / morning / midday / evening / dusk) e um glyph (emoji) que percorre
   da esquerda pra direita seguindo getDayProgress(). O glyph reflete o
   clima atual + a fase do dia (sol, sol nascente, lua, neblina, poeira…).
   Trajetória: x linear, y senoidal (apex no meio). Discreto — arco baixo,
   sem fundo no glyph, leitura por silhueta de emoji. */
.ww-hud__sun-arc {
  position: relative;
  width: 100%;
  height: 22px;
  margin: 0 0 4px;
}
.ww-hud__sun-track {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--ww-line);
  border-radius: 2px;
  opacity: 0.6;
}
.ww-hud__sun-tick {
  position: absolute;
  bottom: -1px;
  width: 2px;
  height: 5px;
  background: var(--ww-line);
  transform: translateX(-50%);
  border-radius: 1px;
  opacity: 0.6;
}
.ww-hud__sun-tick:nth-child(3) {
  height: 7px;
  bottom: -2px;
  opacity: 0.85;
}
.ww-hud__sun {
  --sun-x: 0%;
  --sun-y: 0;
  position: absolute;
  left: var(--sun-x);
  bottom: 0;
  width: 18px;
  height: 18px;
  font-size: 16px;
  line-height: 18px;
  text-align: center;
  font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', system-ui, sans-serif;
  transform: translate(-50%, calc(-1 * var(--sun-y) * 14px));
  transition: transform 0.2s linear, left 0.2s linear;
}
.ww-hud__day-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-top: 6px;
  border-top: 2px solid var(--ww-line);
  margin-top: 2px;
}
.ww-hud__day-icon {
  font-size: 13px;
  line-height: 1;
  font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', system-ui, sans-serif;
}
.ww-hud__day {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ww-text-muted);
  line-height: 1;
}
.ww-hud__time-row {
  display: flex;
  align-items: center;
  gap: 6px;
}
.ww-hud__time {
  font-size: 11px;
  font-weight: 700;
  color: var(--ww-text-muted);
  line-height: 1;
}

/* Frozen (grace period): time hasn't started yet. Hint slot is visible,
   sun glyph idles. Cleared on the first card drag. */
.ww-hud__frozen-hint {
  display: none;
  margin-top: 4px;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ww-accent);
  line-height: 1.2;
  animation: ww-hud-frozen-blink 1.4s ease-in-out infinite;
}
.ww-hud__time-panel.frozen .ww-hud__frozen-hint {
  display: block;
}
@keyframes ww-hud-frozen-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* Panic (fim do dia): painel inteiro vira accent. Pulso de scale composited. */
.ww-hud__time-panel.panic {
  background: var(--ww-accent);
}
.ww-hud__time-panel.panic .ww-hud__day,
.ww-hud__time-panel.panic .ww-hud__time {
  color: var(--ww-surface-raised);
}
.ww-hud__time-panel.panic .ww-hud__day-row {
  border-top-color: var(--ww-surface-raised);
}
.ww-hud__time-panel.panic .ww-hud__sun-track,
.ww-hud__time-panel.panic .ww-hud__sun-tick {
  background: var(--ww-surface-raised);
}
.ww-hud__time-panel.panic {
  animation: ww-hud-pulse 0.8s ease-in-out infinite;
  transform-origin: left center;
}
@keyframes ww-hud-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.03); }
}

/* Hint "drag cards..." — fundo-centro, fora do caminho do clock (topo-esq)
   e dos speed buttons (topo-centro). Fica como pílula discreta. */
.ww-hud__hint {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 700;
  color: var(--ww-text-muted);
  background: var(--ww-surface-raised);
  border: 2px solid var(--ww-line);
  border-radius: 999px;
  padding: 6px 14px;
  pointer-events: none;
  white-space: nowrap;
}

.ww-hud__money {
  position: absolute;
  top: 14px;
  right: 16px;
  min-width: 92px;
  font-size: 26px;
  font-weight: 900;
  font-family: var(--ww-font-display);
  color: var(--ww-accent);
  line-height: 1;
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 10px 12px;
  text-align: right;
  transition: background-color 0.15s linear, color 0.15s linear;
}

/* Crédito: aparece à ESQUERDA do money quando o banco já abriu. Mesmo
   molde visual, alinhado pela borda superior pra ler como par. O `right`
   calcula a largura do bloco do money (min-width 92px + padding 10+12 +
   borda 2×2) com folga de 10px entre os dois. */
.ww-hud__credit {
  position: absolute;
  top: 14px;
  right: calc(16px + 92px + 24px + 4px + 10px);
  display: none;
  min-width: 92px;
  font-size: 16px;
  font-weight: 900;
  font-family: var(--ww-font-display);
  color: var(--ww-text-primary);
  line-height: 1;
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 10px 12px;
  text-align: right;
}

/* Partícula de delta do money. Sai do HUD money, verde pra cima, vermelha pra baixo. */
.ww-money-particle {
  position: absolute;
  top: 14px;
  right: 16px;
  font-size: 14px;
  font-weight: 800;
  pointer-events: none;
  font-family: var(--ww-font-body);
  opacity: 0;
  animation-duration: 900ms;
  animation-fill-mode: forwards;
  animation-timing-function: cubic-bezier(.34, 1.56, .64, 1);
}
.ww-money-particle.up {
  color: #2a8f2a;
  animation-name: ww-money-particle-up;
}
.ww-money-particle.down {
  color: var(--ww-accent);
  animation-name: ww-money-particle-down;
}
@keyframes ww-money-particle-up {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.7); }
  15%  { opacity: 1; transform: translate(0, -14px) scale(1.1); }
  70%  { opacity: 1; transform: translate(0, -24px) scale(1); }
  100% { opacity: 0; transform: translate(0, -36px) scale(0.95); }
}
@keyframes ww-money-particle-down {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.7); }
  15%  { opacity: 1; transform: translate(0, 20px) scale(1.1); }
  70%  { opacity: 1; transform: translate(0, 30px) scale(1); }
  100% { opacity: 0; transform: translate(0, 42px) scale(0.95); }
}
/* Shake = só transform (composited). Troca de cor via background/color sem shadow animado. */
.ww-hud__money.shake {
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
  animation: ww-money-shake 0.9s cubic-bezier(.36,.07,.19,.97) both;
}
@keyframes ww-money-shake {
  0%, 100% { transform: translate3d(0, 0, 0); }
  10%, 30%, 50%, 70%, 90% { transform: translate3d(-6px, 0, 0); }
  20%, 40%, 60%, 80%      { transform: translate3d( 6px, 0, 0); }
}
/* Pulse curto: cada moeda da CoinFountain "absorve" no HUD com este flash. */
.ww-hud__money--coin-pop {
  animation: ww-money-coin-pop 0.18s ease-out both;
}
@keyframes ww-money-coin-pop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}

.ww-hud__bill {
  position: absolute;
  top: 80px;
  right: 16px;
  width: 172px;
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 10px 12px;
  font-size: 12px;
  color: var(--ww-text-primary);
  transition: background-color 0.2s linear, color 0.2s linear;
}
/* Flash = troca de fill (accent). Curto e não-infinito. Só opacity muda na curva. */
.ww-hud__bill.flash {
  animation: ww-bill-flash 0.9s ease-out both;
}
@keyframes ww-bill-flash {
  0%, 40% { background: var(--ww-accent); color: var(--ww-surface-raised); }
  100%    { background: var(--ww-surface-raised); color: var(--ww-text-primary); }
}

/* Splash central de cobrança — carta "gigante" com mesma geometria. Só transform+opacity na anim. */
.ww-bill-splash {
  position: fixed;
  top: 38%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.7);
  pointer-events: none;
  z-index: 90;
  opacity: 0;
  text-align: center;
  font-family: var(--ww-font-display);
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 20px 32px;
  min-width: 280px;
}
.ww-bill-splash.show {
  animation: ww-splash 1.8s ease-out forwards;
}
@keyframes ww-splash {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  15%  { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
  25%  {             transform: translate(-50%, -50%) scale(1.0); }
  80%  { opacity: 1; transform: translate(-50%, -50%) scale(1.0); }
  100% { opacity: 0; transform: translate(-50%, -60%) scale(0.95); }
}
.ww-bill-splash__title {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--ww-surface-raised);
  opacity: 0.85;
}
.ww-bill-splash__amount {
  font-size: 56px;
  font-weight: 900;
  margin: 6px 0 4px;
  color: var(--ww-surface-raised);
  font-family: var(--ww-font-display);
  line-height: 1;
}
.ww-bill-splash__breakdown {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ww-surface-raised);
  opacity: 0.8;
}

.ww-hud__bill-title {
  font-size: 10px;
  font-weight: 800;
  color: var(--ww-text-muted);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 6px;
}
.ww-hud__bill-line {
  display: flex;
  justify-content: space-between;
  line-height: 1.6;
  font-weight: 600;
}
.ww-hud__bill-total {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  padding-top: 6px;
  border-top: var(--ww-line-width) solid var(--ww-line);
  font-weight: 800;
  color: var(--ww-text-primary);
}

/* Debt = painel accent por natureza (estado visível). */
.ww-hud__debt {
  position: absolute;
  top: 220px;
  right: 16px;
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
/* Critical = pulse de scale, não de shadow (shadow animado é caro). */
.ww-hud__debt.critical {
  animation: ww-hud-pulse 0.8s ease-in-out infinite;
  transform-origin: right center;
}
.ww-hud__debt-icon {
  margin-right: 4px;
}

.ww-hud__speed {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  pointer-events: auto;
}
.ww-hud__speed button {
  font-family: var(--ww-font-body);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.3px;
  color: var(--ww-text-primary);
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  padding: 8px 14px;
  min-width: 48px;
  cursor: pointer;
  box-shadow: var(--ww-shadow);
  /* Só anima transform e box-shadow (chapada). Nada de filter. */
  transition: transform 0.08s ease, box-shadow 0.08s ease, background-color 0.1s linear, color 0.1s linear;
}
.ww-hud__speed button:hover {
  transform: translate(-1px, -1px);
  box-shadow: 0 6px 0 var(--ww-line);
}
.ww-hud__speed button:active {
  transform: translate(0, 2px);
  box-shadow: 0 2px 0 var(--ww-line);
}
.ww-hud__speed button.active {
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
}
/* Two audio toggles side by side: SFX (sound effects) and Music. Each button
   is independent — the layout primitive just stacks them horizontally. */
.ww-hud__audio {
  position: absolute;
  bottom: 12px;
  left: 12px;
  display: flex;
  gap: 6px;
  pointer-events: auto;
}
.ww-hud__mute {
  pointer-events: auto;
}
/* Muted state: muted icon already conveys it, but adding muted text-color
   from the muted token keeps it visually consistent with other "off" buttons. */
.ww-hud__mute--off {
  color: var(--ww-text-muted);
}

/* Reset tutorials — discreto (opacity baixa em idle, full no hover).
   Click dispara pulse rápido pra feedback visual. */
.ww-hud__reset-tutos {
  pointer-events: auto;
  opacity: 0.45;
  transition: opacity 160ms ease;
  font-size: 18px;
  line-height: 1;
}
.ww-hud__reset-tutos:hover {
  opacity: 1;
}
.ww-hud__reset-tutos--pulse {
  animation: ww-reset-tutos-pulse 600ms ease;
}
@keyframes ww-reset-tutos-pulse {
  0%   { transform: rotate(0deg)   scale(1);   background: var(--ww-surface-raised); }
  50%  { transform: rotate(180deg) scale(1.18); background: var(--ww-accent); }
  100% { transform: rotate(360deg) scale(1);   background: var(--ww-surface-raised); }
}

/* Tooltip — mesma geometria da carta, escalada menor. Sem anim de background. */
.ww-tooltip {
  position: absolute;
  background: var(--ww-surface-raised);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  box-shadow: var(--ww-shadow);
  padding: 10px 12px;
  color: var(--ww-text-primary);
  font-family: var(--ww-font-body);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.45;
  max-width: 260px;
  pointer-events: none;
  z-index: 30;
}
.ww-tooltip__name {
  color: var(--ww-text-primary);
  font-family: var(--ww-font-display);
  font-size: 14px;
  font-weight: 800;
  line-height: 1.1;
  margin-bottom: 2px;
}
.ww-tooltip__meta {
  color: var(--ww-text-muted);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 6px;
}
.ww-tooltip__props {
  margin: 6px 0;
}
.ww-tooltip__props .row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.ww-tooltip__props .row .k { color: var(--ww-text-muted); font-weight: 700; }
.ww-tooltip__props .row .v { color: var(--ww-text-primary); font-weight: 800; display: inline-flex; gap: 6px; align-items: baseline; }
.ww-tooltip__props .row .v .r { color: var(--ww-text-muted); font-weight: 600; font-size: 10px; opacity: 0.75; }
.ww-tooltip__props .row .v .b { color: var(--ww-text-muted); font-weight: 600; font-size: 10px; opacity: 0.75; }
.ww-tooltip__tags {
  margin-top: 6px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
}
.ww-tooltip__tags .tag {
  color: var(--ww-surface-raised);
  background: var(--ww-text-primary);
  font-size: 9px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 3px;
}
.ww-tooltip__status {
  margin-top: 6px;
  color: var(--ww-accent);
  font-size: 11px;
  font-weight: 800;
}
.ww-tooltip__cargo {
  margin-top: 8px;
  padding-top: 6px;
  border-top: var(--ww-line-width) solid var(--ww-line);
}
.ww-tooltip__cargo .row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.ww-tooltip__cargo .row .k { color: var(--ww-text-muted); font-size: 11px; font-weight: 700; }
.ww-tooltip__cargo .row .v { color: var(--ww-text-primary); font-weight: 800; font-size: 11px; }
.ww-tooltip__section-title {
  color: var(--ww-text-muted);
  font-size: 9px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 4px;
}

/* ═══════════════════════════════════════════════════════════════════════
   Store modal — só hooks de layout/posição.
   Pintura vem das primitivas .ww-panel, .ww-button, .ww-badge, .ww-scroll,
   .ww-heading, .ww-label, .ww-body. HTML em StorePanelRenderer.js.
═══════════════════════════════════════════════════════════════════════ */

.ww-store-modal__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 90;
  pointer-events: auto;
}
.ww-store-modal {
  position: fixed;
  inset: 0;
  z-index: 91;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
}

/* Frame = .ww-panel escalada. Override padding/radius pra encaixar header+body+footer. */
.ww-store-modal__frame {
  width: min(880px, 92vw);
  max-height: 86vh;
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.ww-store-modal__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
  /* Identidade da loja: fundo tingido na cor do tipo, com textura de hatch
     sutil pra ter personalidade sem ficar só "bloco colorido". --ww-store-color
     é setada inline pelo renderer a partir do store.type.color. */
  background:
    repeating-linear-gradient(
      45deg,
      transparent 0 8px,
      rgba(255, 255, 255, 0.08) 8px 10px
    ),
    var(--ww-store-color, var(--ww-surface-raised));
}
.ww-store-modal__header-emoji {
  font-size: 48px;
  line-height: 1;
  flex-shrink: 0;
  filter: drop-shadow(0 2px 0 var(--ww-line));
}
.ww-store-modal__title-block {
  flex: 1;
  line-height: 1.2;
}
.ww-store-modal__title {
  margin: 0;
  font-size: 26px;
  letter-spacing: 1px;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.15);
}
.ww-store-modal__subtitle { margin-top: 6px; }

/* Tabs = .ww-button que ocupa largura igual. --active usa .is-active via modifier. */
.ww-store-modal__tabs {
  display: flex;
  gap: 8px;
  padding: 12px 20px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
}
.ww-store-modal__tab {
  flex: 1;
  text-align: left;
  flex-direction: column;
  gap: 2px;
  padding: 10px 14px;
}
.ww-store-modal__tab--active {
  background: var(--ww-accent);
  color: var(--ww-surface-raised);
}
.ww-store-modal__tab-label {
  font-size: 14px;
  font-weight: 800;
}
.ww-store-modal__tab-sub {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  opacity: 0.75;
}

.ww-store-modal__body {
  flex: 1;
  padding: 20px;
}

.ww-store-modal__offers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
}

/* Card de oferta = .ww-panel escalada. Override pra virar clicável centralizado.
   Hover é DRAMÁTICO — levanta mais, sombra cresce, rotação minúscula pra
   sinalizar "pegar pra si". Click afunda forte. Zero filter/glow. */
.ww-store-modal__card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  min-height: 180px;
  padding: 18px 12px 14px;
  cursor: pointer;
  transition: transform 0.14s cubic-bezier(.3,1.4,.5,1),
              box-shadow 0.14s ease,
              background-color 0.15s linear;
}
.ww-store-modal__card:hover:not(:disabled) {
  transform: translate(-2px, -6px) rotate(-1deg) scale(1.03);
  box-shadow: 0 12px 0 var(--ww-line);
  z-index: 2;
}
.ww-store-modal__card:active:not(:disabled) {
  transform: translate(1px, 3px) scale(0.97);
  box-shadow: 0 2px 0 var(--ww-line);
  transition-duration: 0.04s;
}
.ww-store-modal__card--poor {
  opacity: 0.4;
  cursor: not-allowed;
}
.ww-store-modal__card:disabled:hover { transform: none; box-shadow: var(--ww-shadow); }

/* Wrapper de tamanho fixo pro slot de ícone — garante grid alinhado mesmo
   quando o sprite tem aspect ratio diferente. Renderer emite UM filho:
   ou .ww-store-modal__card-icon (emoji) ou .ww-store-modal__card-icon-sprite
   (img). Em caso de img com erro, onerror troca a img pelo div emoji. */
.ww-store-modal__card-icon-wrap {
  width: 64px;
  height: 64px;
  margin: 4px auto 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ww-store-modal__card-icon {
  font-size: 42px;
  line-height: 1;
}
.ww-store-modal__card-icon-sprite {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  image-rendering: auto;
}
.ww-store-modal__card-name {
  font-size: 14px;
  font-weight: 900;
  color: var(--ww-text-primary);
  line-height: 1.2;
}
.ww-store-modal__card-desc {
  font-size: 11px;
  flex: 1;
}
.ww-store-modal__card-price {
  position: absolute;
  top: -10px;
  right: 10px;
}

.ww-store-modal__catalog {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Row de catálogo = .ww-panel--sunken escalada (visual "dentro"). */
.ww-store-modal__row {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
}
.ww-store-modal__row--poor { opacity: 0.5; }
/* Slot de ícone do catalog — mesmo princípio do offer card, tamanho menor
   pra linha densa. Renderer emite emoji OU sprite, nunca os dois. */
.ww-store-modal__row-icon-wrap {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.ww-store-modal__row-icon {
  font-size: 28px;
  line-height: 1;
}
.ww-store-modal__row-icon-sprite {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  image-rendering: auto;
}
.ww-store-modal__row-body { flex: 1; min-width: 0; }
.ww-store-modal__row-name {
  font-size: 14px;
  font-weight: 800;
  color: var(--ww-text-primary);
}
.ww-store-modal__row-desc {
  font-size: 11px;
  margin-top: 2px;
}
.ww-store-modal__row-buy { min-width: 64px; }

.ww-store-modal__empty {
  text-align: center;
  padding: 40px 0;
}

.ww-store-modal__footer {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px;
  border-top: var(--ww-line-width) solid var(--ww-line);
  background: var(--ww-surface-sunken);
  transition: background-color 0.18s ease;
}
.ww-store-modal__footer--flash {
  animation: ww-footer-flash 0.5s ease-out;
}
@keyframes ww-footer-flash {
  0%, 100% { background: var(--ww-surface-sunken); }
  30%      { background: var(--ww-accent); }
}
.ww-store-modal__wallet {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  position: relative;
}
.ww-store-modal__wallet strong {
  font-size: 22px;
  font-weight: 900;
  color: var(--ww-accent);
  display: inline-block;
  transform-origin: center center;
}
.ww-wallet-flyoff {
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: 10px;
  transform: translateY(-50%);
  color: var(--ww-accent);
  font-family: var(--ww-font-display);
  font-size: 24px;
  font-weight: 900;
  pointer-events: none;
  white-space: nowrap;
  animation: ww-wallet-flyoff 0.9s ease-out forwards;
  z-index: 5;
}
@keyframes ww-wallet-flyoff {
  0%   { transform: translate(0, -50%) scale(0.6); opacity: 0; }
  20%  { transform: translate(8px, -80%) scale(1.25); opacity: 1; }
  100% { transform: translate(24px, -250%) scale(1); opacity: 0; }
}

.ww-store-modal__offers-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
}
.ww-store-modal__offers-info { flex: 1; }
.ww-store-modal__offers-info-title {
  font-family: var(--ww-font-display);
  font-size: 22px;
  font-weight: 900;
  color: var(--ww-accent);
  letter-spacing: 0.5px;
  line-height: 1;
  /* Leve wiggle perpétuo pra puxar o olhar sem ser gritante. */
  animation: ww-offers-wiggle 3s ease-in-out infinite;
  transform-origin: left center;
}
.ww-store-modal__offers-info-sub {
  margin-top: 4px;
  font-family: var(--ww-font-body);
  font-size: 12px;
  font-weight: 600;
  font-style: italic;
  color: var(--ww-text-muted);
}
@keyframes ww-offers-wiggle {
  0%, 100% { transform: rotate(-1.5deg); }
  50%      { transform: rotate(1.5deg); }
}
.ww-store-modal__reroll { gap: 8px; }
.ww-store-modal__reroll-icon { font-size: 16px; }

/* Variant badge = sticker no canto da card. Cor por variante define o tom. */
.ww-store-modal__variant {
  position: absolute;
  top: -10px;
  left: 10px;
}
.ww-store-modal__variant--buff     { background: #3a8f3c; color: var(--ww-surface-raised); }
.ww-store-modal__variant--tradeoff { background: #c48a2a; color: var(--ww-text-primary); }
.ww-store-modal__variant--bargain  { background: #8f3c5a; color: var(--ww-surface-raised); }

/* Borda da card acompanha variant (fallback pra accent). */
.ww-store-modal__card--buff     { border-color: #3a8f3c; }
.ww-store-modal__card--tradeoff { border-color: #c48a2a; }
.ww-store-modal__card--bargain  { border-color: #8f3c5a; }

/* Stats inline na card de oferta. */
.ww-store-modal__card-stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 3px 6px;
  margin-top: 2px;
}
.ww-store-modal__stat {
  font-size: 10px;
  font-weight: 800;
  padding: 1px 6px;
  border-radius: 3px;
  border: 2px solid var(--ww-line);
  line-height: 1.3;
}
.ww-store-modal__stat--up   { background: #3a8f3c; color: var(--ww-surface-raised); }
.ww-store-modal__stat--down { background: var(--ww-accent); color: var(--ww-surface-raised); }

/* Tooltip do hover interno — compõe .ww-panel. */
.ww-store-tooltip {
  position: fixed;
  z-index: 95;
  pointer-events: none;
  max-width: 280px;
  font-size: 12px;
}
.ww-store-tooltip__header {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
}
.ww-store-tooltip__icon-wrap {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.ww-store-tooltip__emoji {
  font-size: 28px;
  line-height: 1;
}
.ww-store-tooltip__emoji-sprite {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  image-rendering: auto;
}
.ww-store-tooltip__name {
  font-size: 14px;
  font-weight: 900;
  color: var(--ww-text-primary);
  line-height: 1.2;
}
.ww-store-tooltip__type {
  font-size: 10px;
  font-weight: 700;
  color: var(--ww-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-top: 2px;
}
.ww-store-tooltip__desc {
  color: var(--ww-text-primary);
  font-size: 12px;
  line-height: 1.45;
  margin-bottom: 8px;
}
.ww-store-tooltip__stats {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 6px;
  border-top: var(--ww-line-width) solid var(--ww-line);
}
.ww-store-tooltip__stat {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
  color: var(--ww-text-primary);
  font-weight: 700;
}
.ww-store-tooltip__stat--up   { color: #2a8f2a; }
.ww-store-tooltip__stat--down { color: var(--ww-accent); }
.ww-store-tooltip__delta {
  color: var(--ww-text-muted);
  font-size: 10px;
  font-weight: 600;
}
.ww-store-tooltip__variant {
  margin-top: 8px;
  padding: 6px 8px;
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: calc(var(--ww-radius) - 2px);
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.4px;
}
.ww-store-tooltip__variant--buff     { background: #3a8f3c; color: var(--ww-surface-raised); }
.ww-store-tooltip__variant--tradeoff { background: #c48a2a; color: var(--ww-text-primary); }
.ww-store-tooltip__variant--bargain  { background: #8f3c5a; color: var(--ww-surface-raised); }
.ww-store-tooltip__hint {
  margin-top: 8px;
  color: var(--ww-text-muted);
  font-size: 11px;
  font-weight: 700;
  text-align: center;
}

/* ---------- Feedback de compra (CSS puro) ---------- */

/* Pulse no botão clicado. Finito (600ms), só scale — composited. */
.ww-store-modal__card,
.ww-store-modal__row-buy,
.ww-store-modal__reroll {
  position: relative;
}
.ww-buy-pulse {
  animation: ww-buy-pulse 0.55s cubic-bezier(.3,1.8,.6,1);
}
@keyframes ww-buy-pulse {
  0%   { transform: scale(1) rotate(0deg); }
  20%  { transform: scale(1.18) rotate(-2deg); }
  50%  { transform: scale(0.92) rotate(1deg); }
  75%  { transform: scale(1.05) rotate(-0.5deg); }
  100% { transform: scale(1) rotate(0deg); }
}

/* "-$X" que sobe do centro do botão. Transform+opacity só. */
.ww-buy-flyoff {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  color: var(--ww-accent);
  font-weight: 900;
  font-size: 22px;
  font-family: var(--ww-font-body);
  white-space: nowrap;
  animation: ww-buy-flyoff 0.9s ease-out forwards;
  z-index: 10;
}
@keyframes ww-buy-flyoff {
  0%   { transform: translate(-50%, -50%) scale(0.6); opacity: 0; }
  20%  { transform: translate(-50%, -80%) scale(1.15); opacity: 1; }
  100% { transform: translate(-50%, -220%) scale(1); opacity: 0; }
}

/* Carta recém-comprada no mundo: shake curto sobrescrevendo idle-breath. */
.ww-card--just-purchased .ww-card__inner {
  animation: ww-just-purchased-shake 0.5s ease-in-out !important;
}
@keyframes ww-just-purchased-shake {
  0%, 100% { transform: translateX(0); }
  15%      { transform: translateX(-4px) rotate(-1deg); }
  30%      { transform: translateX(4px)  rotate(1deg); }
  45%      { transform: translateX(-3px) rotate(-0.8deg); }
  60%      { transform: translateX(3px)  rotate(0.8deg); }
  75%      { transform: translateX(-2px); }
  90%      { transform: translateX(2px); }
}

/* ═══════════════════════════════════════════════════════════════════════
   Game over — layout; pintura pelas primitivas.
═══════════════════════════════════════════════════════════════════════ */

.ww-gameover {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  font-family: var(--ww-font-body);
  pointer-events: auto;
  animation: ww-gameover-fade 0.5s ease-out;
}
@keyframes ww-gameover-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.ww-gameover__inner {
  max-width: 520px;
  width: 92%;
  max-height: 88vh;
  padding: 32px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  animation: ww-gameover-slide 0.45s ease-out 0.1s both;
  /* ww-scroll liga overflow:auto nos dois eixos; aqui só queremos rolagem
     vertical — qualquer valor longo (título com letter-spacing, stat row)
     não pode forçar scrollbar horizontal. */
  overflow-x: hidden;
  box-sizing: border-box;
}
.ww-gameover__inner > * { max-width: 100%; }
.ww-gameover__stat > span { min-width: 0; overflow-wrap: anywhere; }
@keyframes ww-gameover-slide {
  from { transform: translateY(20px) scale(0.95); opacity: 0; }
  to   { transform: translateY(0) scale(1);       opacity: 1; }
}
.ww-gameover__icon {
  font-size: 56px;
  line-height: 1;
}
.ww-gameover__title {
  margin: 0;
  color: var(--ww-accent);
  font-size: 34px;
  letter-spacing: 0.5px;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.ww-gameover__subtitle {
  margin: 0;
  font-size: 14px;
}
.ww-gameover__epitaph {
  margin: 0 0 8px 0;
  font-style: italic;
  font-size: 13px;
  color: var(--ww-text-muted);
}
.ww-gameover__stats {
  width: 100%;
  padding: 14px 16px;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ww-gameover__stats-title {
  text-align: center;
  margin-bottom: 6px;
}
.ww-gameover__stat {
  display: flex;
  justify-content: space-between;
  padding: 4px 0;
  font-size: 13px;
  font-weight: 700;
}
.ww-gameover__stat.emphasis {
  font-size: 15px;
  font-weight: 900;
  color: var(--ww-accent);
  border-top: var(--ww-line-width) solid var(--ww-line);
  margin-top: 6px;
  padding-top: 8px;
}
.ww-gameover__btn {
  margin-top: 8px;
  font-size: 15px;
  padding: 12px 32px;
}

/* ═══════════════════════════════════════════════════════════════════════
   Rank notifications — layout; pintura pelas primitivas.
═══════════════════════════════════════════════════════════════════════ */

.ww-rank-toasts {
  position: fixed;
  top: 80px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  z-index: 80;
  pointer-events: none;
  font-family: var(--ww-font-body);
}
/* Toast = .ww-panel pill-shaped. Só opacity+transform na transição. */
.ww-rank-toast {
  padding: 10px 18px;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.5px;
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.ww-rank-toast.big {
  font-size: 15px;
  padding: 14px 26px;
}
.ww-rank-toast.show {
  opacity: 1;
  transform: translateY(0);
}

/* Trophy popup = .ww-panel--accent escalado. */
.ww-rank-trophy {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 20px;
  opacity: 0;
  transform: translateY(-16px) scale(0.9);
  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(.34,1.56,.64,1);
}
.ww-rank-trophy.show {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.ww-rank-trophy__icon {
  font-size: 44px;
  line-height: 1;
  animation: ww-trophy-bob 1.4s ease-in-out infinite;
}
@keyframes ww-trophy-bob {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50%      { transform: translateY(-4px) rotate(4deg); }
}
.ww-rank-trophy__title {
  margin: 0;
  color: var(--ww-surface-raised);
  letter-spacing: 1.5px;
}
.ww-rank-trophy__sub {
  margin-top: 4px;
  color: var(--ww-surface-raised);
  opacity: 0.85;
}

.ww-confetti {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 75;
}
.ww-confetti__piece {
  position: absolute;
  top: -20px;
  width: 10px;
  height: 14px;
  border-radius: 2px;
  animation: ww-confetti-fall var(--dur, 2s) var(--delay, 0s) ease-in forwards;
}
@keyframes ww-confetti-fall {
  0% {
    transform: translate(0, 0) rotate(0);
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    transform: translate(var(--dx, 0), 115vh) rotate(var(--rot, 360deg));
    opacity: 0;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   Pause + confirm — layout; pintura pelas primitivas.
   REGRA CRÍTICA: .ww-pause tem pointer-events:none e z-index:15 (abaixo do HUD z:20).
   Mudar aqui quebra botões de speed no pause. A única coisa clicável é o end-run,
   que reativa pointer-events nele mesmo.
═══════════════════════════════════════════════════════════════════════ */

.ww-pause {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 15;
  pointer-events: none;
  font-family: var(--ww-font-body);
  animation: ww-pause-in 0.2s ease-out;
}

/* Quando a mesa está encoberta (pause/loja), painéis do HUD ganham destaque
   — escala levemente maior + sombra mais chapada — pra subirem como foco
   visual. Dinheiro e relógio ficam naturalmente à frente ao invés de se
   perderem atrás do overlay cinza. */
body.is-pause-open .ww-hud__panel,
body.is-pause-open .ww-hud__time-panel,
body.is-pause-open .ww-hud__money,
body.is-pause-open .ww-hud__bill,
body.is-pause-open .ww-hud__debt {
  transform: scale(1.05);
  box-shadow: 0 6px 0 var(--ww-line);
  transition: transform 0.18s ease-out, box-shadow 0.18s ease-out;
}
@keyframes ww-pause-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.ww-pause__inner {
  text-align: center;
  padding: 24px 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.ww-pause__icon {
  font-size: 56px;
  line-height: 1;
  margin-bottom: 4px;
}
.ww-pause__title {
  margin: 0;
  letter-spacing: 4px;
}
.ww-pause__hint {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.5px;
}
.ww-pause__end-run {
  pointer-events: auto;
  margin-top: 12px;
}

.ww-pause-confirm {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 20;
  pointer-events: auto;
  font-family: var(--ww-font-body);
  animation: ww-pause-in 0.15s ease-out;
}
/* Modifier pra casos em que o confirm precisa sobrepor o main menu (z 200). */
.ww-pause-confirm--over-mainmenu {
  z-index: 210;
}
.ww-pause-confirm__inner {
  max-width: 420px;
  padding: 24px 28px;
}
.ww-pause-confirm__title {
  margin: 0 0 10px 0;
}
.ww-pause-confirm__body {
  margin: 0 0 20px 0;
}
.ww-pause-confirm__actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

/* ═══════════════════════════════════════════════════════════════════════
   Main menu — layout; pintura vem das primitivas.
═══════════════════════════════════════════════════════════════════════ */

.ww-mainmenu {
  position: fixed;
  inset: 0;
  /* Transparente: o background (mesa xadrez + campo de árvores) é renderizado
     pela MenuBackgroundScene no canvas Phaser ATRÁS deste DOM. Pintar aqui
     tampa as árvores. body já tem var(--ww-stage-bg) como fallback caso o
     canvas falhe. */
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  font-family: var(--ww-font-body);
  pointer-events: auto;
  padding: 24px;
  overflow: hidden;
}
.ww-mainmenu__inner {
  display: grid;
  grid-template-columns: minmax(360px, 1fr) minmax(280px, 360px);
  gap: 20px;
  max-width: 920px;
  width: 100%;
  max-height: 100%;
  min-height: 0;
}
.ww-mainmenu__fixed {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 28px 32px;
  text-align: left;
  overflow: auto;
}
.ww-mainmenu__title {
  margin: 0;
  color: var(--ww-accent);
}
/* Variante PNG do título — usa a arte da carta `title-1` quando o
   SpriteManifest tem o sprite. Largura ocupa o painel inteiro,
   height auto preserva a proporção original da arte. image-rendering
   smooth porque a arte é raster sendo downscaled. */
.ww-mainmenu__title-img {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 0 4px;
  user-select: none;
  -webkit-user-drag: none;
}
.ww-mainmenu__subtitle {
  margin: 0 0 4px;
}

/* Intro = painel sunken dentro do frame. */
.ww-mainmenu__intro {
  background: var(--ww-surface-sunken);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: var(--ww-radius);
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ww-mainmenu__intro p { margin: 0; }
.ww-mainmenu__intro strong { font-weight: 900; }

.ww-mainmenu__continue {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ww-mainmenu__separator {
  text-align: center;
  margin: 4px 0;
  opacity: 0.8;
}

.ww-mainmenu__name-row {
  display: flex;
  gap: 8px;
}
.ww-mainmenu__name-input {
  flex: 1;
  font-size: 15px;
}

/* Painel direito: agrupa controles (continue/nome/new run) e leaderboard
   compacto na base. Antes era só leaderboard, mas a home foi reorganizada
   pra deixar o painel esquerdo livre pro título PNG + intro. */
.ww-mainmenu__side {
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}
.ww-mainmenu__leaderboard-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  margin-top: 6px;
}
.ww-mainmenu__leaderboard-title {
  margin: 0;
  text-align: center;
}
.ww-mainmenu__local {
  display: inline-block;
  margin-left: 6px;
  vertical-align: middle;
}
.ww-mainmenu__leaderboard-scroll {
  flex: 1 1 auto;
  min-height: 0;
  padding-right: 4px;
}
.ww-mainmenu__empty {
  text-align: center;
  padding: 14px 0;
}
.ww-mainmenu__leaderboard-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ww-mainmenu__leaderboard-row {
  display: grid;
  grid-template-columns: 36px 1fr auto auto;
  gap: 10px;
  padding: 8px 10px;
  align-items: center;
  cursor: help;
  background: var(--ww-surface-sunken);
  border: var(--ww-line-width) solid var(--ww-line);
  border-radius: calc(var(--ww-radius) - 2px);
  font-size: 13px;
  font-weight: 700;
  color: var(--ww-text-primary);
}
.ww-mainmenu__leaderboard-row:hover {
  background: var(--ww-surface-raised);
}
.ww-mainmenu__rank {
  color: var(--ww-text-muted);
  font-weight: 900;
}
.ww-mainmenu__farmer {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ww-mainmenu__score {
  color: var(--ww-accent);
  font-weight: 900;
}
.ww-mainmenu__days {
  color: var(--ww-text-muted);
  font-size: 11px;
}

/* Botões do menu têm layout vertical (title + meta). Compostos sobre .ww-button. */
.ww-mainmenu__btn {
  flex-direction: column;
  gap: 2px;
  padding: 14px 20px;
}
.ww-mainmenu__btn-title {
  font-size: 16px;
  font-weight: 900;
}
.ww-mainmenu__btn-meta {
  font-size: 11px;
  font-weight: 700;
  opacity: 0.7;
}

/* Responsive: em tela estreita, leaderboard vai embaixo. */
@media (max-width: 820px) {
  .ww-mainmenu__inner {
    grid-template-columns: 1fr;
    max-width: 540px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   Weather overlay — DESATIVADO VISUALMENTE (ficou feio).
   ───────────────────────────────────────────────────────────────────────
   O sistema (WeatherManager em core/weather.js, evento WEATHER_CHANGED,
   ctx.weather/ctx.weatherIntensity) continua rodando e ativo — só a
   camada visual está suprimida. Pra reabilitar, descomentar o bloco
   abaixo e reiterar no visual (possivelmente trocar a abordagem de
   textura de ruído tiled + mix-blend por algo mais atmosférico).
═══════════════════════════════════════════════════════════════════════ */

.ww-weather { display: none; }

/*
.ww-weather {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 12;
  background-image: url('../../public/textures/noise-75.png');
  background-repeat: repeat;
  background-size: 75px 75px;
  opacity: calc(var(--ww-weather-intensity, 0) * var(--ww-weather-max, 0));
  transition: opacity 0.8s ease;
  mix-blend-mode: multiply;
  will-change: background-position, opacity;
}
@keyframes ww-weather-drift {
  from { background-position: 0 0; }
  to   { background-position: 300px 120px; }
}
.ww-weather--haze {
  --ww-weather-max: 0.45;
  background-color: rgba(230, 180, 90, 0.3);
  animation: ww-weather-drift 60s linear infinite;
}
.ww-weather--fog-light {
  --ww-weather-max: 0.55;
  background-color: rgba(220, 220, 230, 0.55);
  animation: ww-weather-drift 45s linear infinite;
}
.ww-weather--fog-dense {
  --ww-weather-max: 0.85;
  background-color: rgba(180, 190, 205, 0.75);
  animation: ww-weather-drift 30s linear infinite;
  filter: blur(1.5px);
}
.ww-weather--dust {
  --ww-weather-max: 0.55;
  background-color: rgba(200, 150, 80, 0.55);
  animation: ww-weather-drift 18s linear infinite;
}
*/

/* ═══════════════════════════════════════════════════════════════════════
   GUIDE — Oto, personagem do canto inferior direito
   Fora do mundo: position fixed, sem pan/zoom.
═══════════════════════════════════════════════════════════════════════ */
.ww-guide {
  position: fixed;
  /* Posição vem do JS (left/top + transform translate(-50%,-50%) pra centralizar).
     CSS legado de right/bottom removido — tudo passa pelo pose dinâmico agora.
     Sem transition aqui: pose muda discretamente entre steps do act, e o tilt
     do mouse-proximity precisa ser instantâneo a cada frame (já é interpolado
     em JS via TILT_LERP). Transições suaves entre poses ficam pra Fase 2. */
  left: 0;
  top: 0;
  pointer-events: none;
  z-index: 50;
  font-family: var(--ww-font-body);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  will-change: transform;
}
.ww-guide__figure {
  /* Width/height definidos via JS de acordo com o aspect-ratio do FRAME
     (não da sheet inteira). Background-image + background-position fazem
     o "recorte" do frame ativo — ver GuideRenderer._mountFigure.
     Transform aqui (scale/rotation do pose) é animado via inline transition
     setado pelo JS — não definir transition aqui pra não conflitar. */
  pointer-events: auto;
  position: relative;
  transform-origin: 50% 100%;   /* base do personagem — escala pra cima sem afundar */
  will-change: transform;
}
/* Fallback sem sprite: emoji solto, sem moldura. Oto não é carta. */
.ww-guide__emoji {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  font-size: 96px;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}
.ww-guide__bubble {
  position: absolute;
  right: 110px;
  bottom: 110px;
  max-width: 260px;
  min-width: 120px;
  padding: 10px 12px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 200ms ease, transform 200ms ease;
}
.ww-guide__bubble.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.ww-guide__bubble.is-fading {
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 280ms ease, transform 280ms ease;
}
.ww-guide__bubble::after {
  /* Triângulo apontando pro Oto (canto inferior direito do balão). */
  content: '';
  position: absolute;
  right: -10px;
  bottom: 14px;
  width: 0;
  height: 0;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  border-left: 12px solid var(--ww-surface-raised);
  filter: drop-shadow(2px 0 0 var(--ww-line));
}
.ww-guide__bubble-text {
  white-space: pre-wrap;
  line-height: 1.35;
}
.ww-guide--muted .ww-guide__figure { opacity: 0.45; }
.ww-guide--muted .ww-guide__bubble { display: none; }

/* Botões "no tutos please" + "next" no balão do Oto durante o tour.
   Compõe sobre .ww-button já existente. pointer-events: auto pra
   reverter o pai (.ww-guide__bubble é pointer-events:none por padrão). */
.ww-guide__bubble-actions {
  margin-top: 10px;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  pointer-events: auto;
}
.ww-guide__bubble-tour-btn {
  white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════
   TOUR OVERLAY — escurece a tela e destaca um alvo (HUD ou carta).
   Buraco: box-shadow inset gigante pinta só o "fora" do hole.
   Hole em si tem outline accent + cor sunken pra ler como "olha aqui".
═══════════════════════════════════════════════════════════════════════ */
.ww-tour-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 49;   /* abaixo do Oto (z-50) e da Store modal (z varia), acima do HUD (z-20) */
}
.ww-tour-overlay__hole {
  position: absolute;
  /* Sombra inset gigante = pinta o "fora" do hole de preto translúcido.
     Vector enorme garante que cobre qualquer viewport. */
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.55);
  border: 3px solid var(--ww-accent);
  border-radius: var(--ww-radius);
  transition: left 200ms ease, top 200ms ease, width 200ms ease, height 200ms ease;
  pointer-events: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   CARD SPEECH BUBBLE — qualquer carta pode falar via Speech.say()
   Ancorado no .ww-card (filho absoluto), segue a carta de graça via
   transform CSS herdado. Centralizado em cima, triângulo apontando pra baixo.
═══════════════════════════════════════════════════════════════════════ */
.ww-card-speech__bubble {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 12px);
  transform: translate(-50%, 4px);
  max-width: 200px;
  min-width: 60px;
  padding: 8px 10px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease, transform 200ms ease;
  white-space: pre-wrap;
  z-index: 50;
}
.ww-card-speech__bubble.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}
.ww-card-speech__bubble.is-fading {
  opacity: 0;
  transform: translate(-50%, -2px);
  transition: opacity 280ms ease, transform 280ms ease;
}
.ww-card-speech__bubble::after {
  /* Triângulo apontando pra baixo (pra carta). */
  content: '';
  position: absolute;
  left: 50%;
  bottom: -10px;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 12px solid var(--ww-surface-raised);
  filter: drop-shadow(0 2px 0 var(--ww-line));
}
.ww-card-speech__text {
  white-space: pre-wrap;
  line-height: 1.3;
  font-size: 13px;
  text-align: center;
}

/* ═══════════════════════════════════════════════════════════════════════
   STORE — loja "em obras" (openAt > Context.day)
═══════════════════════════════════════════════════════════════════════ */
.ww-card--unopened .ww-card__inner {
  filter: grayscale(0.85) brightness(0.85);
}
.ww-card--unopened .ww-card__inner::after {
  /* listras diagonais "em obras" */
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    45deg,
    rgba(0,0,0,0.0) 0 8px,
    rgba(0,0,0,0.18) 8px 14px
  );
  border-radius: var(--ww-card-radius);
  z-index: 5;
}
/* Faixa diagonal "opens in N days" — atravessa a carta na diagonal,
   estilo fita de etiqueta. Pseudo-bordas pretas no topo/base reforçam
   leitura de "fita aplicada por cima". Pointer-events off — não bloqueia
   click/hover. Largura 200% pra garantir que cubra a carta toda mesmo com
   rotação (as pontas vão pra fora e ficam escondidas pelo overflow:hidden
   do __inner). */
.ww-card__unopened-label {
  position: absolute;
  left: -50%;
  right: -50%;
  top: 50%;
  transform: translateY(-50%) rotate(-22deg);
  transform-origin: center center;
  font-family: var(--ww-font-display);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.3px;
  text-align: center;
  color: var(--ww-surface-raised);
  background: var(--ww-line);
  padding: 4px 0;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  border-top: 1.5px solid rgba(0,0,0,0.35);
  border-bottom: 1.5px solid rgba(0,0,0,0.35);
  box-shadow: 0 2px 0 rgba(0,0,0,0.2);
  z-index: 6;
}
@keyframes ww-card-locked-blip {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0); }
  20% { transform: translate3d(-3px, 0, 0) rotate(-1deg); }
  60% { transform: translate3d(3px, 0, 0) rotate(1deg); }
}
.ww-card--locked-blip .ww-card__inner {
  animation: ww-card-locked-blip 0.45s ease-in-out;
}

/* ═══════════════════════════════════════════════════════════════════════
   NEWSPAPER — carta jornal "stale" (não lida no dia anterior) e modal
═══════════════════════════════════════════════════════════════════════ */
.ww-card--stale .ww-card__inner {
  filter: sepia(0.65) contrast(0.9);
  opacity: 0.78;
}

.ww-newspaper-modal__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(17, 17, 17, 0.5);
  z-index: 90;
}
.ww-newspaper-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
}
.ww-newspaper-modal__frame {
  width: min(640px, 92vw);
  max-height: 86vh;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 22px 26px;
}
.ww-newspaper-modal__masthead {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-bottom: var(--ww-line-width) solid var(--ww-line);
  padding-bottom: 10px;
}
.ww-newspaper-modal__lead {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--ww-text-muted);
}
.ww-newspaper-modal__headline {
  font-family: var(--ww-font-display);
  font-weight: 900;
  font-size: 28px;
  line-height: 1.15;
  color: var(--ww-text-primary);
}
.ww-newspaper-modal__sub-headline {
  font-family: var(--ww-font-display);
  font-weight: 800;
  font-size: 18px;
  line-height: 1.2;
  color: var(--ww-text-primary);
}
.ww-newspaper-modal__body {
  line-height: 1.5;
}
.ww-newspaper-modal__rest {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ww-newspaper-modal__secondary {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 0;
  border-top: 1px solid var(--ww-text-muted);
}
.ww-newspaper-modal__effects {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-top: 6px;
}
.ww-newspaper-modal__effect {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ww-text-secondary, var(--ww-text-primary));
  background: rgba(0, 0, 0, 0.04);
  padding: 3px 8px;
  border-radius: 6px;
}
.ww-newspaper-modal__effect-icon {
  font-size: 15px;
  line-height: 1;
}
.ww-newspaper-modal__market {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--ww-text-muted);
}
.ww-newspaper-modal__swings {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
}
.ww-newspaper-modal__swing-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 12px;
  padding: 4px 8px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  background: rgba(0, 0, 0, 0.03);
  border-radius: 4px;
}
.ww-newspaper-modal__swing-label {
  color: var(--ww-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ww-newspaper-modal__swing-delta {
  font-weight: 700;
  letter-spacing: 0.02em;
}
.ww-newspaper-modal__swing-price {
  color: var(--ww-text-muted);
  min-width: 48px;
  text-align: right;
}
.ww-newspaper-modal__swing--up .ww-newspaper-modal__swing-delta {
  color: #2e7d32;
}
.ww-newspaper-modal__swing--down .ww-newspaper-modal__swing-delta {
  color: #c62828;
}
.ww-newspaper-modal__footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 4px;
}

