/* ==========================================================================
   Biblinha — App shell mobile
   Carregado DEPOIS de app.css e v3.css.

   Modelo:
   - celular: o app ocupa a tela inteira (nada muda);
   - telas maiores: html é o espaço externo e body é a coluna do app,
     com largura máxima --app-max, centralizada.

   O CSS de telas é mobile first: as antigas @media(max-width >= 500px) viraram
   regras base, então a coluna renderiza igual a um celular de --app-max.
   ========================================================================== */

:root {
    --app-max: 430px;
    /* 1vw "do app": igual a 1vw no celular, limitado à coluna em telas maiores. */
    --app-vw: calc(min(100vw, var(--app-max)) / 100);
    /* Margem externa de cada lado da coluna.
       SOMENTE para elementos position:fixed (50% = metade do viewport). */
    --app-gutter: max(0px, calc(50% - var(--app-max) / 2));
    --app-outer-bg: #7cb95a;
}

/* --------------------------------------------------------------------------
   1. Coluna do app
   -------------------------------------------------------------------------- */
body {
    width: 100%;
    max-width: var(--app-max);
    margin-inline: auto;
    min-height: 100vh;
    min-height: 100dvh;
    /* O .app-shell ocupa a altura restante (inclusive descontando o
       padding-top do topbar) sem gerar rolagem extra em telas curtas. */
    display: flex;
    flex-direction: column;
}

.app-shell {
    position: relative;
    flex: 1 0 auto;
    width: 100%;
    /* clip (e não hidden) não cria contêiner de rolagem: sticky continua funcionando. */
    overflow-x: clip;
}

/* --------------------------------------------------------------------------
   2. Elementos fixed presos à coluna
   No celular --app-gutter é 0, então continuam cobrindo a tela inteira.
   -------------------------------------------------------------------------- */
.topbar-v3,
.drawer-backdrop,
.chapter-wrong-modal,
.card-modal,
.books-loading,
.books-v4-sparkles,
.bib-v3 .page-shell-v3:has(.books-v4)::before {
    left: var(--app-gutter);
    right: var(--app-gutter);
}

.drawer-v3 {
    left: var(--app-gutter);
}

/* Fechado, o drawer fica deslocado para a esquerda; escondido para não
   aparecer no espaço externo (e sair da ordem de foco). */
.drawer-v3:not(.open) {
    visibility: hidden;
    transition: transform .36s var(--ease-spring), visibility 0s linear .36s;
}

.drawer-v3.open {
    visibility: visible;
    transition: transform .36s var(--ease-spring), visibility 0s;
}

.options-sheet {
    right: calc(var(--app-gutter) + 18px);
}

/* Decorativos de /biblia: mesma posição relativa à borda da coluna. */
.books-v4::before {
    left: calc(var(--app-gutter) - 95px);
}

.books-v4::after {
    right: calc(var(--app-gutter) - 130px);
}

/* --------------------------------------------------------------------------
   3. Espaço externo (só existe quando a tela é mais larga que a coluna)
   -------------------------------------------------------------------------- */
@media (min-width: 431px) {
    /* Com fundo próprio no html, o fundo do body deixa de ser propagado para
       a tela inteira e passa a pintar somente a coluna do app. */
    html {
        background: var(--app-outer-bg);
        /* Reserva o espaço da barra de rolagem: a coluna não "pula" quando o
           drawer trava a rolagem (body overflow:hidden). */
        scrollbar-gutter: stable;
    }

    /* Máscaras laterais: nada que transborde a coluna (drawer em transição,
       sombras, decorativos) aparece no espaço externo. */
    html::before,
    html::after {
        content: "";
        position: fixed;
        z-index: 2147483647;
        top: 0;
        bottom: 0;
        width: var(--app-gutter);
        background: var(--app-outer-bg);
        pointer-events: none;
    }

    html::before {
        left: 0;
    }

    html::after {
        right: 0;
    }
}

/* --------------------------------------------------------------------------
   4. Fundo das páginas preso à tela
   A arte sai do body (onde rolava junto com o conteúdo, e o
   background-attachment:fixed é ignorado no iOS) e vai para uma camada
   position:fixed do tamanho da coluna x altura da tela. O body mantém só a
   cor de fundo; o conteúdo rola por cima normalmente.
   (O /livro já usa camada própria equivalente no v3.css.)
   -------------------------------------------------------------------------- */
