/* ============================================
   RESET E BASE
   ============================================ */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* scrollbar-gutter:stable evita o descompasso entre unidades vw e % que a
   técnica de "full bleed" da sidebar da Home usa (calc(-50vw + 50%) em
   .home-body-row, mais abaixo) — sem isso, vw conta a faixa da barra de
   rolagem e % não, deixando a sidebar uns pixels pra fora da tela em
   páginas altas o bastante pra ter barra de rolagem de verdade. */
html {
    scrollbar-gutter: stable;
}

body {
    font-family: 'Inter', sans-serif;
    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
    color: #e0e0e0;
    min-height: 100vh;
}

/* ============================================
   HEADER
   ============================================ */
.header {
    background: rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(10px);
    padding: 1rem 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.logo {
    font-size: 1.5rem;
    font-weight: 700;
    color: #ff6b9d;
    text-shadow: 0 0 20px rgba(255, 107, 157, 0.3);
}

.nav {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    /* Antes tinha overflow-x:auto (rolagem horizontal) pra caber os 12+
       botões que existiam antes do header ser reorganizado em dropdowns
       (Coleção/Ferramentas/Conta) — removido de propósito: overflow-x
       diferente de "visible" força o eixo Y a virar clipping context
       também (regra do CSS, não dá pra ter só um eixo rolando), o que
       CORTAVA o painel dos dropdowns novos (position:absolute, abre pra
       baixo do gatilho) — bug real reportado pelo dono do projeto: o menu
       "abria" (classe .open aplicada certinha) mas ficava invisível.
       Com bem menos botões soltos agora, flex-wrap resolve os dois
       problemas de uma vez: sem corte no dropdown, e sem rolagem
       escondida (que ninguém percebia que existia). */
    flex-wrap: wrap;
    max-width: 100%;
}

.nav-btn, .header-select, .nav .login-btn, .nav .logout-btn {
    flex-shrink: 0;
}

.nav-btn {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: #d8d8e6;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
    font-size: 0.85rem;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.nav-btn:hover {
    background: rgba(255, 107, 157, 0.12);
    border-color: #ff6b9d;
    color: white;
    transform: translateY(-1px);
}

.nav-btn.active {
    background: linear-gradient(135deg, #ff6b9d, #c44569);
    border-color: transparent;
    color: white;
    font-weight: 600;
    box-shadow: 0 3px 12px rgba(255, 107, 157, 0.35);
}

/* Botão só-ícone (sino de notificações) — mesma pílula, sem texto,
   deixa espaço reservado pro badge de não-lidas no canto. */
.nav-icon-btn {
    padding: 0.5rem 0.75rem;
    position: relative;
    font-size: 1rem;
}

.nav-divider {
    width: 1px;
    height: 22px;
    background: rgba(255, 255, 255, 0.15);
    flex-shrink: 0;
    margin: 0 0.2rem;
}

/* ============================================
   DROPDOWNS DO HEADER — agrupa itens relacionados (Coleção/Ferramentas/
   Conta) atrás de um gatilho só, em vez de uma pílula por página (o header
   tinha crescido pra 12+ botões numa fileira só rolável — ver
   toggleNavDropdown/markActiveNav em app-core.js pro comportamento).
   ============================================ */
.nav-dropdown {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
}

.nav-caret {
    font-size: 0.65em;
    margin-left: 1px;
    transition: transform 0.2s ease;
    display: inline-block;
}

.nav-dropdown.open .nav-caret { transform: rotate(180deg); }

.nav-dropdown-panel {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    min-width: 210px;
    background: rgba(15, 23, 42, 0.98);
    backdrop-filter: blur(14px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 200;
}

.nav-dropdown.open .nav-dropdown-panel {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

/* "Conta" mora na ponta direita do header — abrir o painel alinhado à
   esquerda (padrão) faria ele estourar pra fora da tela em telas
   estreitas, por isso essa variante alinha pela direita. */
.nav-dropdown-right .nav-dropdown-panel {
    left: auto;
    right: 0;
}

.nav-dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.6rem 0.8rem;
    border-radius: 9px;
    color: #d8d8e6;
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    white-space: nowrap;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
    width: 100%;
    font-family: inherit;
}

.nav-dropdown-item:hover {
    background: rgba(255, 107, 157, 0.14);
    color: white;
}

.nav-dropdown-item.active {
    background: linear-gradient(135deg, #ff6b9d, #c44569);
    color: white;
    font-weight: 600;
}

.nav-dropdown-item-danger { color: #ff8a7a; }
.nav-dropdown-item-danger:hover {
    background: rgba(231, 76, 60, 0.18);
    color: #ffb3a3;
}

.login-btn {
    background: #4ecdc4;
    border-color: #4ecdc4;
    color: #1a1a2e;
    font-weight: 700;
}

.login-btn:hover {
    background: #5fe0d6;
    border-color: #5fe0d6;
    color: #1a1a2e;
}

.logout-btn {
    background: rgba(231, 76, 60, 0.15);
    border-color: rgba(231, 76, 60, 0.5);
    color: #ff8a7a;
}

.logout-btn:hover {
    background: #e74c3c;
    border-color: #e74c3c;
    color: white;
}

/* ============================================
   MENU MOBILE (hambúrguer) — abaixo de 900px o .nav vira um painel
   deslizante (da direita) em vez de ficar inline no header; acima disso,
   tudo continua exatamente como já era (essas regras só existem DENTRO do
   @media lá embaixo). O botão-hambúrguer e o backdrop escurecido só fazem
   sentido nesse modo, por isso ficam com display:none por padrão.
   ============================================ */
.nav-hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 4px;
    width: 42px;
    height: 42px;
    padding: 0;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    cursor: pointer;
    flex-shrink: 0;
}

.nav-hamburger-bar {
    display: block;
    width: 20px;
    height: 2px;
    border-radius: 2px;
    background: #e0e0e0;
    transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Vira um "✕" quando o menu está aberto — mesmo botão, sem precisar de um
   ícone separado (o aria-expanded/estado vem de toggleMobileNav() em
   app-core.js). */
.nav-hamburger[aria-expanded="true"] .nav-hamburger-bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-hamburger[aria-expanded="true"] .nav-hamburger-bar:nth-child(2) { opacity: 0; }
.nav-hamburger[aria-expanded="true"] .nav-hamburger-bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav-backdrop {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* height, não bottom:0 — mesmo motivo do .nav logo abaixo (.header
       com backdrop-filter vira containing block do fixed). */
    height: 100vh;
    height: 100dvh;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
    z-index: 190;
}

.nav-mobile-header { display: none; }

/* ============================================
   PÁGINAS
   ============================================ */
.page {
    display: none;
    padding: 2rem;
    max-width: 1400px;
    margin: 0 auto;
}

.page.active {
    display: block;
}

/* ============================================
   HERO
   ============================================ */
.hero {
    text-align: center;
    padding: 1.2rem 1rem 3rem;
}

.hero-logo {
    max-width: 420px;
    width: 80%;
    height: auto;
    margin-bottom: 0.8rem;
    filter: drop-shadow(0 0 24px rgba(255, 107, 157, 0.35));
}

.hero p {
    color: #a0a0a0;
    font-size: 1.1rem;
    margin-bottom: 2rem;
}

/* ============================================
   AVISO DO APP ANDROID — banner "em breve" (não publicado ainda). Trocar
   pelo link real da Play Store quando o app for lançado (ver comentário
   junto ao HTML, em index.html).
   ============================================ */
.android-banner {
    display: flex;
    align-items: center;
    gap: 1rem;
    max-width: 700px;
    margin: 0 auto 2rem;
    padding: 1rem 1.4rem;
    background: linear-gradient(90deg, rgba(78, 205, 196, 0.12), rgba(255, 107, 157, 0.12));
    border: 1px solid rgba(78, 205, 196, 0.3);
    border-radius: 16px;
}

.android-banner-icon {
    font-size: 1.8rem;
    flex-shrink: 0;
}

.android-banner-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    text-align: left;
    flex: 1;
    min-width: 0;
}

.android-banner-text strong {
    color: white;
    font-size: 0.9rem;
}

.android-banner-text span {
    color: #a0a0a0;
    font-size: 0.78rem;
}

.android-banner-badge {
    flex-shrink: 0;
    background: #4ecdc4;
    color: #1a1a2e;
    font-weight: 700;
    font-size: 0.7rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

@media (max-width: 600px) {
    .android-banner { flex-wrap: wrap; text-align: center; }
    .android-banner-text { text-align: center; }
}

.stats {
    display: flex;
    justify-content: center;
    gap: 2rem;
    margin-top: 2rem;
}

.stat-card {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 16px;
    padding: 1.5rem 2.5rem;
    text-align: center;
}

.stat-number {
    font-size: 2.5rem;
    font-weight: 700;
    color: #4ecdc4;
}

.stat-label {
    color: #a0a0a0;
    font-size: 0.9rem;
    margin-top: 0.3rem;
}

/* ============================================
   BUSCA
   ============================================ */
.search-section {
    max-width: 600px;
    margin: 0 auto 2rem;
    padding: 0 1rem;
}

/* Filtros que aparecem só com resultado de busca (searchCards(),
   app-sets.js) — mesmos componentes de Minha Coleção (.header-select de
   set + chips de raridade clicáveis), só empilhados em coluna e
   centralizados aqui porque a busca da Home é uma caixa isolada, não uma
   barra de ferramentas com vários controles lado a lado. */
.search-filters {
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.7rem;
}
.search-filters .header-select { margin-left: 0; }
.search-filters .profile-chip-row { justify-content: center; }

#search-input, #cards-search-input, #collection-search-input {
    width: 100%;
    padding: 1rem 1.5rem;
    border-radius: 50px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.05);
    color: white;
    font-size: 1rem;
    outline: none;
    transition: all 0.3s;
}

#search-input:focus, #cards-search-input:focus {
    border-color: #ff6b9d;
    box-shadow: 0 0 20px rgba(255, 107, 157, 0.2);
}

#search-input::placeholder, #cards-search-input::placeholder {
    color: #666;
}

/* ============================================
   TÍTULOS DE SEÇÃO
   ============================================ */
.section-title {
    margin: 2rem 0 1rem;
}

.section-title h2 {
    font-size: 1.5rem;
    color: #ff6b9d;
}

.section-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 2rem;
}

.back-btn {
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.3s;
}

.back-btn:hover {
    background: rgba(255, 255, 255, 0.2);
}

/* Capa do set na página de um set (/colecoes/{set_code}), ao lado do
   nome — mesmo resolveSetCoverPath() já usado na grade da Home
   (i18n.js). onerror já esconde a tag se o set não tiver capa própria
   (mesmo fallback gracioso de qualquer outra capa de set no site). */
.set-header-cover {
    width: 48px;
    height: 48px;
    border-radius: 10px;
    object-fit: cover;
    border: 1px solid rgba(255, 255, 255, 0.15);
    flex-shrink: 0;
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease;
}
.set-header-cover:hover { transform: scale(1.06); border-color: #ff6b9d; }

/* Modal da capa do set (aberto por openSetCoverModal(), clique na
   .set-header-cover acima) — imagem grande + o mesmo .set-info-panel de
   sempre, só que dentro do modal em vez de solto na página. */
.set-cover-modal-content {
    max-width: 480px;
    text-align: center;
}
.set-cover-modal-img {
    width: 100%;
    max-width: 320px;
    border-radius: 14px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    margin: 0 auto 1.2rem;
    display: block;
}

/* Painel de informações da caixa/booster — ver renderSetInfoPanel em
   app-sets.js. Grid pra quebrar linha sozinho em telas estreitas, sem
   precisar de media query. */
.set-info-panel {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0.75rem;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 14px;
    padding: 1rem 1.2rem;
    text-align: left;
}

.set-info-item {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.set-info-label {
    font-size: 0.75rem;
    color: #888;
}

.set-info-value {
    font-size: 0.95rem;
    font-weight: 600;
    color: white;
}

/* "Sem info." em itálico e mais apagado — deixa claro que é falta de
   dado, não um valor de verdade tipo "0". */
.set-info-value.set-info-empty {
    font-style: italic;
    font-weight: 500;
    color: #666;
}

/* ============================================
   GRID DE SETS — grade fixa de 6 colunas (a Home é a única página que
   lista sets agora; a antiga página "Todos os Sets" foi removida por ser
   quase idêntica). Padding/gap enxutos pra caber mais coisa na tela sem
   parecer vazio, com capas quadradas (ver .set-cover mais abaixo).
   ============================================ */
.sets-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 0.5rem;
}

/* Divisões por família de coleção (NS - 1 Yuan, NS - 2 Yuan...), mesmo
   agrupamento do app — estilo "cabeçalho + total" ao invés de uma grade
   única com dezenas de sets soltos. */
.set-group {
    margin-bottom: 1.8rem;
}

.set-group-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 0.7rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.set-group-title {
    font-size: 1.1rem;
    font-weight: 700;
    color: #e0e0e0;
}

.set-group-total {
    font-size: 0.8rem;
    color: #888;
}

@media (max-width: 1100px) {
    .sets-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 700px) {
    .sets-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 420px) {
    .sets-grid { grid-template-columns: repeat(2, 1fr); }
}

.set-card {
    /* Era um <a> sem text-decoration/color próprios — herdava o
       sublinhado azul padrão do navegador em todo o texto de dentro
       (mais visível na data, por ser a linha mais fina/clara). */
    position: relative;
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
    background: linear-gradient(160deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    padding: 0.45rem;
    cursor: pointer;
    text-align: center;
    transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), border-color 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}

/* Estrela de favorito — canto superior direito do set-card, por cima da
   capa (ver loadSets()/_toggleFavoriteSet em app-sets.js). z-index acima
   da <img> de capa (que não tem z-index próprio, então qualquer valor
   positivo já basta). */
.set-favorite-btn {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 2;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, 0.55);
    color: #8b90b3;
    font-size: 1rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.set-favorite-btn:hover {
    transform: scale(1.15);
    background: rgba(0, 0, 0, 0.75);
}
.set-favorite-btn-active {
    color: #f2c14e;
    text-shadow: 0 0 8px rgba(242, 193, 78, 0.7);
}

.set-card:hover {
    transform: translateY(-5px);
    border-color: #ff6b9d;
    background: linear-gradient(160deg, rgba(255, 107, 157, 0.1), rgba(255, 255, 255, 0.03));
    box-shadow: 0 10px 26px rgba(255, 107, 157, 0.22), 0 0 0 1px rgba(255, 107, 157, 0.15) inset;
}

.set-card:active {
    transform: translateY(-2px);
    transition-duration: 0.1s;
}

.set-code {
    font-size: 0.88rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: #4ecdc4;
    margin-bottom: 0.3rem;
    text-shadow: 0 0 14px rgba(78, 205, 196, 0.25);
}

.set-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    color: #c4c4d8;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 999px;
    padding: 0.12rem 0.5rem;
    margin: 0 auto;
    font-size: 0.66rem;
    font-weight: 600;
}

.set-count::before {
    content: '🎴';
    font-size: 0.7rem;
    line-height: 1;
}

.set-date {
    color: #75758c;
    font-size: 0.62rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    margin-top: 0.3rem;
}

/* ============================================
   GRID DE CARTAS
   ============================================ */
.cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 1.5rem;
}

.card-item {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 16px;
    overflow: hidden;
    cursor: pointer;
    transition: all 0.3s;
    position: relative;
}

.card-item:hover {
    transform: scale(1.03);
    border-color: #ff6b9d;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

.card-image {
    width: 100%;
    aspect-ratio: 3/4;
    object-fit: cover;
    background: linear-gradient(135deg, #2a2a4a, #1a1a2e);
}

.card-image.error {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #666;
    font-size: 0.8rem;
}

/* Botão "+" de catalogação rápida (ver quickAddToCollection em
   app-sets.js) — canto superior direito da imagem, só aparece logado. */
/* Marca de "já possui" na grade de um set — canto superior ESQUERDO de
   propósito, pra não brigar com .card-quick-add-btn (canto direito). Mesma
   ideia visual (✓ verde) já usada no app na grade de um set. */
/* Destaque no perfil público (ver highlightMissing em renderCards,
   app-sets.js) — carta que o DONO do perfil tem mas quem está vendo ainda
   não, útil pra achar oportunidade de troca. Laranja de propósito, pra
   não confundir com o rosa de hover/+ nem com o verde de "você já tem"
   (.card-owned-badge). */
.card-item-missing {
    border: 2px solid #ff9800;
    box-shadow: 0 0 14px rgba(255, 152, 0, 0.4);
}

/* Carta na MINHA lista de desejos, vista no perfil de outra pessoa (ver
   highlightMissing em renderCards, app-sets.js) — roxo de propósito
   (mesmo tom do efeito "Refração Holográfica" já usado no app,
   RARITY_EFFECTS em pricing.py, #B565F5), pra não confundir com o laranja
   de "você não tem" acima nem com nenhuma outra cor já em uso aqui. Vem
   DEPOIS de .card-item-missing no arquivo de propósito — as duas podem
   coexistir na mesma carta (a pessoa tem uma carta que eu quero e ainda
   não tenho), e nesse caso o roxo é a informação mais acionável, então
   ganha visualmente. */
.card-item-wishlisted {
    border: 2px solid #b565f5;
    box-shadow: 0 0 14px rgba(181, 101, 245, 0.5);
}

.card-owned-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    min-width: 24px;
    height: 24px;
    padding: 0 6px;
    border-radius: 12px;
    background: #2ecc71;
    color: white;
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 6;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.card-quick-add-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(255, 107, 157, 0.92);
    color: white;
    border: none;
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 6;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    transition: transform 0.15s ease, background 0.15s ease;
}

.card-quick-add-btn:hover {
    background: #ff6b9d;
    transform: scale(1.12);
}

/* "-" logo abaixo do "+" (ver quickDecHTML em app-sets.js) — mesma família
   visual do "+" (ação rápida de quantidade, não é destrutiva como a
   lixeira), só que num tom mais neutro pra não competir com ele. Só
   aparece com 2+ cópias possuídas. */
.card-quick-dec-btn {
    position: absolute;
    top: 42px;
    right: 8px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(90, 100, 130, 0.85);
    color: white;
    border: none;
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 6;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    transition: transform 0.15s ease, background 0.15s ease;
}

.card-quick-dec-btn:hover {
    background: rgba(120, 130, 160, 0.95);
    transform: scale(1.12);
}

/* Wrapper só da imagem (não do card-item inteiro) — necessário pra "canto
   inferior" das duas ações abaixo alinhar com a BASE DA IMAGEM, e não com
   o fim do bloco de texto (.card-info) que vem depois. Sem isso, `bottom:
   8px` cairia em cima do preço. Não muda nada visualmente pros badges já
   existentes (✓/+), que continuam no topo. */
.card-image-wrap {
    position: relative;
}

/* Lixeira — canto inferior DIREITO da imagem, só aparece na carta que o
   usuário já tem (ver ownedCollectionIds em renderCards/loadSetProgress,
   app-sets.js). Remove a carta inteira da coleção (todas as condições
   cadastradas dela), não só decrementa 1 — ação simétrica ao "+" de
   catalogar rápido. */
.card-remove-btn {
    position: absolute;
    bottom: 8px;
    right: 8px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(231, 76, 60, 0.92);
    color: white;
    border: none;
    font-size: 1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 6;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    transition: transform 0.15s ease, background 0.15s ease;
}

.card-remove-btn:hover {
    background: #e74c3c;
    transform: scale(1.12);
}

/* Coração — canto inferior ESQUERDO da imagem, adiciona à lista de
   desejos direto da grade (mesma ideia do "+" de coleção, só que pra
   desejos). Sempre visível logado, mesmo em carta que o usuário já tem —
   desejo e coleção são listas independentes. */
.card-wishlist-btn {
    position: absolute;
    bottom: 8px;
    left: 8px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(255, 79, 129, 0.92);
    color: white;
    border: none;
    font-size: 1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 6;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    transition: transform 0.15s ease, background 0.15s ease;
}

.card-wishlist-btn:hover {
    background: #ff4f81;
    transform: scale(1.12);
}

/* Já está na lista de desejos (toque remove em vez de adicionar, ver
   toggleQuickWishlist em app-sets.js) — o próprio emoji já muda (🤍→💜),
   esse glow é só reforço visual extra, mesma ideia do .card-owned-badge. */
.card-wishlist-btn-active {
    box-shadow: 0 0 10px rgba(255, 79, 129, 0.85), 0 2px 8px rgba(0, 0, 0, 0.4);
}

.card-info {
    padding: 1rem;
}

/* ============================================
   GATE DE CONTEÚDO NSFW — carta sempre aparece na grade (não some), só
   com a imagem borrada; nome/anime/raridade/preço aparecem normais
   desde o início. Clicar abre o detalhe normalmente — a imagem lá
   também continua borrada (ver app-card-detail.js), só o toggle
   global em Perfil desborra ela. Ver applyNsfwBlur() em app-core.js.
   ============================================ */
.card-image-nsfw-blur {
    filter: blur(18px) saturate(0.7);
    transform: scale(1.08); /* esconde a borda nítida que vazaria na beirada do blur */
}

.card-number {
    font-size: 0.8rem;
    color: #666;
    margin-bottom: 0.3rem;
}

/* Linha código+raridade lado a lado (ver renderCards, app-sets.js) — só
   quando o card vem envolto nesse wrapper; sem ele (Coleção/Desejos, que
   montam o próprio HTML e continuam usando .card-number sozinho, raridade
   noutro lugar do card) nada muda. Zera o margin-bottom do .card-number
   aqui dentro pra não empurrar a raridade pra baixo do código — a margem
   vai pro wrapper inteiro. */
.card-number-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.3rem;
}