body.bib-v3 {
    /* A camada de z-index negativo fica acima da cor do body, não atrás dela. */
    isolation: isolate;
}

/* A entrada da página (pageIn) anima transform no body. Com fill "both" a
   animação continua valendo depois de terminar, e o navegador passa a tratar
   o body como referência dos position:fixed: as camadas de fundo (e topbar,
   modais etc.) rolavam junto e o fundo acabava, mostrando branco.
   Sem o fill final, o body volta ao normal quando a entrada termina; o estado
   final (opacidade 1, sem transform) é idêntico ao padrão. */
body.bib-v3.page-enter {
    animation-fill-mode: backwards;
}

body.bib-v3::before {
    content: "";
    position: fixed;
    z-index: -10;
    top: 0;
    left: var(--app-gutter);
    right: var(--app-gutter);
    height: 100vh;
    /* Altura com a barra do navegador recolhida: nunca sobra faixa sem arte. */
    height: 100lvh;
    pointer-events: none;
}

/* Padrão das telas comuns (antes no body). */
body.bib-v3:not(.is-immersive) {
    background-image: none;
}

body.bib-v3:not(.is-immersive)::before {
    background: url('../img/backgrounds/bg-pattern.webp') center top/760px auto repeat-y;
}

/* Home */
body.bib-v3:has(.home-v6) {
    background-image: none;
}

body.bib-v3:has(.home-v6)::before {
    background: url('../img/backgrounds/bg-home.webp') center top/cover no-repeat;
}

/* Capítulo */
body.bib-v3.is-immersive:has(.chapter-v6) {
    background-image: none;
}

body.bib-v3.is-immersive:has(.chapter-v6)::before {
    background: url('../img/backgrounds/bg-chapter.webp') center top/cover no-repeat;
}

/* Bíblia (lista de livros), Capítulo do dia, Coleção, Orações, Histórico e
   Perfil: mesmo fundo da tela de capítulos do livro (bg-garden-frame, igual
   ao body::before do .book-v6 no v3.css). */
body.bib-v3:has(.books-v4)::before,
body.bib-v3:has(.v3-daily-intro)::before,
body.bib-v3:has(.collection-screen)::before,
body.bib-v3:has(.v3-prayer-grid)::before,
body.bib-v3:has(.v3-history-intro)::before,
body.bib-v3:has(.v3-profile-hero)::before {
    background: #ddecad url('../img/backgrounds/bg-garden-frame.webp') center center/cover no-repeat;
}

/* Jogos: arte do prado (bg-crossword, a mesma das Palavras Cruzadas), a mais
   próxima da referência da tela; mesmo enquadramento (cover, centralizada). */
body.bib-v3:has(.games-screen)::before {
    background: #8fcf6a url('../img/backgrounds/bg-crossword.webp') center center/cover no-repeat;
}

/* Jornada do Quebra-cabeça (livros e capítulos de um livro): o mesmo fundo de
   antes (bg-garden-frame), agora na camada fixa das demais telas. */
body.bib-v3:has(.pzj-screen)::before {
    background: #eaf6b8 url('../img/backgrounds/bg-garden-frame.webp') center center/cover no-repeat;
}

/* Loja: mesma arte de sempre (bg-cards com o véu verde), só que na camada fixa
   das demais telas. Antes ela era pintada na própria .store-screen, então
   esticava junto com o conteúdo e rolava com ele. */
body.bib-v3:has(.store-screen)::before {
    background: linear-gradient(rgba(197,239,151,.58), rgba(170,225,115,.65)),
                url('../img/backgrounds/bg-cards.webp') center center/cover no-repeat;
}

/* Sem as camadas pintadas na section, para não cobrir o fundo fixo acima
   (o .game-screen traz fundo sólido, sombra e um ::before com radiais). */
body.bib-v3 .store-screen {
    background: none;
    box-shadow: none;
}

body.bib-v3 .store-screen::before {
    content: none;
}