.card-number-row .card-number {
    margin-bottom: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card-number-row .card-rarity {
    flex-shrink: 0;
}

.card-name {
    font-weight: 600;
    color: white;
    font-size: 0.95rem;
    margin-bottom: 0.3rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card-anime {
    font-size: 0.8rem;
    color: #888;
    margin-bottom: 0.5rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card-rarity {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border-radius: 20px;
    font-size: 0.75rem;
    font-weight: 600;
}

.rarity-SSR { background: #ffd700; color: #333; }
.rarity-UR { background: #9b59b6; color: white; }
.rarity-SR { background: #3498db; color: white; }
.rarity-R { background: #95a5a6; color: #333; }
.rarity-SP { background: #e74c3c; color: white; }
.rarity-SEC { background: #1abc9c; color: white; }
.rarity-PR { background: #ff6b9d; color: white; }
.rarity-default { background: #666; color: white; }

.card-price {
    margin-top: 0.5rem;
    font-weight: 700;
    color: #4ecdc4;
}

/* Segunda linha de preço (waifucards) na Coleção — mesma cor usada pra
   esse preço no modal de detalhe (app-card-detail.js), fonte menor pra
   ficar claramente secundária ao preço base. */
.card-price-wc {
    margin-top: 0.2rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: #ff6b9d;
}

/* ============================================
   COLEÇÃO
   ============================================ */
/* Toolbar única (stats + busca + filtro) — antes eram 3 blocos com
   alinhamentos diferentes entre si (stats começando na margem esquerda,
   busca centralizada com max-width próprio, filtro colado no título) e
   sem nada em comum visualmente. Agora tudo mora na mesma barra, mesma
   altura, mesma borda. */
/* Empilhado (flex-direction:column) de propósito, não lado a lado — cartas/
   valores sempre numa linha própria em cima, filtros numa linha própria
   embaixo (ver o canvas de design aprovado: 3 opções de reformulação do
   filtro de raridade, "Opção 2" escolhida). Lado a lado com wrap parecia
   consistente só em algumas larguras; empilhado é sempre a mesma
   estrutura, não importa o tamanho da tela. */
.collection-toolbar {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 0.9rem 1.2rem;
    margin-bottom: 1.5rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 16px;
}

.collection-toolbar-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 1.6rem;
}

.mini-stat {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.mini-stat-value {
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--pv-accent2);
    line-height: 1.1;
}
/* Mesma cor do preço waifucards por carta (.card-price-wc), pra ficar
   claro que esse total é o waifucards, não o base. */
.mini-stat-value-wc {
    color: #ff6b9d;
}
.mini-stat-label {
    font-size: 0.7rem;
    color: var(--pv-text-dim);
}

.collection-toolbar-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.7rem;
}

/* Mesma altura pro campo de busca e pro <select> de filtro — dois
   elementos nativos diferentes (input vs select) nunca batem de altura
   sozinhos mesmo com o mesmo CSS, mesmo problema já corrigido na
   Calculadora de ROI (ver .roi-config-row select/input). */
.collection-search-input,
.collection-toolbar-controls .header-select {
    height: 40px;
    box-sizing: border-box;
    margin-left: 0;
}

.collection-wc-price-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: var(--pv-text-dim);
    white-space: nowrap;
    cursor: pointer;
}
.collection-wc-price-toggle input {
    cursor: pointer;
}

.home-favorite-sets-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--pv-text-dim);
    white-space: nowrap;
    cursor: pointer;
}
.home-favorite-sets-toggle input {
    cursor: pointer;
}

/* Especificidade extra (2 classes) de propósito: .btn-google (mais abaixo
   no arquivo, width:100%) tem a MESMA especificidade de ".collection-
   clear-filters-btn" sozinha — empatado, ganha quem vem depois no arquivo
   (.btn-google), anulando esse width:auto e esticando o botão pra ocupar
   a linha inteira quando ele quebra sozinho (ver .collection-toolbar-
   controls, flex-wrap). Prefixar com o pai evita depender de ordem. */
.collection-toolbar-controls .collection-clear-filters-btn {
    width: auto;
    height: 40px;
    padding: 0 1rem;
    font-size: 0.82rem;
    white-space: nowrap;
    margin-left: auto;
}

/* Barra "Raridade" recolhível (ver toggleCollectionRarityPanel em
   app-collection.js) — linha própria automaticamente, .collection-toolbar
   agora é flex-direction:column (ver acima), sem precisar de flex-basis. */
.collection-toolbar .collection-rarity-bar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.8rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--pv-border);
    border-radius: 10px;
    cursor: pointer;
}
.collection-rarity-label {
    color: var(--pv-text);
    font-weight: 600;
    font-size: 0.85rem;
}
.collection-rarity-summary {
    font-family: monospace;
    font-weight: 700;
    font-size: 0.85rem;
    color: var(--pv-text-dim);
}
.collection-rarity-clear {
    color: var(--pv-text-dim);
    font-size: 0.75rem;
    text-decoration: underline;
    margin-left: -0.2rem;
}
.collection-rarity-clear:hover { color: var(--pv-text); }
.collection-rarity-chevron {
    margin-left: auto;
    color: var(--pv-text-dim);
    transition: transform 0.15s ease;
    flex-shrink: 0;
}
.collection-rarity-chevron-expanded { transform: rotate(180deg); }

/* Chips de raridade (ver #collection-rarity-chips em colecao.body.html) —
   linha própria automaticamente (.collection-toolbar é flex-direction:
   column, com gap cuidando do espaçamento). Só visível expandido (ver
   renderCollectionRarityChips), com seleção múltipla — mais de um chip
   pode ficar ativo ao mesmo tempo. */
.collection-rarity-chip-active {
    box-shadow: 0 0 8px currentColor;
    font-weight: 800 !important;
}

.collection-search-input {
    flex: 1;
    min-width: 160px;
    max-width: 360px;
    padding: 0 1rem;
    border-radius: 10px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.05);
    color: var(--pv-text);
    font-size: 0.88rem;
    outline: none;
    transition: border-color 0.2s ease;
}
.collection-search-input:focus { border-color: var(--pv-accent2); }
.collection-search-input::placeholder { color: var(--pv-text-dim); }

@media (max-width: 700px) {
    .collection-search-input { max-width: none; }
}

.collection-card .card-quantity {
    position: absolute;
    top: 10px;
    right: 10px;
    background: #ff6b9d;
    color: white;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.9rem;
}

.collection-card .card-condition {
    position: absolute;
    top: 10px;
    left: 10px;
    background: rgba(0,0,0,0.7);
    color: #4ecdc4;
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
    font-size: 0.75rem;
    font-weight: 600;
}

/* "-" logo abaixo do selo de quantidade (.card-quantity acima) — mesma
   ideia da grade de um set (.card-quick-dec-btn em app-sets.js), só que
   aqui reduz a quantidade de uma carta que já está na coleção. Só existe
   no HTML (ver quickDecBtnHTML, app-collection.js) com 2+ cópias — sem
   "+" de propósito aqui (pedido do dono do projeto). */
.collection-card .card-qty-dec-btn {
    position: absolute;
    top: 44px;
    right: 10px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    color: white;
    border: none;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 6;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    transition: transform 0.15s ease, background 0.15s ease;
    background: rgba(90, 100, 130, 0.85);
}
.collection-card .card-qty-dec-btn:hover { background: rgba(120, 130, 160, 0.95); transform: scale(1.12); }

/* ============================================
   MODAL
   ============================================ */
.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    z-index: 1000;
    justify-content: center;
    align-items: center;
    padding: 2rem;
}

.modal.active {
    display: flex;
}

.modal-content {
    background: linear-gradient(135deg, #1a1a2e, #16213e);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 20px;
    padding: 2rem;
    max-width: 500px;
    width: 100%;
    position: relative;
    max-height: 90vh;
    overflow-y: auto;
}

.card-modal-content {
    max-width: 600px;
}

.close-btn {
    position: absolute;
    top: 1rem;
    right: 1.5rem;
    font-size: 1.5rem;
    cursor: pointer;
    color: #888;
    transition: color 0.3s;
}

.close-btn:hover {
    color: #ff6b9d;
}

/* Setas laterais de navegação entre cartas do modal de detalhe — filhas
   diretas de #card-modal (position: fixed cobrindo a tela toda), por isso
   `position: absolute` aqui já posiciona relativo à VIEWPORT, não ao
   .modal-content menor. Visibilidade controlada via JS
   (updateCardDetailNavButtons em app-card-detail.js). */
.card-modal-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(22, 33, 62, 0.9);
    color: #fff;
    font-size: 1.3rem;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 1001;
    transition: background 0.2s, border-color 0.2s;
}

.card-modal-nav:hover:not(:disabled) {
    background: rgba(255, 107, 157, 0.25);
    border-color: #ff6b9d;
}

.card-modal-nav:disabled {
    opacity: 0.25;
    cursor: default;
    pointer-events: none;
}

.card-modal-nav-prev { left: 1rem; }
.card-modal-nav-next { right: 1rem; }

@media (max-width: 640px) {
    .card-modal-nav { width: 38px; height: 38px; font-size: 1.05rem; }
    .card-modal-nav-prev { left: 0.35rem; }
    .card-modal-nav-next { right: 0.35rem; }
}

/* ============================================
   FORMULÁRIOS
   ============================================ */
.modal-content h2 {
    margin-bottom: 1.5rem;
    color: #ff6b9d;
}

.modal-content input {
    width: 100%;
    padding: 0.8rem 1rem;
    margin-bottom: 1rem;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.05);
    color: white;
    font-size: 1rem;
    outline: none;
}

.modal-content input:focus {
    border-color: #ff6b9d;
}

.btn-primary {
    width: 100%;
    padding: 0.8rem;
    background: linear-gradient(90deg, #ff6b9d, #c44569);
    border: none;
    border-radius: 10px;
    color: white;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 20px rgba(255, 107, 157, 0.4);
}

.btn-danger {
    padding: 0.8rem 1.4rem;
    background: linear-gradient(90deg, #e74c3c, #c0392b);
    border: none;
    border-radius: 10px;
    color: white;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;
}

.btn-danger:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 20px rgba(231, 76, 60, 0.4);
}

/* Modal de confirmação de remoção (ver requestCardRemovalConfirmation,
   app-core.js) — .modal-content genérico já dá o visual, isso aqui só
   ajusta largura e o texto de aviso sobre o toggle nas configurações. */
.remove-confirm-modal-content {
    max-width: 420px;
}

.remove-confirm-hint {
    color: var(--pv-text-dim);
    font-size: 0.82rem;
    margin-top: 0.6rem;
    margin-bottom: 1.3rem;
}

.remove-confirm-actions {
    display: flex;
    gap: 0.8rem;
    justify-content: flex-end;
}

.remove-confirm-actions .btn-google {
    width: auto;
}

.auth-switch {
    text-align: center;
    margin-top: 1rem;
    color: #888;
}

.auth-switch a {
    color: #4ecdc4;
    cursor: pointer;
    text-decoration: underline;
}

.auth-message {
    margin-top: 1rem;
    padding: 0.8rem;
    border-radius: 8px;
    text-align: center;
    display: none;
}

.auth-message.success {
    display: block;
    background: rgba(78, 205, 196, 0.2);
    color: #4ecdc4;
    border: 1px solid #4ecdc4;
}

.auth-message.error {
    display: block;
    background: rgba(231, 76, 60, 0.2);
    color: #e74c3c;
    border: 1px solid #e74c3c;
}

/* ============================================
   DETALHES DA CARTA NO MODAL
   ============================================ */
.card-detail {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.card-detail-image {
    width: 100%;
    max-width: 300px;
    margin: 0 auto;
    border-radius: 16px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}

.nsfw-detail-hint {
    text-align: center;
    font-size: 0.78rem;
    color: #ffb400;
    margin: 0.5rem 0 0;
}

.card-detail-info h3 {
    font-size: 1.5rem;
    color: white;
    margin-bottom: 0.5rem;
}

.card-detail-info .detail-row {
    display: flex;
    justify-content: space-between;
    padding: 0.5rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.detail-label {
    color: #888;
}

.detail-value {
    color: white;
    font-weight: 600;
}

.add-to-collection {
    margin-top: 1rem;
    padding: 1rem;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.add-to-collection h4 {
    margin-bottom: 0.8rem;
    color: #4ecdc4;
}

.add-to-collection select,
.add-to-collection input {
    width: 100%;
    padding: 0.6rem;
    margin-bottom: 0.5rem;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.05);
    color: white;
}

/* "Adicionar imagem" no modal de detalhe (ver handleCardDetailImageError/
   uploadCardImage em app-card-detail.js) — só revelado quando a <img> da
   carta falha (404, carta sem foto de verdade no disco). Mesmo espírito
   visual de .add-to-collection logo acima, cor teal em vez de acento
   rosa pra não competir com o "+" de catalogar. */
.card-detail-add-image {
    margin-top: 1rem;
    padding: 1rem;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    text-align: center;
}
.card-detail-add-image p {
    color: var(--pv-text-dim);
    font-size: 0.85rem;
    margin: 0 0 0.7rem;
}
.card-detail-add-image .btn-google {
    width: auto;
    padding: 0.6rem 1.2rem;
    margin: 0 auto;
}

/* ============================================
   TOAST — ver showToast() em app-core.js. Fixo na tela (sobrevive ao
   fechamento de qualquer modal por baixo), some sozinho, não bloqueia
   clique em nada — pensado pra catalogar várias cartas em sequência sem
   precisar fechar um alert() a cada uma.
   ============================================ */
.app-toast {
    position: fixed;
    left: 50%;
    bottom: 2rem;
    transform: translateX(-50%) translateY(20px);
    background: #16213e;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-left: 4px solid #4ecdc4;
    color: white;
    padding: 0.9rem 1.4rem;
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    font-size: 0.95rem;
    font-weight: 600;
    z-index: 2000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease;
    max-width: min(90vw, 380px);
    text-align: center;
}

.app-toast.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.app-toast.error {
    border-left-color: #e74c3c;
}

/* Remoção de carta da coleção: sem popup de confirmação (ver
   quickRemoveFromCollection em app-sets.js e deleteCollectionItem em
   app-collection.js) — a ação já acontece na hora, então o toast precisa
   chamar mais atenção que o normal (maior, vermelho de verdade, fica mais
   tempo na tela) pra deixar claro que algo foi removido, já que não teve
   confirmação antes. */
.app-toast.danger {
    border: 2px solid #e74c3c;
    border-left: 6px solid #e74c3c;
    background: linear-gradient(135deg, rgba(231, 76, 60, 0.35), #16213e 60%);
    color: #ffe1de;
    font-size: 1.15rem;
    padding: 1.15rem 1.8rem;
    box-shadow: 0 14px 38px rgba(231, 76, 60, 0.5);
}

/* ============================================
   LOADING E MENSAGENS
   ============================================ */
.loading {
    text-align: center;
    padding: 3rem;
    color: #666;
    grid-column: 1 / -1;
}

.empty-state {
    text-align: center;
    padding: 3rem;
    color: #666;
    grid-column: 1 / -1;
}

/* ============================================
   RESPONSIVO
   ============================================ */

/* Menu mobile (hambúrguer) — abaixo de 900px o .nav some da fileira do
   header e vira um painel deslizante da direita, coberto por um backdrop
   escurecido. Escolhido 900px (não 768px, breakpoint mais comum de
   "tablet") porque o header tem bastante coisa (Início, Coleção▾,
   Ferramentas▾, idioma, moeda, 🔔, Conta▾/Entrar) — sobra pouco espaço
   numa tela de tablet retrato também. */
@media (max-width: 900px) {
    .header { padding: 0.85rem 1.1rem; }

    .nav-hamburger { display: flex; }

    .nav-backdrop.open {
        display: block;
        opacity: 1;
        pointer-events: auto;
    }

    .nav {
        display: none;
        position: fixed;
        top: 0;
        right: 0;
        /* height (não bottom:0) de propósito — .header tem backdrop-filter,
           que vira "containing block" desse position:fixed em navegadores
           atuais; bottom:0 resolveria contra a borda de BAIXO do header
           (~70px), não a da tela, e o painel ficava anão. 100dvh sobre
           100vh porque dvh já desconta a barra de endereço do navegador
           mobile (evita cortar o fim do painel atrás dela). */
        height: 100vh;
        height: 100dvh;
        width: min(320px, 84vw);
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 0.4rem;
        background: #12142a;
        border-left: 1px solid rgba(255, 255, 255, 0.1);
        padding: 0 1rem 1.5rem;
        overflow-y: auto;
        z-index: 195;
        box-shadow: -12px 0 40px rgba(0, 0, 0, 0.5);
    }

    .nav.mobile-open { display: flex; }

    .nav-mobile-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        position: sticky;
        top: 0;
        background: #12142a;
        padding: 1.1rem 0 0.9rem;
        margin-bottom: 0.3rem;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .nav-mobile-title {
        font-weight: 700;
        color: #ff6b9d;
        font-size: 1.05rem;
    }

    .nav-mobile-close {
        width: 34px;
        height: 34px;
        border-radius: 50%;
        border: 1px solid rgba(255, 255, 255, 0.15);
        background: rgba(255, 255, 255, 0.06);
        color: #e0e0e0;
        font-size: 1rem;
        cursor: pointer;
    }

    /* Toque confortável: itens mais altos que no header horizontal
       (onde o espaço é apertado), e cada um ocupa a largura toda em vez
       de pílula do tamanho do texto. */
    .nav > .nav-btn, .nav > .nav-dropdown, .nav .header-select, .nav > .nav-icon-btn {
        width: 100%;
    }

    .nav-btn, .nav-dropdown-trigger {
        padding: 0.85rem 1rem;
        justify-content: flex-start;
    }

    .nav-icon-btn { justify-content: flex-start; }

    /* Os 3 dropdowns (Coleção/Ferramentas/Conta) eram painéis FLUTUANTES
       (position:absolute) — dentro do painel vertical isso ficava
       cortado/mal posicionado. Aqui viram um acordeão: o painel empurra o
       conteúdo abaixo dele em vez de flutuar por cima. */
    /* .nav-dropdown é inline-flex (ROW) no desktop — o gatilho e o painel
       ficam lado a lado por padrão. Sem essa troca pra coluna, o painel
       (agora position:static) desenhava do LADO do botão "Coleção ▾" em
       vez de embaixo dele. */
    .nav-dropdown { width: 100%; display: flex; flex-direction: column; align-items: stretch; }
    .nav-dropdown-panel {
        position: static;
        min-width: 0;
        width: 100%;
        opacity: 1;
        transform: none;
        pointer-events: auto;
        max-height: 0;
        padding: 0;
        border: none;
        background: rgba(255, 255, 255, 0.03);
        border-radius: 10px;
        overflow: hidden;
        box-shadow: none;
        transition: max-height 0.2s ease;
    }
    .nav-dropdown.open .nav-dropdown-panel {
        max-height: 400px;
        padding: 0.3rem;
        margin-top: 0.2rem;
    }
    .nav-dropdown-right .nav-dropdown-panel { right: auto; }

    .nav-dropdown-item { padding: 0.8rem 0.9rem; }

    /* Divisor horizontal (era uma barra vertical entre grupos de botões
       numa fileira só) */
    .nav-divider {
        width: 100%;
        height: 1px;
        margin: 0.5rem 0;
    }

    .login-btn, .logout-btn { text-align: left; }
}

/* Enquanto o menu mobile está aberto (ver openMobileNav() em
   app-core.js) — impede rolar a página por trás do painel/backdrop. */
body.nav-lock-scroll { overflow: hidden; }

@media (max-width: 768px) {
    .hero h1 {
        font-size: 1.8rem;
    }

    .stats {
        flex-direction: column;
        gap: 1rem;
    }

    .cards-grid {
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
        gap: 1rem;
    }
}

/* ============================================
   PRISM VAULT — variáveis promovidas pro :root (antes só existiam dentro de
   .pv-scope, que cobria só o modal de login e a página de perfil). Com a
   reconstrução do site pra ter paridade com o app, as páginas novas
   (Portfólio, Notificações, Selados, ROI, Expositor) também usam essas
   variáveis via var(--pv-*), sem precisar da classe
   wrapper. .pv-scope continua existindo (agora como no-op, redeclarando os
   mesmos valores) só pra não quebrar nada que já dependia dela.
   ============================================ */
:root {
    --pv-bg: #0d0f1f;
    --pv-surface: #161a30;
    --pv-surface2: #1f2440;
    --pv-accent: #ff4f81;
    --pv-accent2: #3ce6c9;
    --pv-text: #eef1fb;
    --pv-text-dim: #8b90b3;
    --pv-border: rgba(255, 255, 255, 0.09);
}

.pv-scope {
    --pv-bg: #0d0f1f;
    --pv-surface: #161a30;
    --pv-surface2: #1f2440;
    --pv-accent: #ff4f81;
    --pv-accent2: #3ce6c9;
    --pv-text: #eef1fb;
    --pv-text-dim: #8b90b3;
    --pv-border: rgba(255, 255, 255, 0.09);
}

.pv-card {
    background: var(--pv-surface) !important;
    border-color: var(--pv-border) !important;
}

.pv-accent { color: var(--pv-accent) !important; }
.pv-accent2 { color: var(--pv-accent2) !important; }

/* Divisor "ou" entre o formulário e o botão do Google */
.auth-divider {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin: 1rem 0;
    color: var(--pv-text-dim);
    font-size: 0.8rem;
}
.auth-divider::before,
.auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--pv-border);
}

/* Botão "Continuar com Google" — reservado, ainda sem OAuth de verdade
   (precisa de um Client ID/Secret do Google Cloud Console). */
.btn-google {
    width: 100%;
    padding: 0.75rem;
    border-radius: 10px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.03);
    color: var(--pv-text);
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    transition: border-color 0.2s ease;
}
.btn-google:hover { border-color: var(--pv-accent2); }

.google-g {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: white;
    color: #4285f4;
    font-size: 0.7rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Container onde o próprio Google desenha o botão de verdade
   (google.accounts.id.renderButton) — sem isso o iframe do Google
   renderiza colado nos elementos vizinhos. */
.google-btn-container {
    display: flex;
    justify-content: center;
    min-height: 44px;
}

/* Botão "Continuar com Discord" — diferente do Google (SDK renderiza o
   próprio botão via JS), o Discord não tem SDK de botão: é um <a href>
   de verdade que manda o navegador inteiro pra /auth/discord/login
   (redirect 307 pro discord.com, ver app/routers/auth.py). Cor "blurple"
   oficial da marca (#5865F2). Dimensões (280x40, box-sizing border-box)
   batem exatamente com o botão do Google (renderButton com width: 280,
   size: 'large' → 40px de altura, ver renderGoogleButtons() em
   app-core.js) — sem isso o Discord ficava esticado a 100% da largura do
   modal enquanto o Google fica com largura fixa, então os dois saíam de
   tamanhos bem diferentes lado a lado. */
.discord-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    box-sizing: border-box;
    width: 280px;
    height: 40px;
    margin: 0.6rem auto 0;
    background: #5865F2;
    color: white;
    border-radius: 999px;
    text-decoration: none;
    font-weight: 700;
    font-size: 0.95rem;
    transition: background 0.15s ease;
}

.discord-btn:hover { background: #4752c4; }

.soon-badge {
    font-size: 0.7rem;
    color: var(--pv-text-dim);
    background: var(--pv-surface2);
    padding: 0.15rem 0.5rem;
    border-radius: 6px;
}

/* ============================================
   PÁGINA DE PERFIL
   ============================================ */
#page-profile {
    background: var(--pv-bg);
    border-radius: 20px;
    padding: 2rem;
}

.profile-header {
    display: flex;
    align-items: center;
    gap: 1.2rem;
}

.profile-avatar {
    width: 70px;
    height: 70px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--pv-accent), var(--pv-accent2));
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.8rem;
    flex-shrink: 0;
    overflow: hidden;
}
.profile-avatar img { width: 100%; height: 100%; object-fit: cover; }

/* Botão "Trocar foto" (perfil.body.html) — pill pequena embaixo do avatar,
   some/vira aviso de cooldown via updateAvatarUploadUI() (app-profile.js). */
.profile-change-photo-btn {
    display: block;
    margin: 0.5rem auto 0;
    padding: 0.3rem 0.7rem;
    font-size: 0.72rem;
    font-weight: 600;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.06);
    color: var(--pv-text);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.profile-change-photo-btn:hover { background: rgba(255, 255, 255, 0.12); border-color: var(--pv-accent); }
.profile-change-photo-btn:disabled { opacity: 0.6; cursor: default; }

.profile-cooldown-msg {
    color: var(--pv-text-dim);
    font-size: 0.72rem;
    text-align: center;
    margin: 0.35rem 0 0;
    max-width: 100px;
}
#profile-username-cooldown-msg {
    text-align: left;
    max-width: none;
    margin: -0.6rem 0 0.6rem;
}

/* Dentro do modal "Editar Perfil" (aba Avatar) o botão/aviso não fica
   mais centralizado embaixo de um avatar de 70px — a aba usa a largura
   toda, como qualquer outro campo do formulário. */
.profile-edit-panel .profile-change-photo-btn { margin: 0 0 0.6rem; }
.profile-edit-panel .profile-cooldown-msg { text-align: left; max-width: none; margin: -0.3rem 0 0.6rem; }

/* Botão único que abre o modal "Editar Perfil" (perfil.body.html) —
   substitui a leva de .profile-section que existia solta antes. */
.profile-edit-trigger-btn {
    margin-top: 0.4rem;
    padding: 0.35rem 0.8rem;
    font-size: 0.78rem;
    font-weight: 600;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.06);
    color: var(--pv-text);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.profile-edit-trigger-btn:hover { background: rgba(255, 255, 255, 0.12); border-color: var(--pv-accent); }

/* Modal "Editar Perfil" — mais largo que o .modal-content padrão (500px)
   pra caber a barra de abas sem espremer. */
.profile-edit-modal-content { max-width: 640px; }

.profile-edit-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    padding-bottom: 0.9rem;
    margin-bottom: 1.2rem;
}

.profile-edit-tab {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.8rem;
    font-size: 0.78rem;
    font-weight: 600;
    border-radius: 999px;
    border: 1px solid transparent;
    background: rgba(255, 255, 255, 0.04);
    color: var(--pv-text-dim);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.profile-edit-tab svg { flex-shrink: 0; }
.profile-edit-tab:hover { background: rgba(255, 255, 255, 0.08); color: var(--pv-text); }
.profile-edit-tab.active { background: rgba(255, 107, 157, 0.15); border-color: #ff6b9d; color: var(--pv-text); }

.profile-edit-panel { display: none; }
.profile-edit-panel.active { display: block; }

/* Cada aba consolidada (redesign 2026-09, junta assuntos parecidos —
   ver artifact do /design) agrupa 2-3 campos que antes eram aba própria
   — subseção = rótulo pequeno + ícone, separada da próxima por uma
   linha fina, mesmo espírito de .rarity-config-section noutras telas
   do projeto. */
.profile-edit-subsection { padding: 1.1rem 0; }
.profile-edit-subsection:first-child { padding-top: 0; }
.profile-edit-subsection:last-child { padding-bottom: 0; }
.profile-edit-subsection + .profile-edit-subsection { border-top: 1px solid rgba(255, 255, 255, 0.08); }
.profile-edit-subsection-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.6rem; }
.profile-edit-subsection-head svg { color: var(--pv-text-dim); flex-shrink: 0; }
.profile-edit-subsection-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--pv-text-dim);
}

.profile-header h2 { color: var(--pv-text); margin: 0 0 0.2rem; }
.profile-email { color: var(--pv-text-dim); font-size: 0.85rem; margin: 0; }

.supporter-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.15rem 0.55rem;
    border-radius: 20px;
    margin-left: 0.5rem;
    vertical-align: middle;
    background: rgba(255, 201, 74, 0.18);
    color: #ffc94a;
    border: 1px solid #ffc94a;
}

.profile-section {
    background: var(--pv-surface);
    border: 1px solid var(--pv-border);
    border-radius: 16px;
    padding: 1.4rem;
    margin-bottom: 1.2rem;
}
.profile-section h3 { color: var(--pv-accent2); font-size: 1rem; margin-bottom: 1rem; }
.profile-section input, .profile-section select {
    width: 100%;
    padding: 0.7rem 1rem;
    margin-bottom: 0.8rem;
    border-radius: 10px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.04);
    color: var(--pv-text);
    font-size: 0.95rem;
}

.profile-section select {
    cursor: pointer;
}
/* dropdown nativo herda a cor de fundo da página em alguns navegadores
   (Chrome/Edge) se não for setado explicitamente — sem isso, as opções
   apareciam com texto escuro sobre fundo escuro, ilegíveis. */
.profile-section select option {
    background: #1a1a2e;
    color: #fff;
}

/* ============================================
   CARD "COMPARTILHAR MINHA COLEÇÃO" (Perfil) — antes era só um checkbox
   nativo + input/botão genéricos, sem nenhuma identidade visual própria.
   ============================================ */
.share-card {
    position: relative;
    overflow: hidden;
    background: linear-gradient(155deg, var(--pv-surface), rgba(78, 205, 196, 0.05));
}

.share-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    margin-bottom: 0.6rem;
}
.share-card-header h3 { margin-bottom: 0; }

.share-status-badge {
    flex-shrink: 0;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    padding: 0.25rem 0.7rem;
    border-radius: 999px;
    white-space: nowrap;
}
.share-status-badge.is-public {
    color: var(--pv-accent2);
    background: rgba(60, 230, 201, 0.14);
    border: 1px solid rgba(60, 230, 201, 0.4);
}
.share-status-badge.is-private {
    color: var(--pv-text-dim);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--pv-border);
}

.share-toggle-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    cursor: pointer;
    width: fit-content;
}

/* Toggle switch custom — o checkbox nativo continua no DOM (fica
   transparente e sobreposto, sem afetar o form) só pra manter onchange/
   :checked funcionando; o visual é 100% dos dois <span> ao lado. */
.share-switch {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
    flex-shrink: 0;
}
.share-switch input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
}
.share-switch-track {
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background: var(--pv-surface2);
    border: 1px solid var(--pv-border);
    transition: background 0.2s ease, border-color 0.2s ease;
}
.share-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--pv-text-dim);
    transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.2s ease;
}
.share-switch input:checked ~ .share-switch-track {
    background: rgba(60, 230, 201, 0.35);
    border-color: var(--pv-accent2);
}
.share-switch input:checked ~ .share-switch-track .share-switch-thumb {
    transform: translateX(18px);
    background: var(--pv-accent2);
    box-shadow: 0 0 8px rgba(60, 230, 201, 0.6);
}