/* Coleção: mesmo tratamento da loja acima — só o fundo fixo do body aparece,
   sem o verde pintado na própria section nem o ::before com radiais. */
body.bib-v3 .collection-screen {
    background: none;
    box-shadow: none;
}

body.bib-v3 .collection-screen::before {
    content: none;
}

/* Abrir envelope: a mesma arte de sempre (bg-cards, sem véu) sai da própria
   .envelope-screen, onde parecia um grande card de cantos arredondados, e vai
   para a camada fixa das demais telas. */
body.bib-v3:has(.envelope-screen)::before {
    background: url('../img/backgrounds/bg-cards.webp') center center/cover no-repeat;
}

body.bib-v3 .envelope-screen {
    background: none;
    box-shadow: none;
    border-radius: 0;
}

body.bib-v3 .envelope-screen::before {
    content: none;
}

/* Roleta: a mesma arte de sempre (bg-roulette) sai da própria .roulette-v4,
   onde esticava junto com o conteúdo e rolava com ele, e vai para a camada
   fixa das demais telas. */
body.bib-v3:has(.roulette-v4)::before {
    background: #b7ed54 url('../img/backgrounds/bg-roulette.webp') center center/cover no-repeat;
}

body.bib-v3 .roulette-v4 {
    background: none;
    box-shadow: none;
    border-radius: 0;
}

/* Coleção de Relíquias: arte própria (bg-relics-archipelago) na camada fixa
   das demais telas, com o mesmo enquadramento (cover, centralizada). */
body.bib-v3:has(.relics-screen)::before {
    background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.2)), url(../img/backgrounds/bg-relics-archipelago.webp) center center / cover no-repeat; background-color: #000000;
}

/* Palavras Cruzadas: arte própria (bg-crossword, prado com cachoeira) na
   camada fixa das demais telas, com o mesmo enquadramento (cover, centralizada). */
body.bib-v3:has(.crossword-screen)::before {
    background: #8fcf6a url('../img/backgrounds/bg-crossword.webp') center center/cover no-repeat;
}

/* Sai o fundo fixo anterior da /biblia (padrão verde com véu), para não
   haver duas camadas sobrepostas. */
.bib-v3 .page-shell-v3:has(.books-v4)::before {
    content: none;
}

/* --------------------------------------------------------------------------
   5. Topo do app no fluxo da página
   O header (menu, leão + progresso, opções) deixa de ser fixed: aparece no
   topo e sobe junto com o conteúdo. Sem fundo próprio: fica direto sobre o
   fundo decorativo da tela.
   -------------------------------------------------------------------------- */
.bib-v3 .topbar-v3 {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    /* O body reservava 98px para o topo fixed de 116px (o topo cobria 18px
       do início da página). Mantém o conteúdo exatamente onde estava. */
    margin-bottom: -18px;
}

/* O espaço antes reservado para o topo fixed não é mais necessário. */
body.bib-v3.bib-body {
    padding-top: 0;
}