.share-link-row {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 1.1rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--pv-border);
}

.share-link-box {
    flex: 1;
    min-width: 220px;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0 0.9rem;
    height: 44px;
    border-radius: 10px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.04);
}
.share-link-icon { flex-shrink: 0; font-size: 0.9rem; opacity: 0.7; }
.share-link-box input {
    flex: 1;
    min-width: 0;
    border: none;
    background: transparent;
    color: var(--pv-accent2);
    font-family: monospace;
    font-size: 0.85rem;
    outline: none;
    cursor: text;
    text-overflow: ellipsis;
}

.share-copy-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    height: 44px;
    padding: 0 1.1rem;
    border-radius: 10px;
    border: 1px solid var(--pv-accent2);
    background: rgba(60, 230, 201, 0.1);
    color: var(--pv-accent2);
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.2s ease, transform 0.15s ease;
}
.share-copy-btn:hover { background: rgba(60, 230, 201, 0.2); }
.share-copy-btn:active { transform: scale(0.96); }

/* Seção "Métodos de login" do Perfil — uma linha por método (senha/
   Google/Discord), com o status (✅ vinculado / botão pra vincular) sempre
   à direita. */
.login-method-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--pv-border);
}
.login-method-row:last-of-type { border-bottom: none; }
.login-method-label {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-weight: 600;
    font-size: 0.92rem;
}
.login-method-status {
    flex-shrink: 0;
    font-size: 0.78rem;
    font-weight: 700;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    white-space: nowrap;
}
.login-method-status.is-linked {
    color: var(--pv-accent2);
    background: rgba(60, 230, 201, 0.14);
    border: 1px solid rgba(60, 230, 201, 0.4);
}
.login-method-status.is-missing {
    color: var(--pv-text-dim);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--pv-border);
}
/* Mesmo porte dos selos .login-method-status ao lado (não do .discord-btn
   do modal de login, 40px — usar aquela altura aqui fazia a linha do
   Discord ficar bem mais alta que as de Senha/Google, desalinhando as 3
   linhas da seção). */
.login-method-link-btn {
    flex-shrink: 0;
    height: 28px;
    padding: 0 0.85rem;
    border-radius: 999px;
    border: none;
    background: #5865F2;
    color: white;
    font-weight: 700;
    font-size: 0.78rem;
    cursor: pointer;
    transition: background 0.15s ease;
}
.login-method-link-btn:hover { background: #4752c4; }

/* ============================================
   REDESENHO DA PÁGINA /perfil (2026-09) — antes era só uma coluna de
   .profile-section empilhados na largura cheia do .page (1400px),
   parecendo uma tela de app mobile mesmo no desktop. Layout novo:
   avatar+nome+estatísticas numa barra "hero" horizontal, e o resto dos
   .profile-section (classe COMPARTILHADA com Portfólio/Selados/
   Notificações/ROI/Expositor — base acima não é tocada) numa grade
   responsiva que aproveita o espaço largo. .profile-header/
   .profile-avatar/.profile-email/.stat-card também são compartilhados
   com perfil-publico.body.html (perfil público de outra pessoa) — só
   ganham classes ADICIONAIS aqui (.profile-avatar-lg,
   .stat-card-compact), nunca uma redefinição da classe base.
   ============================================ */
#profile-content {
    max-width: 1100px;
    margin: 0 auto;
}

.profile-hero-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin-bottom: 1.8rem;
    padding-bottom: 1.6rem;
    border-bottom: 1px solid var(--pv-border);
}

.profile-avatar-lg {
    width: 88px;
    height: 88px;
    font-size: 2.2rem;
    box-shadow: 0 0 0 4px rgba(255, 79, 129, 0.15), 0 0 28px rgba(60, 230, 201, 0.22);
}

.stat-card.stat-card-compact {
    padding: 1rem 1.7rem;
}

.profile-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    grid-auto-flow: dense;
    align-items: start;
    gap: 1.2rem;
}

/* Só usada nesta página — faz um card ocupar a largura toda quando o
   conteúdo pede (chips de raridade, lista de progresso por coleção,
   card de compartilhar coleção). */
.profile-section-wide {
    grid-column: 1 / -1;
}

/* ============================================
   ENVIAR CARTA NOVA (cadastro pelo usuário, /enviar-carta,
   app-submissions.js) — reaproveita .profile-section/.btn-primary/
   .btn-google/.auth-message/.share-toggle-row já existentes; só os 3
   componentes abaixo são exclusivos dessa página.
   ============================================ */
.submission-field-label {
    display: block;
    font-size: 0.85rem;
    color: var(--pv-text-dim);
    margin-bottom: 0.4rem;
}

#sub-general-notes {
    width: 100%;
    padding: 0.7rem 1rem;
    border-radius: 10px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.04);
    color: var(--pv-text);
    font-family: inherit;
    font-size: 0.95rem;
    resize: vertical;
}

.submission-media-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.6rem;
}
.submission-media-row .btn-google { width: auto; padding: 0.5rem 1rem; }
.submission-media-name { font-size: 0.8rem; color: var(--pv-text-dim); }

.submission-resume-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.6rem;
    background: rgba(60, 230, 201, 0.1);
    border: 1px solid rgba(60, 230, 201, 0.35);
    border-radius: 12px;
    padding: 0.7rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.88rem;
    color: var(--pv-text);
}
.submission-resume-banner button {
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: white;
    padding: 0.3rem 0.8rem;
    border-radius: 8px;
    cursor: pointer;
    font-size: 0.8rem;
    flex-shrink: 0;
}

.submission-item-row {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--pv-border);
    border-radius: 14px;
    padding: 1.1rem;
    margin-bottom: 1rem;
}

.submission-item-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.7rem;
}

/* Selo de status pending/aprovado/rejeitado — "Minhas cartas enviadas".
   Mesma linguagem visual de .share-status-badge (pílula pequena), só
   com um 3º estado (rejeitado) que aquele componente não tinha. */
.submission-status {
    flex-shrink: 0;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.2rem 0.65rem;
    border-radius: 999px;
    white-space: nowrap;
}
.submission-status.pending, .submission-status.in-review {
    color: #ffc94a;
    background: rgba(255, 201, 74, 0.14);
    border: 1px solid rgba(255, 201, 74, 0.4);
}
.submission-status.approved {
    color: var(--pv-accent2);
    background: rgba(60, 230, 201, 0.14);
    border: 1px solid rgba(60, 230, 201, 0.4);
}
.submission-status.rejected {
    color: #ff6b6b;
    background: rgba(255, 107, 107, 0.14);
    border: 1px solid rgba(255, 107, 107, 0.4);
}

.profile-chip-row { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.profile-rarity-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.8rem;
    border-radius: 20px;
    font-family: monospace;
    font-weight: 700;
    font-size: 0.8rem;
}

.set-progress-row { margin-bottom: 0.9rem; }
.set-progress-row .set-progress-label {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    color: var(--pv-text-dim);
    margin-bottom: 0.3rem;
}
.set-progress-row .set-progress-label b { color: var(--pv-text); font-family: monospace; }
.set-progress-bar {
    height: 6px;
    border-radius: 6px;
    background: var(--pv-surface2);
    overflow: hidden;
}
.set-progress-fill {
    height: 100%;
    background: var(--pv-accent2);
    border-radius: 6px;
}

/* Progresso compacto no tile de set da Home (só quando logado, ver
   _renderSetProgressMini em app-sets.js) — reusa .set-progress-bar/-fill
   acima, só adiciona o layout e o texto "X/Y" embaixo da barra. */
.set-progress-mini {
    margin-top: 0.55rem;
    padding-top: 0.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.07);
}
.set-progress-mini .set-progress-bar {
    height: 5px;
    background: rgba(255, 255, 255, 0.08);
}
.set-progress-mini .set-progress-fill {
    background: linear-gradient(90deg, var(--pv-accent2), #6ee7dc);
    box-shadow: 0 0 6px rgba(78, 205, 196, 0.5);
}
.set-progress-mini-label {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--pv-text-dim);
    font-family: monospace;
    letter-spacing: 0.02em;
}

/* Chip de raridade 100% completa dentro de um set (ver
   _renderSetRarityProgress em app-sets.js) — mesmo "glow" do app
   (BoxShadow na cor da própria raridade, ver _buildSetProgressHeader em
   cards_screen.dart). box-shadow usa currentColor de propósito: a cor já
   vem via style inline (color:${color}) no elemento, então o glow segue
   sem precisar repetir o valor. */
.rarity-chip-complete {
    box-shadow: 0 0 8px currentColor;
    font-weight: 800 !important;
}

/* Chip clicável na página do set (ver filterCardsByRarity em app-sets.js)
   — clicar filtra a grade de cartas abaixo pra só aquela raridade; clicar
   de novo limpa. Classe própria (não mexe em .profile-rarity-chip direto)
   porque essa mesma classe base também é usada no card "por raridade" do
   Perfil, que é só informativo e não deve virar clicável. */
.rarity-chip-clickable {
    cursor: pointer;
    transition: transform 0.15s ease;
}
.rarity-chip-clickable:hover {
    transform: translateY(-1px);
}
.rarity-chip-active {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* Card de progresso detalhado no topo da página de um set (ver
   loadSetProgress()/renderSetProgress() em app-sets.js) — mesmo conteúdo
   de _buildSetProgressHeader() em cards_screen.dart, só HTML/CSS em vez
   de widgets Flutter. */
.set-progress-card {
    background: var(--pv-surface);
    border: 1px solid var(--pv-border);
    border-radius: 16px;
    padding: 1rem 1.2rem;
    margin-bottom: 1.2rem;
}
.set-progress-card-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.7rem;
    gap: 0.8rem;
}
.set-progress-card-title {
    font-weight: 700;
    font-size: 0.85rem;
    color: var(--pv-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.set-progress-card-pct {
    flex-shrink: 0;
    background: rgba(255, 79, 129, 0.15);
    color: var(--pv-accent);
    font-weight: 700;
    font-size: 0.78rem;
    padding: 0.2rem 0.6rem;
    border-radius: 10px;
}
.set-progress-card-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.5rem;
    gap: 0.8rem;
    font-size: 0.75rem;
    color: var(--pv-text-dim);
}
.set-progress-toggle {
    background: none;
    border: none;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.2rem 0.4rem;
    border-radius: 8px;
    cursor: pointer;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--pv-accent2);
}
.set-progress-toggle:hover { background: rgba(255, 255, 255, 0.06); }
.set-progress-toggle-complete { color: #2ecc71; }
.set-progress-rarities {
    margin-top: 0.8rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--pv-border);
}
.set-progress-rarities-label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--pv-text-dim);
    margin-bottom: 0.6rem;
}

/* ============================================
   HEADER — seletores extras (idioma) e badge de notificação
   ============================================ */
.header-select {
    background: rgba(22, 33, 62, 0.9);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 8px;
    padding: 6px 10px;
    font-size: 0.85rem;
    cursor: pointer;
    outline: none;
    margin-left: 8px;
}

.nav-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background: #e74c3c;
    color: white;
    font-size: 0.65rem;
    font-weight: 700;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

/* ============================================
   CAPA DOS SETS — imagens locais (goddess_story_app/assets/sets/*.jpg,
   copiadas pra frontend/img/sets/) em vez de só texto.
   ============================================ */
.set-cover {
    width: 100%;
    aspect-ratio: 1/1;
    object-fit: cover;
    border-radius: 9px;
    margin-bottom: 0.4rem;
    background: linear-gradient(135deg, #2a2a4a, #1a1a2e);
}

/* ============================================
   EDITAR/REMOVER ITEM DA COLEÇÃO
   ============================================ */
.collection-actions {
    position: absolute;
    bottom: 10px;
    right: 10px;
    z-index: 2;
    display: flex;
    gap: 0.4rem;
}

.icon-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, 0.65);
    color: white;
    font-size: 0.9rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s;
}

.icon-btn:hover { background: rgba(255, 107, 157, 0.8); }
.icon-btn-danger:hover { background: rgba(231, 76, 60, 0.85); }

/* ============================================
   DETALHE DA CARTA — preço detalhado (colapsável), histórico (sparkline),
   desejos, alerta de preço
   ============================================ */
.price-breakdown {
    margin-top: 1rem;
    padding: 1rem;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.price-breakdown h4 {
    color: #4ecdc4;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0;
}

.price-breakdown .chev {
    transition: transform 0.25s;
}

.price-breakdown.expanded .chev {
    transform: rotate(180deg);
}

.breakdown-updated {
    color: #666;
    font-size: 0.75rem;
    margin: 0.3rem 0 0;
}

.price-breakdown .breakdown-body {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
}

.price-breakdown.expanded .breakdown-body {
    max-height: 300px;
    margin-top: 0.8rem;
}

.price-sparkline-section {
    margin-top: 1rem;
}

.price-sparkline-section h4 {
    color: #4ecdc4;
    margin-bottom: 0.6rem;
}

#price-sparkline-canvas {
    width: 100%;
    height: 70px;
    display: block;
}

.empty-inline {
    color: #666;
    font-size: 0.85rem;
    padding: 0.6rem 0;
}

.wishlist-toggle-btn {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: #e0e0e0;
    padding: 0.4rem 0.8rem;
    border-radius: 20px;
    font-size: 0.8rem;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.2s;
}

.wishlist-toggle-btn.active {
    background: rgba(255, 79, 129, 0.2);
    border-color: #ff4f81;
    color: #ff4f81;
}

/* ============================================
   PORTFÓLIO — valor atual, gráfico (Chart.js), maiores altas/baixas
   ============================================ */
.mover-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.2rem;
}

@media (max-width: 768px) {
    .mover-columns { grid-template-columns: 1fr; }
}

.mover-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--pv-border);
    gap: 0.6rem;
}

.mover-row:last-child { border-bottom: none; }

.mover-info { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.mover-info b { color: var(--pv-text); font-size: 0.88rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mover-code { color: var(--pv-text-dim); font-family: monospace; font-size: 0.75rem; }

.mover-values {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.15rem;
    font-size: 0.8rem;
    color: var(--pv-text-dim);
    white-space: nowrap;
}

.mover-up { color: #3ce6c9; font-weight: 700; }
.mover-down { color: #ff5c5c; font-weight: 700; }

/* ============================================
   NOTIFICAÇÕES + ALERTAS DE PREÇO
   ============================================ */
.notif-row {
    display: flex;
    gap: 0.8rem;
    padding: 0.9rem 0;
    border-bottom: 1px solid var(--pv-border);
    cursor: default;
}

.notif-row:last-child { border-bottom: none; }

.notif-row.notif-unread { cursor: pointer; }
.notif-row.notif-unread .notif-body b { color: var(--pv-accent2); }

.notif-icon { font-size: 1.3rem; flex-shrink: 0; }

.notif-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.notif-body b { color: var(--pv-text); font-size: 0.9rem; }
.notif-body p { color: var(--pv-text-dim); font-size: 0.82rem; margin: 0; }
.notif-date { color: var(--pv-text-dim); font-size: 0.7rem; opacity: 0.7; }

.alert-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--pv-border);
    gap: 0.6rem;
}

.alert-row:last-child { border-bottom: none; }

.alert-info { display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.85rem; color: var(--pv-text-dim); }
.alert-info b { color: var(--pv-text); }

/* ============================================
   ITENS LACRADOS
   ============================================ */
/* .sealed-row-main (capa+info) e .sealed-row-actions (valores+editar/
   excluir) são dois grupos flex separados, não filhos soltos direto de
   .sealed-row — em telas estreitas, .sealed-values (largura fixa, preço
   "de → para" não quebra) + 2 botões de ação já passavam de ~230px, e
   somados à capa (52px) e ao mínimo de .sealed-info sobravam menos que
   zero espaço pro nome da carta (ele colapsava pra 0px de largura e virava
   uma coluna de texto ilegível, uma letra por linha — achado no audit de
   mobile). Com os dois grupos, flex-wrap deixa .sealed-row-actions cair
   pra uma segunda linha inteira quando não cabe mais do lado do nome, em
   vez de espremer o nome até sumir. */
.sealed-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    padding: 0.8rem;
    margin-bottom: 0.6rem;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--pv-border);
    gap: 0.6rem 0.9rem;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.sealed-row:hover {
    background: rgba(255, 255, 255, 0.055);
    border-color: rgba(255, 255, 255, 0.16);
}

.sealed-row:last-child { margin-bottom: 0; }

.sealed-row-main {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    flex: 1 1 200px;
    min-width: 0;
}

.sealed-row-actions {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-left: auto;
}

.sealed-cover {
    width: 52px;
    height: 52px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
    background: linear-gradient(135deg, #2a2a4a, #1a1a2e);
}

.sealed-info { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; flex: 1; }
.sealed-info b { color: var(--pv-text); font-size: 0.9rem; }
.sealed-notes { color: var(--pv-text-dim); font-size: 0.75rem; font-style: italic; }

.sealed-values {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.2rem;
    font-size: 0.8rem;
    color: var(--pv-text-dim);
    white-space: nowrap;
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}

/* Quando .sealed-row-actions cai pra segunda linha (telas estreitas
   demais pra caber do lado de .sealed-row-main), some com o
   margin-left:auto (que só faz sentido colado à direita na MESMA linha do
   nome) e alinha os valores com o preço/lucro à esquerda em vez de à
   direita, alinhado embaixo do início do texto — mais fácil de ler numa
   coluna estreita do que "flutuando" à direita. */
@media (max-width: 480px) {
    .sealed-row-actions {
        margin-left: 0;
        flex-basis: 100%;
        justify-content: space-between;
    }
    .sealed-values { align-items: flex-start; }
}

/* ============================================
   CALCULADORA DE ROI
   ============================================ */
.roi-config-row {
    display: flex;
    gap: 1rem;
    align-items: flex-end;
}

.roi-config-row > div {
    display: flex;
    flex-direction: column;
}

.roi-config-row label {
    display: block;
    font-size: 0.75rem;
    color: var(--pv-text-dim);
    margin-bottom: 0.4rem;
}

/* height fixa nos dois — <select> nativo tem padding/line-height próprios
   que nunca batem exatamente com <input> mesmo com o mesmo CSS (variação
   de navegador pro navegador), o que fazia os dois campos parecerem
   desalinhados/de alturas diferentes lado a lado apesar do
   align-items:flex-end. appearance:none + seta customizada no select
   evita a seta nativa (que também varia de tamanho por navegador). */
.roi-config-row select,
.roi-config-row input {
    width: 100%;
    height: 44px;
    padding: 0 0.85rem;
    border-radius: 10px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.04);
    color: var(--pv-text);
    font-size: 0.92rem;
    box-sizing: border-box;
}

.roi-config-row select {
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    padding-right: 2.2rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%238b90b3'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.9rem center;
}

.roi-config-row select:focus,
.roi-config-row input:focus {
    outline: none;
    border-color: var(--pv-accent2);
}

@media (max-width: 600px) {
    .roi-config-row {
        flex-direction: column;
        align-items: stretch;
    }
}

.roi-results-panel {
    display: flex;
    justify-content: space-around;
    padding: 1rem;
    margin: 1rem 0;
    border-radius: 16px;
    background: linear-gradient(135deg, var(--pv-surface), var(--pv-surface2));
    border: 1px solid var(--pv-border);
}

.roi-results-panel > div {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
}

.roi-results-panel span { color: var(--pv-text-dim); font-size: 0.75rem; }
.roi-results-panel b { font-size: 1.1rem; color: var(--pv-text); }

.roi-card-row {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.6rem;
    margin-bottom: 0.6rem;
    border-radius: 12px;
    background: var(--pv-surface);
    border: 1px solid var(--pv-border);
    transition: border-color 0.2s;
}

.roi-card-row.roi-card-active {
    border-color: var(--pv-accent);
}

.roi-card-thumb {
    width: 40px;
    height: 56px;
    object-fit: cover;
    border-radius: 6px;
    flex-shrink: 0;
    background: var(--pv-surface2);
}

.roi-card-info { display: flex; flex-direction: column; gap: 0.2rem; flex: 1; min-width: 0; }
.roi-card-info b { color: var(--pv-text); font-size: 0.85rem; }
.roi-card-info span { font-size: 0.75rem; color: var(--pv-text-dim); }

.roi-qty-controls {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

.roi-qty-controls button {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 1px solid var(--pv-border);
    background: transparent;
    color: var(--pv-text);
    cursor: pointer;
    font-size: 0.8rem;
}

.roi-qty-controls span {
    min-width: 20px;
    text-align: center;
    font-weight: 700;
    color: var(--pv-text);
}

/* ============================================
   CHIPS GENÉRICOS (usados no montador de expositores)
   ============================================ */
.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.showcase-size-chip,
.showcase-label-chip,
.showcase-theme-chip,
.ranking-tab-chip {
    padding: 0.4rem 0.9rem;
    border-radius: 20px;
    border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.03);
    color: var(--pv-text-dim);
    font-size: 0.8rem;
    cursor: pointer;
    transition: all 0.2s;
}

.showcase-size-chip.active,
.showcase-label-chip.active,
.showcase-theme-chip.active,
.ranking-tab-chip.active {
    background: var(--pv-accent);
    border-color: var(--pv-accent);
    color: white;
    font-weight: 600;
}

/* ============================================
   CLASSIFICAÇÃO (ranking de usuários com coleção pública)
   ============================================ */
.ranking-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.ranking-row {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.8rem 1rem;
    border-radius: 14px;
    background: var(--pv-surface);
    border: 1px solid var(--pv-border);
    text-decoration: none;
    color: inherit;
    transition: border-color 0.2s, transform 0.15s;
}
.ranking-row:hover {
    border-color: var(--pv-accent);
    transform: translateY(-1px);
}

.ranking-position {
    width: 28px;
    flex-shrink: 0;
    text-align: center;
    font-weight: 800;
    font-size: 0.95rem;
    color: var(--pv-text-dim);
}
/* Pódio: 1º/2º/3º ganham cor própria — mesma ideia do glow de raridade
   completa (rarity-chip-complete), só que fixo em ouro/prata/bronze em
   vez de reaproveitar cor de raridade (não faria sentido aqui). */
.ranking-position.rank-1 { color: #ffd54a; text-shadow: 0 0 8px rgba(255, 213, 74, 0.6); }
.ranking-position.rank-2 { color: #c9d2e0; text-shadow: 0 0 6px rgba(201, 210, 224, 0.5); }
.ranking-position.rank-3 { color: #d8965a; text-shadow: 0 0 6px rgba(216, 150, 90, 0.5); }

.ranking-avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--pv-accent), var(--pv-accent2));
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    flex-shrink: 0;
    overflow: hidden;
}
.ranking-avatar img { width: 100%; height: 100%; object-fit: cover; }

.ranking-info { flex: 1; min-width: 0; }
.ranking-username {
    font-weight: 700;
    color: var(--pv-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ranking-metric {
    font-weight: 800;
    font-size: 1rem;
    color: var(--pv-accent2);
    white-space: nowrap;
}
.ranking-metric-label {
    display: block;
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--pv-text-dim);
    text-align: right;
}

/* ============================================
   MONTADOR DE EXPOSITORES
   ============================================ */
.showcase-picker-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
    gap: 0.6rem;
}

.showcase-slot {
    aspect-ratio: 63/88;
    border-radius: 10px;
    border: 1px dashed var(--pv-border);
    background: var(--pv-surface2);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    cursor: pointer;
    font-size: 1.4rem;
    color: var(--pv-text-dim);
}

.showcase-slot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.showcase-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
    gap: 0.6rem;
    max-height: 60vh;
    overflow-y: auto;
}

.showcase-picker-thumb {
    aspect-ratio: 63/88;
    width: 100%;
    object-fit: cover;
    border-radius: 8px;
    cursor: pointer;
    border: 1px solid var(--pv-border);
    transition: border-color 0.2s;
}

.showcase-picker-thumb:hover {
    border-color: var(--pv-accent);
}