/* Na Home o body já reservava a altura inteira do topo (116px). */
.bib-v3:has(.home-v6) .topbar-v3 {
    margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   6. Bordas da tela no iPhone (status bar, barra do Safari, "elástico")
   O Safari não pinta essas faixas com a camada fixa do item 4: usa a cor de
   fundo da página (canvas) e o theme-color. Antes os dois eram o verde do
   shell (e, a partir de 431px, como no iPhone Pro Max, o verde externo), o
   que criava uma faixa em cima e outra embaixo.
   Cada fundo informa a cor real da sua borda superior e inferior (medidas na
   própria arte), e o canvas passa a usar essas cores. Em desktop nada muda:
   o espaço externo continua com --app-outer-bg.
   -------------------------------------------------------------------------- */
:root {
    /* bg-pattern (telas comuns) */
    --page-edge-top: #a5dd7f;
    --page-edge-bottom: #a4dc7e;
}

:root:has(body.bib-v3 .home-v6) {
    --page-edge-top: #c1d67e;
    --page-edge-bottom: #6c953f;
}

:root:has(body.bib-v3.is-immersive .chapter-v6) {
    --page-edge-top: #2c83d8;
    --page-edge-bottom: #3e7059;
}

/* bg-garden-frame: Bíblia, livro, Capítulo do dia, Coleção, Orações,
   Histórico, Perfil e Jornada do Quebra-cabeça. */
:root:has(body.bib-v3 .books-v4),
:root:has(body.bib-v3 .book-v6),
:root:has(body.bib-v3 .v3-daily-intro),
:root:has(body.bib-v3 .collection-screen),
:root:has(body.bib-v3 .v3-prayer-grid),
:root:has(body.bib-v3 .v3-history-intro),
:root:has(body.bib-v3 .v3-profile-hero),
:root:has(body.bib-v3 .pzj-screen) {
    --page-edge-top: #b5cd68;
    --page-edge-bottom: #81aa4b;
}

/* bg-roulette (Roleta). */
:root:has(body.bib-v3 .roulette-v4) {
    --page-edge-top: #9de74b;
    --page-edge-bottom: #2a9d07;
}

/* bg-crossword (Palavras Cruzadas). */
:root:has(body.bib-v3 .crossword-screen) {
    --page-edge-top: #6cba95;
    --page-edge-bottom: #54982a;
}

/* bg-crossword (Jogos). */
:root:has(body.bib-v3 .games-screen) {
    --page-edge-top: #6cba95;
    --page-edge-bottom: #54982a;
}

/* bg-cards com o véu verde da loja. */
:root:has(body.bib-v3 .store-screen) {
    --page-edge-top: #9bd984;
    --page-edge-bottom: #85b553;
}

/* A cor do body fica atrás da camada fixa (nunca aparece na coluna); ela só
   serve de referência para o Safari na borda de baixo. */
body.bib-v3:not(.is-immersive),
body.bib-v3.is-immersive:has(.chapter-v6),
body.bib-v3.is-immersive:has(.roulette-v4) {
    background-color: var(--page-edge-bottom);
}

/* A camada fixa passa por baixo das áreas seguras quando o iOS as reserva
   (app na tela inicial, paisagem). Sem área segura env() é 0: nada muda.
   O /livro tem camada própria no v3.css (100dvh); recebe a mesma regra. */
body.bib-v3::before,
body.bib-v3.is-immersive:has(.book-v6)::before {
    top: calc(0px - env(safe-area-inset-top, 0px));
    height: calc(100vh + env(safe-area-inset-top, 0px) + env(safe-area-inset-bottom, 0px));
    height: calc(100lvh + env(safe-area-inset-top, 0px) + env(safe-area-inset-bottom, 0px));
}

/* Celular: o canvas (topo, rodapé e o elástico da rolagem) usa a cor da borda. */
@media (max-width: 430px) {
    html {
        background-color: var(--page-edge-top);
    }
}

/* Celulares com mais de 430px (iPhone Pro Max: 440px). A coluna continua com
   430px, mas o espaço externo de ~5px não é o "desktop": o fundo da tela passa
   a ocupar a largura toda e as faixas usam a cor da arte, não o verde externo.
   Telas com mouse (desktop) não entram aqui. */
@media (min-width: 431px) and (max-width: 500px) and (hover: none) and (pointer: coarse) {
    html {
        background: var(--page-edge-top);
    }

    html::before,
    html::after {
        content: none;
    }

    body.bib-v3::before,
    body.bib-v3.is-immersive:has(.book-v6)::before {
        left: 0;
        right: 0;
    }
}

/* --------------------------------------------------------------------------
   7. Telas fixas de jogo (Abrir envelope e Roleta), sem rolagem vertical
   No /envelope o gesto de rasgar é horizontal, e um arrasto que saía um pouco
   na vertical levava a página junto; na /roleta a tela é uma composição só
   (topo, título, roda e cronômetro). Só nessas telas (via :has, como as regras
   por página acima): o documento fica travado na altura visível, e a coluna
   .app-shell -> main -> tela ocupa exatamente essa altura.
   Abaixo de 440px de altura (celular deitado) nada disso vale e a tela rola
   como antes, para nunca cortar o conteúdo. Sem suporte a :has, idem.
   -------------------------------------------------------------------------- */
@media (min-height: 440px) {
    :root:has(body.bib-v3 .envelope-screen),
    :root:has(body.bib-v3 .roulette-v4) {
        height: 100%;
        overflow: hidden;
        /* Sem o "elástico" do Safari/Chrome puxando a página. */
        overscroll-behavior: none;
    }

    body.bib-v3:has(.envelope-screen),
    body.bib-v3:has(.roulette-v4) {
        /* Altura visível real: 100dvh acompanha as barras do Safari e do
           Chrome (aparecendo ou recolhidas); 100vh fica para quem não tem dvh. */
        height: 100vh;
        height: 100dvh;
        min-height: 0;
        overflow: hidden;
        overscroll-behavior: none;
    }

    body.bib-v3:has(.envelope-screen) .app-shell,
    body.bib-v3:has(.roulette-v4) .app-shell {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    body.bib-v3:has(.envelope-screen) .topbar-v3 {
        flex-shrink: 0;
    }

    body.bib-v3:has(.envelope-screen) .page-shell-v3,
    body.bib-v3:has(.roulette-v4) .page-shell-v3 {
        flex: 1 1 auto;
        min-height: 0;
        width: 100%;
        display: flex;
        flex-direction: column;
        /* Os 54px de sobra das telas que rolam viram só a área segura de baixo
           (barra de gestos do iPhone com o app na tela inicial). */
        padding-bottom: max(6px, env(safe-area-inset-bottom, 0px));
    }

    /* Ocupa o que sobra abaixo do header, no lugar do min-height de
       100dvh - 115px das telas de jogo (que, somado ao padding do main,
       deixava o documento sempre 45px mais alto que a tela; na roleta, o
       min-height de 100dvh da própria .roulette-v4). */
    body.bib-v3:has(.envelope-screen) .envelope-screen,
    body.bib-v3:has(.roulette-v4) .roulette-v4 {
        flex: 1 1 auto;
        min-height: 0;
    }

    /* Caber em telas baixas sem cortar nada: a largura do envelope (--env-w,
       que dimensiona palco, carta, halo, efeitos e instrução) ganha um limite
       pela altura da própria tela (cqh). O conteúdo vertical é 150px fixos
       (saldo, faixa do resultado, respiro do palco e botões de depois) +
       1,262 x W (o palco, que cresce com a largura). Em telas altas o limite
       não pesa e o envelope fica como sempre foi. */
    @supports (height: 1cqh) {
        body.bib-v3:has(.envelope-screen) .envelope-screen {
            container-type: size;
        }

        body.bib-v3:has(.envelope-screen) .envelope-screen .envelope-stage {
            --env-w: min(78%, 360px, calc((100cqh - 150px) / 1.262));
        }
    }

    /* Roleta: coluna topo -> título -> bloco de jogo (roda + cronômetro).
       Topo e título têm tamanho próprio, reduzido pela altura da tela (cqh da
       .roulette-v4) em telas baixas; o bloco de jogo fica com o resto. A roda
       é um quadrado de --wheel: o menor entre a largura, 540px e a altura do
       bloco menos o rodapé, então em telas baixas ela encolhe pela altura sem
       deformar, e o cronômetro vem logo abaixo dela. Sem container queries, a
       roda usa uma estimativa pela altura visível (dvh). */
    body.bib-v3:has(.roulette-v4) .roulette-v4 {
        display: flex;
        flex-direction: column;
        padding: clamp(6px, 2dvh, 18px) 12px clamp(4px, 1.5dvh, 16px);
    }

    body.bib-v3:has(.roulette-v4) .roulette-topbar-art,
    body.bib-v3:has(.roulette-v4) .roulette-title-art {
        flex: none;
    }

    body.bib-v3:has(.roulette-v4) .roulette-play {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        /* A sobra de altura vira três vãos iguais: acima da roda, entre a roda e
           o cronômetro e abaixo dele. Com justify-content:center a sobra ia toda
           para as pontas e a composição ficava torta: um buraco grande embaixo do
           título, a roda colada no cronômetro e outro buraco no fim. Sem margem
           fixa: o vão é o que a tela deixar, e em tela baixa (quando a roda já
           encolheu pela altura e a sobra é zero) nada muda. */
        justify-content: space-evenly;
        /* Cabe o maior dos três estados (cronômetro ~64px, botão ~59px). */
        --footer-h: 72px;
    }

    body.bib-v3:has(.roulette-v4) .roulette-stage {
        flex: none;
        width: min(calc(96 * var(--app-vw)), 540px, calc(100dvh - 338px));
    }

    body.bib-v3:has(.roulette-v4) .roulette-footer {
        flex: none;
        box-sizing: border-box;
        height: var(--footer-h);
        margin-top: 0;
        padding-top: 6px;
    }

    @supports (height: 1cqh) {
        body.bib-v3:has(.roulette-v4) .roulette-v4 {
            container-type: size;
        }

        body.bib-v3:has(.roulette-v4) .roulette-topbar-art {
            --top-btn: clamp(46px, 9.6cqh, 64px);
            --mascot: clamp(58px, 15cqh, 100px);
            grid-template-columns: var(--top-btn) 1fr var(--top-btn);
            margin-bottom: clamp(0px, 1cqh, 8px);
        }

        body.bib-v3:has(.roulette-v4) .roulette-icon-button {
            width: var(--top-btn);
            height: var(--top-btn);
        }

        body.bib-v3:has(.roulette-v4) .roulette-top-center {
            min-height: calc(var(--mascot) * 1.16);
            padding-top: calc(var(--mascot) * .34);
        }

        body.bib-v3:has(.roulette-v4) .roulette-top-mascot {
            width: var(--mascot);
        }

        body.bib-v3:has(.roulette-v4) .roulette-top-progress {
            width: min(100%, 392px, calc(var(--mascot) * 2.6));
        }

        /* Arte do título 986x329: 45cqh de largura = no máximo 15cqh de altura. */
        body.bib-v3:has(.roulette-v4) .roulette-title-art {
            width: min(98%, 690px, 45cqh);
            margin-bottom: clamp(0px, 1cqh, 12px);
        }

        body.bib-v3:has(.roulette-v4) .roulette-play {
            container-type: size;
            --wheel: min(100cqw, 540px, calc(100cqh - var(--footer-h)));
        }

        body.bib-v3:has(.roulette-v4) .roulette-stage {
            width: var(--wheel);
        }
    }
}

/* --------------------------------------------------------------------------
   8. Coleção de Relíquias, tela única sem rolagem vertical
   Mesmo modelo das telas fixas acima: o documento fica travado na altura
   visível (100dvh acompanha as barras do Safari/Chrome; 100vh para quem não
   tem dvh) e a coluna .app-shell -> main -> .relics-screen ocupa exatamente
   essa altura, abaixo do header. Dentro da tela, a sobra é distribuída em vãos
   iguais entre placa, ilhas/baús e pílula de progresso (v3.css, .relics-stage).
   O conteúdo mínimo é ~540px a 360px de largura e ~575px a 430px (placa,
   ilhas e baús crescem com a largura); abaixo de 600px de altura (celular
   deitado) nada disso vale e a tela rola como antes, para nunca cortar nada.
   -------------------------------------------------------------------------- */
@media (min-height: 600px) {
    :root:has(body.bib-v3 .relics-screen) {
        height: 100%;
        overflow: hidden;
        overscroll-behavior: none;
    }

    body.bib-v3:has(.relics-screen) {
        height: 100vh;
        height: 100dvh;
        min-height: 0;
        overflow: hidden;
        overscroll-behavior: none;
    }

    body.bib-v3:has(.relics-screen) .app-shell {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    body.bib-v3:has(.relics-screen) .topbar-v3 {
        flex-shrink: 0;
    }

    body.bib-v3:has(.relics-screen) .page-shell-v3 {
        flex: 1 1 auto;
        min-height: 0;
        width: 100%;
        display: flex;
        flex-direction: column;
        /* Os 54px de sobra das telas que rolam viram só a área segura de baixo. */
        padding-bottom: max(6px, env(safe-area-inset-bottom, 0px));
    }

    body.bib-v3:has(.relics-screen) .relics-screen {
        flex: 1 1 auto;
        min-height: 0;
    }
}