/* Página /precificacao — explicação do motor de preços */
.pricing-method-grid {
    display: grid;
    /* min(320px, 100%) — mesmo motivo do .pricing-examples-grid acima:
       320px cru não encolhe em telas mais estreitas que isso (ex: iPhone
       SE, 320px de largura TOTAL, menos ainda de largura útil depois do
       padding da página) e vazava a página pros lados. */
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 1.2rem;
}
.pricing-method-card h3 {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.pricing-tag {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.2rem 0.6rem;
    border-radius: 20px;
    background: rgba(255, 255, 255, 0.08);
    color: #8888a0;
    border: 1px solid rgba(255, 255, 255, 0.12);
}
.pricing-tag-good {
    background: rgba(60, 230, 201, 0.12);
    color: var(--pv-accent2);
    border-color: rgba(60, 230, 201, 0.35);
}
.pricing-formula {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    padding: 0.9rem 1rem;
    margin: 0.8rem 0;
    font-family: 'Courier New', monospace;
    font-size: 0.85rem;
    line-height: 1.8;
    color: #ccc;
}
.pricing-formula b {
    color: var(--pv-accent2);
}
.pricing-example {
    background: rgba(255, 255, 255, 0.04);
    border: 1px dashed rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    padding: 0.9rem 1rem;
    margin: 1rem 0;
}
.pricing-example-title {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #8888a0;
    margin-bottom: 0.6rem;
}
.pricing-example-row {
    display: flex;
    justify-content: space-between;
    padding: 0.3rem 0;
    font-size: 0.88rem;
}
.pricing-example-row span { color: #aaa; }
.pricing-example-row b { color: #eee; }
.pricing-example-result {
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    margin-top: 0.4rem;
    padding-top: 0.6rem;
    font-weight: 700;
}
.pricing-example-result span { color: #eee; }
.pricing-example-result b { color: var(--pv-accent2); }

.pricing-examples-grid {
    display: grid;
    /* min(380px, 100%) em vez de 380px cru — sem isso, em qualquer tela
       mais estreita que 380px (todo celular) a coluna não tinha como
       encolher e o grid inteiro vazava pra fora da página (achado no
       audit de mobile: barra de rolagem horizontal na página inteira). */
    grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr));
    gap: 1.2rem;
}
.pricing-example-card-body {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    margin-top: 0.6rem;
}
.pricing-example-img {
    width: 100px;
    aspect-ratio: 63/88;
    object-fit: cover;
    border-radius: 8px;
    flex-shrink: 0;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
}
.pricing-example-info { flex: 1; min-width: 0; }
.pricing-example-name {
    font-family: 'Outfit', 'Inter', sans-serif;
    font-weight: 700;
    font-size: 1.02rem;
    color: #fff;
}
.pricing-example-meta {
    color: #8888a0;
    font-size: 0.78rem;
    margin-top: 0.15rem;
}
.pricing-example-note {
    color: #8888a0;
    font-size: 0.85rem;
    line-height: 1.6;
    margin: 0.9rem 0 0;
    padding-top: 0.7rem;
    border-top: 1px dashed rgba(255, 255, 255, 0.1);
}
@media (max-width: 480px) {
    .pricing-example-card-body { flex-direction: column; }
    .pricing-example-img { width: 140px; }
}

/* ============================================
   SIDEBAR DE COLEÇÕES (Home, 2026-08) — antes o site era 100%
   Goddess Story sem noção de "jogo"; a Home agora tem uma coluna lateral
   fixa (busca + lista de coleções, vindo de GET /games) ao lado do
   conteúdo principal (hero + grade de sets), que passa a refletir só a
   coleção selecionada. Mesma marcação/CSS já validados na prévia de
   design publicada antes da implementação de verdade.
   ============================================ */
/* .page (envolve {{CONTENT}} de toda página, _base.html) tem max-width:1400px
   + margin:0 auto — ótimo pra conteúdo centralizado, mas deixava a sidebar
   "flutuando" no meio da tela em vez de grudada na borda esquerda de
   verdade. calc(-50vw + 50%) estoura o container centralizado só pra essa
   linha (técnica padrão de "full bleed" dentro de layout centralizado),
   sem mexer em padding/max-width de nenhuma outra página do site. */
.home-body-row {
    display: flex;
    align-items: flex-start;
    gap: 0;
    /* Sem width:100vw de propósito — vw inclui a faixa da barra de rolagem
       em vários navegadores, o que criaria um scroll horizontal de uns
       pixels a mais. Margem negativa dos dois lados já estica um elemento
       de bloco até a borda real sozinha, sem esse efeito colateral. */
    margin-left: calc(-50vw + 50%);
    margin-right: calc(-50vw + 50%);
}
.home-sidebar {
    width: 268px;
    flex-shrink: 0;
    border-right: 1px solid rgba(255, 255, 255, 0.08);
    padding: 1.4rem 1rem 2rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    /* Fixa a sidebar embaixo do header (69px, ver .header) enquanto a
       grade de sets rola por baixo — sem isso ela subia junto com o
       resto da página e sumia de vista ao descer pra ver outras
       coleções. Rola sozinha (overflow-y) se a lista de coleções um dia
       crescer mais que a tela. Só acima do breakpoint de 900px — abaixo
       disso a sidebar já vira um bloco full-width empilhado (ver media
       query logo abaixo), onde "grudar" no topo não faz sentido. */
    position: sticky;
    top: 69px;
    max-height: calc(100vh - 69px);
    overflow-y: auto;
}
.home-sidebar-search { position: relative; margin-bottom: 1.1rem; }
.home-sidebar-search input {
    width: 100%;
    padding: 0.65rem 1rem 0.65rem 2.3rem;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.05);
    color: #fff;
    font-size: 0.85rem;
}
.home-sidebar-search input::placeholder { color: #666; }
.home-sidebar-search svg {
    position: absolute; left: 0.8rem; top: 50%; transform: translateY(-50%);
    color: #666; width: 15px; height: 15px; pointer-events: none;
}
.home-sidebar-group-label {
    font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.07em;
    color: #5a5a72; padding: 0.6rem 0.5rem 0.35rem; font-weight: 700;
}
.home-sidebar-item {
    display: flex; align-items: center; gap: 0.65rem;
    padding: 0.5rem 0.55rem; border-radius: 10px; cursor: pointer;
    border: 1px solid transparent; background: none; width: 100%;
    text-align: left; font: inherit; color: inherit;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.home-sidebar-item:hover { background: rgba(255, 255, 255, 0.05); }
.home-sidebar-item.active {
    border-color: rgba(255, 107, 157, 0.45);
    background: linear-gradient(135deg, rgba(255, 107, 157, 0.16), rgba(255, 255, 255, 0.02));
}
.home-sidebar-item.locked { cursor: default; opacity: 0.5; }
.home-sidebar-item.locked:hover { background: transparent; }
.home-sidebar-cover {
    width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #2a2a4a, #1a1a2e);
}
.home-sidebar-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.home-sidebar-text { min-width: 0; flex: 1; }
.home-sidebar-name {
    font-size: 0.83rem; font-weight: 600; color: #fff;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.home-sidebar-meta { font-size: 0.68rem; color: #75758c; }
.home-sidebar-favorite-star {
    flex-shrink: 0; font-size: 1.05rem; line-height: 1; color: #4a4a5e;
    padding: 0.2rem; border-radius: 6px; transition: color 0.15s ease, transform 0.1s ease;
}
.home-sidebar-favorite-star:hover { color: #8b90b3; transform: scale(1.15); }
.home-sidebar-favorite-star.is-favorite { color: #ff6b9d; }
.home-sidebar-favorite-star.is-favorite:hover { color: #ff8fb3; }
.home-sidebar-lock { flex-shrink: 0; color: #5a5a72; display: flex; align-items: center; }
.home-sidebar-empty { color: #5a5a72; font-size: 0.8rem; padding: 0.8rem 0.5rem; }
/* .home-main-content perdeu o padding que .page dava de graça (2rem em
   todo canto) quando .home-body-row estourou pra fora de .page — sem
   isso, hero/busca/grade de sets ficavam colados na borda direita de
   verdade (e na borda da sidebar à esquerda). 30px reaproveita esse
   respiro só pra essa área. */
.home-main-content { flex: 1; min-width: 0; padding: 0 30px; }

@media (max-width: 900px) {
    .home-body-row { flex-direction: column; }
    .home-sidebar {
        width: 100%; border-right: none;
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        padding: 1rem 1rem 1.4rem;
        /* Empilhada e full-width aqui — "grudar" no topo não faz sentido
           nesse layout, e o scroll próprio (overflow-y) ficaria estranho
           misturado com o resto da página rolando por baixo. */
        position: static;
        max-height: none;
        overflow-y: visible;
    }
}

/* ============================================
   BINDER (página /binder) — planejador de pasta/binder
   ============================================ */
.binder-intro { color: var(--pv-text-dim); max-width: 70ch; margin: 0 0 1rem; }
.binder-config { display: flex; flex-direction: column; gap: 1.1rem; }
.binder-field { display: flex; flex-direction: column; gap: 0.45rem; }
.binder-label { font-weight: 700; font-size: 0.9rem; }
.binder-label-row { display: flex; justify-content: space-between; align-items: center; }
.binder-link-row { display: flex; gap: 0.8rem; }
.binder-link { background: none; border: none; padding: 0; color: var(--pv-accent); cursor: pointer; font-size: 0.8rem; text-decoration: underline; }
.binder-hint { color: var(--pv-text-dim); font-size: 0.8rem; margin: 0; }
.binder-chip {
    padding: 0.4rem 0.9rem; border-radius: 20px; border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.03); color: var(--pv-text-dim); font-size: 0.8rem;
    cursor: pointer; transition: all 0.2s;
}
.binder-chip.active { background: var(--pv-accent); border-color: var(--pv-accent); color: white; font-weight: 600; }
.binder-set-picker {
    max-height: 190px; overflow-y: auto; display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0.25rem 0.8rem;
    padding: 0.6rem 0.8rem; border: 1px solid var(--pv-border); border-radius: 12px;
    background: rgba(255, 255, 255, 0.02);
}
.binder-set-option { display: flex; gap: 0.45rem; align-items: center; font-size: 0.82rem; cursor: pointer; }
.binder-set-option em { color: var(--pv-text-dim); font-style: normal; font-size: 0.75rem; }
.binder-options { gap: 0.5rem; }
.binder-plans-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.binder-plans-row .collection-search-input { flex: 1 1 160px; max-width: 260px; }
.binder-btn { width: auto; padding: 0.45rem 1rem; }
.binder-btn-secondary {
    padding: 0.45rem 1rem; border-radius: 10px; border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.04); color: var(--pv-text); cursor: pointer; font-size: 0.85rem;
}
.binder-btn-danger { color: #ff6b6b; border-color: rgba(255, 107, 107, 0.4); }

.binder-summary { margin: 1rem 0; font-weight: 600; color: var(--pv-text); }
.binder-nav { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0.8rem; margin-bottom: 0.9rem; }
.binder-nav-btn {
    width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--pv-border);
    background: rgba(255, 255, 255, 0.05); color: var(--pv-text); font-size: 1.4rem; line-height: 1; cursor: pointer;
}
.binder-nav-btn:disabled { opacity: 0.3; cursor: default; }
.binder-nav-label { font-weight: 700; min-width: 8.5rem; text-align: center; }
.binder-goto { display: flex; align-items: center; gap: 0.4rem; font-size: 0.8rem; color: var(--pv-text-dim); }
.binder-goto input { width: 4.2rem; padding: 0.3rem 0.4rem; border-radius: 8px; border: 1px solid var(--pv-border); background: rgba(255, 255, 255, 0.05); color: var(--pv-text); }

.binder-book { display: flex; justify-content: center; align-items: flex-start; gap: 0; }
.binder-page {
    flex: 1 1 0; max-width: 460px; min-width: 0; padding: 0.7rem 0.8rem 0.9rem;
    background: linear-gradient(160deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
    border: 1px solid var(--pv-border); border-radius: 14px;
}
.binder-book.is-spread .binder-page:first-child { border-radius: 14px 4px 4px 14px; border-right-width: 3px; }
.binder-book.is-spread .binder-page:last-child { border-radius: 4px 14px 14px 4px; border-left-width: 3px; }
.binder-page-head { display: flex; justify-content: space-between; gap: 0.6rem; font-size: 0.72rem; color: var(--pv-text-dim); margin-bottom: 0.5rem; }
.binder-page-num { font-weight: 700; white-space: nowrap; }
.binder-page-groups { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.binder-grid { display: grid; grid-template-columns: repeat(var(--binder-n), 1fr); gap: 0.4rem; }

.binder-pocket {
    position: relative; aspect-ratio: 63 / 88; border-radius: 6px; overflow: hidden;
    display: flex; align-items: center; justify-content: center; text-align: center;
    border: 1px solid var(--pv-border); background: rgba(255, 255, 255, 0.03);
}
.binder-pocket.is-owned, .binder-pocket.is-missing, .binder-pocket.is-wish { cursor: pointer; }
.binder-pocket.is-owned { border-color: rgba(255, 255, 255, 0.18); }
.binder-pocket.is-owned .card-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.binder-pocket.is-missing { border: 1.5px dashed rgba(255, 255, 255, 0.28); background: rgba(255, 255, 255, 0.015); }
.binder-pocket.is-wish { border: 1.5px dashed #b565f5; background: rgba(181, 101, 245, 0.08); }
.binder-pocket.is-pad { border: 1px dashed rgba(255, 255, 255, 0.08); background: transparent; }
.binder-ghost-text { display: flex; flex-direction: column; gap: 0.15rem; padding: 0.2rem; font-size: 0.62rem; line-height: 1.15; color: var(--pv-text-dim); overflow: hidden; }
.binder-ghost-text b { color: var(--pv-text); font-size: 0.66rem; word-break: break-all; }
.binder-ghost-text i { font-style: normal; opacity: 0.7; }
.binder-wish-mark { position: absolute; top: 3px; right: 4px; font-size: 0.75rem; }
.binder-qty {
    position: absolute; right: 3px; bottom: 3px; padding: 0 5px; border-radius: 10px;
    background: rgba(0, 0, 0, 0.75); color: #fff; font-size: 0.68rem; font-weight: 700;
}

.binder-map { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; margin-top: 1rem; max-height: 160px; overflow-y: auto; }
.binder-map-cell {
    min-width: 30px; padding: 0.25rem 0.35rem; border-radius: 6px; font-size: 0.68rem; cursor: pointer;
    border: 1px solid var(--pv-border); background: rgba(255, 255, 255, 0.04); color: var(--pv-text-dim);
}
.binder-map-cell.is-full { background: rgba(62, 207, 142, 0.25); border-color: rgba(62, 207, 142, 0.6); color: #d5fbe9; }
.binder-map-cell.is-partial { background: rgba(240, 169, 60, 0.2); border-color: rgba(240, 169, 60, 0.55); color: #ffe7c2; }
.binder-map-cell.is-current { outline: 2px solid var(--pv-accent); outline-offset: 1px; color: #fff; }

.binder-todo { margin-top: 1.2rem; }
.binder-todo summary { cursor: pointer; font-weight: 700; }
.binder-todo-count { color: var(--pv-text-dim); font-weight: 400; }
.binder-todo-page { margin-top: 0.8rem; }
.binder-todo-page ul { list-style: none; margin: 0.3rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.82rem; }
.binder-todo-page li.is-wish { color: #d3a8ff; }
.binder-todo-pos { display: inline-block; min-width: 4.2rem; color: var(--pv-text-dim); }
.binder-todo-done { color: #3ecf8e; margin: 0.6rem 0 0; }

@media (max-width: 899px) {
    .binder-page { max-width: 520px; }
}

.binder-set-option input, .binder-options input { width: auto; flex: none; margin: 0; }

.binder-group-picker { max-height: 240px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.binder-group-picker .binder-set-option { justify-content: space-between; }
.binder-group-picker .binder-set-option > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.binder-only { flex: none; opacity: 0.75; }

/* "Compre agora" na página de um set (ver renderSetBuyNow() em app-sets.js) */
.set-buy-now {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem 0.9rem;
    background: var(--pv-surface);
    border: 1px solid var(--pv-border);
    border-radius: 16px;
    padding: 0.8rem 1.2rem;
    margin-bottom: 1.2rem;
}
.set-buy-now-label { font-weight: 700; font-size: 0.9rem; color: var(--pv-text); }
.set-buy-now-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.set-buy-btn {
    display: inline-block;
    padding: 0.5rem 1.1rem;
    border-radius: 10px;
    font-weight: 700;
    font-size: 0.85rem;
    text-decoration: none;
    border: 1px solid transparent;
    transition: transform 0.15s, filter 0.15s;
}
.set-buy-btn:hover { transform: translateY(-1px); filter: brightness(1.1); }
.set-buy-btn-ali { background: rgba(255, 140, 0, 0.16); color: #ff9a2e; border-color: rgba(255, 140, 0, 0.4); }
.set-buy-btn-ebay { background: rgba(60, 130, 246, 0.16); color: #5b9bff; border-color: rgba(60, 130, 246, 0.4); }

/* "Adicionar/remover raridade" no dropdown "Faltam" de um set (ver
   renderSetProgress()/requestRarityBulk() em app-sets.js) */
.set-rarity-edit-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
    font-size: 0.82rem;
    color: var(--pv-text);
    cursor: pointer;
}
.set-rarity-edit-toggle input { width: auto; margin: 0; }
.rarity-edit-group { display: inline-flex; align-items: center; gap: 0.25rem; }
.rarity-bulk-btn {
    width: 1.6rem;
    height: 1.6rem;
    padding: 0;
    border-radius: 50%;
    border: 1px solid var(--pv-border);
    background: var(--pv-surface);
    color: var(--pv-text);
    font-weight: 700;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.rarity-bulk-add { border-color: #4ecdc4; color: #4ecdc4; }
.rarity-bulk-remove { border-color: #e74c3c; color: #e74c3c; }
.rarity-bulk-btn:hover:not(:disabled) { filter: brightness(1.25); }
.rarity-bulk-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* Modal de confirmação do "Adicionar/remover raridade" (set.body.html →
   #rarity-bulk-modal, preenchido por requestRarityBulk() em app-sets.js).
   --rc = cor da raridade; .rarity-bulk-is-add/-is-remove definem o tom. */
.rarity-bulk-modal-content {
    max-width: 440px;
    padding: 1.6rem 1.6rem 1.4rem;
    overflow-x: hidden;
    --tone: #4ecdc4;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55), 0 0 0 1px color-mix(in srgb, var(--tone) 22%, transparent);
    animation: rarity-bulk-pop 0.18s ease-out;
}
.rarity-bulk-modal-content.rarity-bulk-is-remove { --tone: #ff6b5e; }
@keyframes rarity-bulk-pop {
    from { opacity: 0; transform: translateY(8px) scale(0.98); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .rarity-bulk-modal-content { animation: none; } }

.rarity-bulk-head { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 1.2rem; padding-right: 1.5rem; }
.rarity-bulk-icon {
    flex: none;
    width: 2.8rem;
    height: 2.8rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1;
    color: var(--tone);
    background: color-mix(in srgb, var(--tone) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--tone) 55%, transparent);
}
.rarity-bulk-head h2 { font-size: 1.2rem; margin: 0 0 0.3rem; color: var(--pv-text); }
.rarity-bulk-sub { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; font-size: 0.78rem; color: var(--pv-text-dim); }
.rarity-bulk-tag { padding: 0.12rem 0.55rem; border-radius: 999px; border: 1px solid; font-weight: 700; font-size: 0.75rem; }

.rarity-bulk-fan {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0.4rem 0 1.1rem;
    min-height: 7.6rem;
}
.rarity-bulk-thumb {
    width: 3.9rem;
    aspect-ratio: 5 / 7;
    flex: none;
    margin-left: -1.1rem;
    border-radius: 8px;
    overflow: hidden;
    border: 2px solid var(--rc, #888);
    background: var(--pv-surface2);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45);
}
.rarity-bulk-thumb:first-child { margin-left: 0; }
.rarity-bulk-thumb:nth-child(1) { transform: rotate(-8deg) translateY(3px); }
.rarity-bulk-thumb:nth-child(2) { transform: rotate(-4deg) translateY(1px); }
.rarity-bulk-thumb:nth-child(3) { transform: rotate(0deg) translateY(-2px); z-index: 1; }
.rarity-bulk-thumb:nth-child(4) { transform: rotate(4deg) translateY(1px); }
.rarity-bulk-thumb:nth-child(5) { transform: rotate(8deg) translateY(3px); }
.rarity-bulk-thumb:nth-child(6) { transform: rotate(10deg) translateY(4px); }
.rarity-bulk-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rarity-bulk-thumb-more {
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--rc, var(--pv-text));
    background: color-mix(in srgb, var(--rc, #888) 14%, var(--pv-surface));
}

.rarity-bulk-body { margin: 0 0 1rem; font-size: 0.95rem; line-height: 1.5; color: var(--pv-text); text-align: center; }

.rarity-bulk-progress { background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: 12px; padding: 0.75rem 0.9rem; }
.rarity-bulk-progress-top { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; font-size: 0.76rem; color: var(--pv-text-dim); margin-bottom: 0.5rem; }
.rarity-bulk-progress-nums { font-variant-numeric: tabular-nums; color: var(--pv-text); font-size: 0.88rem; }
.rarity-bulk-progress-nums strong { color: var(--tone); }
.rarity-bulk-arrow { color: var(--pv-text-dim); margin: 0 0.15rem; }
.rarity-bulk-bar { position: relative; height: 0.5rem; border-radius: 999px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
.rarity-bulk-bar-change,
.rarity-bulk-bar-solid { position: absolute; inset: 0 auto 0 0; border-radius: 999px; transition: width 0.35s ease; }
.rarity-bulk-bar-change { background: color-mix(in srgb, var(--tone) 45%, transparent); }
.rarity-bulk-bar-solid { background: var(--rc, var(--tone)); }

.rarity-bulk-note { margin: 0.8rem 0 1.2rem; font-size: 0.78rem; line-height: 1.45; color: var(--pv-text-dim); text-align: center; }

.rarity-bulk-actions { display: flex; gap: 0.7rem; }
.rarity-bulk-actions .btn-google { width: auto; flex: 1; justify-content: center; }
.rarity-bulk-confirm {
    flex: 1.4;
    padding: 0.8rem 1.2rem;
    border: none;
    border-radius: 10px;
    font-size: 0.95rem;
    font-weight: 700;
    color: #0d0f1f;
    background: var(--tone);
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s, filter 0.15s;
}
.rarity-bulk-is-remove .rarity-bulk-confirm { color: #fff; }
.rarity-bulk-confirm:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 6px 20px color-mix(in srgb, var(--tone) 40%, transparent); }
.rarity-bulk-confirm:focus-visible, .rarity-bulk-actions .btn-google:focus-visible { outline: 2px solid var(--tone); outline-offset: 2px; }
.rarity-bulk-confirm:disabled { opacity: 0.6; cursor: progress; }

@media (max-width: 480px) {
    #rarity-bulk-modal { padding: 0.75rem; }
    .rarity-bulk-modal-content { padding: 1.1rem 1rem 1rem; }
    .rarity-bulk-head { gap: 0.7rem; margin-bottom: 0.9rem; }
    .rarity-bulk-head h2 { font-size: 1.05rem; }
    .rarity-bulk-thumb { width: 3rem; margin-left: -0.9rem; }
    .rarity-bulk-fan { min-height: 6rem; padding-bottom: 0.8rem; }
}

/* ============================================
   BLOG (/blog e /blog/{slug}) — ver app-blog.js e app/routers/blog.py.
   .blog-article também é usado na pré-visualização do Admin Hub.
   ============================================ */
.blog-subtitle { color: var(--pv-text-dim); margin: -0.4rem 0 1.6rem; max-width: 60ch; }

.blog-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.4rem;
}
@media (max-width: 960px) { .blog-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .blog-grid { grid-template-columns: minmax(0, 1fr); } }

.blog-card {
    display: flex;
    flex-direction: column;
    background: var(--pv-surface);
    border: 1px solid var(--pv-border);
    border-radius: 16px;
    overflow: hidden;
    text-decoration: none;
    color: var(--pv-text);
    transition: transform 0.18s, border-color 0.18s, box-shadow 0.18s;
}
.blog-card:hover, .blog-card:focus-visible {
    transform: translateY(-3px);
    border-color: rgba(255, 79, 129, 0.55);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
}
.blog-card:focus-visible { outline: 2px solid var(--pv-accent); outline-offset: 2px; }
.blog-card-cover {
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, var(--pv-surface2), #241a3a);
    display: grid;
    place-items: center;
    overflow: hidden;
}
.blog-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card-cover-fallback { font-size: 2.6rem; opacity: 0.55; }
.blog-card-body { display: flex; flex-direction: column; gap: 0.45rem; padding: 1rem 1.15rem 1.2rem; flex: 1; }
.blog-card-date { font-size: 0.75rem; color: var(--pv-accent2); letter-spacing: 0.02em; }
.blog-card-title { margin: 0; font-size: 1.1rem; line-height: 1.3; text-wrap: balance; }
.blog-card-summary {
    margin: 0;
    color: var(--pv-text-dim);
    font-size: 0.88rem;
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.blog-card-more { margin-top: auto; padding-top: 0.5rem; font-size: 0.85rem; font-weight: 600; color: var(--pv-accent); }

.blog-pagination { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0.4rem; margin: 2rem 0 1rem; }
.blog-page-link, .blog-page-gap {
    min-width: 2.3rem;
    padding: 0.45rem 0.8rem;
    text-align: center;
    border-radius: 10px;
    font-size: 0.88rem;
    font-variant-numeric: tabular-nums;
    text-decoration: none;
}
.blog-page-link { border: 1px solid var(--pv-border); background: var(--pv-surface); color: var(--pv-text); }
a.blog-page-link:hover { border-color: var(--pv-accent); }
.blog-page-current { background: var(--pv-accent); border-color: var(--pv-accent); color: #fff; font-weight: 700; }
.blog-page-disabled { opacity: 0.4; }
.blog-page-gap { color: var(--pv-text-dim); padding-left: 0.2rem; padding-right: 0.2rem; }

.blog-post { max-width: 760px; margin: 0 auto; }
.blog-back { display: inline-block; margin-bottom: 1.4rem; }
.blog-post-header { margin-bottom: 1.4rem; }
.blog-post-date { display: block; font-size: 0.82rem; color: var(--pv-accent2); margin-bottom: 0.5rem; }
.blog-post-title { margin: 0; font-size: 2rem; line-height: 1.2; text-wrap: balance; }
@media (max-width: 600px) { .blog-post-title { font-size: 1.55rem; } }
.blog-post-cover { width: 100%; border-radius: 16px; margin-bottom: 1.6rem; display: block; }

.blog-article { font-size: 1.02rem; line-height: 1.75; color: var(--pv-text); overflow-wrap: anywhere; }
.blog-article > * { margin: 0 0 1.15rem; }
.blog-article h2, .blog-article h3, .blog-article h4 { line-height: 1.3; margin: 2rem 0 0.7rem; text-wrap: balance; }
.blog-article h2 { font-size: 1.5rem; }
.blog-article h3 { font-size: 1.2rem; }
.blog-article h4 { font-size: 1.05rem; color: var(--pv-accent2); }
.blog-article a { color: var(--pv-accent2); text-decoration: underline; text-underline-offset: 2px; }
.blog-article a:hover { color: var(--pv-accent); }
.blog-article ul, .blog-article ol { padding-left: 1.4rem; }
.blog-article li { margin-bottom: 0.35rem; }
.blog-article blockquote {
    padding: 0.7rem 1.1rem;
    border-left: 3px solid var(--pv-accent);
    background: var(--pv-surface);
    border-radius: 0 10px 10px 0;
    color: var(--pv-text-dim);
}
.blog-article hr { border: none; height: 1px; background: var(--pv-border); margin: 2rem 0; }
.blog-article code { background: var(--pv-surface2); padding: 0.1rem 0.4rem; border-radius: 6px; font-size: 0.9em; }
.blog-article pre { background: var(--pv-surface2); padding: 1rem; border-radius: 12px; overflow-x: auto; }
.blog-article pre code { background: none; padding: 0; }
.blog-article img { max-width: 100%; height: auto; border-radius: 12px; display: block; }
.blog-article figure { margin: 1.6rem 0; }
.blog-article figcaption { margin-top: 0.5rem; font-size: 0.82rem; color: var(--pv-text-dim); text-align: center; }
