/* Tema escuro da Biblioteca: base compartilhada por TODAS as telas da biblioteca
   (vitrine, livro, carrinho, entrega, leitor).
   O CHECKOUT NÃO USA ISTO de propósito: ele é branco e sem fantasia. Ver
   `checkout/index.html` e a seção "O tema termina na porta do checkout" no CLAUDE.md.

   As regras que só existem na vitrine (trilho, estante, luz de categoria) seguem
   inline no `index.html`: aqui mora só o que mais de uma tela usa de fato. */

:root {
  --void: oklch(0.08 0.028 300);
  --veil-1: oklch(0.13 0.045 298);
  --veil-2: oklch(0.10 0.035 288);
  --silver: oklch(0.93 0.035 290);
  --silver-dim: oklch(0.72 0.055 292);
  --whisper: oklch(0.78 0.045 295);
  /* acento frio, espectral: o dourado quente é a linguagem do Método Cálice */
  --spectral: oklch(0.86 0.09 285);
  --tinta: oklch(0.05 0.02 300);

  /* FONTE DOS TEXTOS PEQUENOS (decidido em 20/08/2026).
     A Cormorant Garamond é bonita grande e ilegível pequena: altura de x baixa,
     traço fino e itálico por padrão nesta tela. Abaixo de uns 16px ela vira
     borrão, e era isso que fazia aviso legal, contador e notas de apoio
     parecerem "difíceis de ler" sem que o problema fosse tamanho nem contraste.
     A mística mora no título (Cinzel) e no texto grande (Cormorant); o que é
     informação funcional usa a fonte do sistema, que já vem otimizada pra
     tamanho pequeno na tela de quem está lendo. Não trocar por outra serifada. */
  --fonte-ui: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }

/* `[hidden]` PRECISA VENCER, e sem isto ele não vence (achado em 21/08/2026).
   O navegador declara `[hidden] { display: none }` na folha dele, mas qualquer
   regra de AUTOR que defina `display` ganha da folha do navegador, mesmo com
   especificidade igual ou menor. Como `.barra`, `.barra .grim` e `.ancora` todas
   declaram `display`, o atributo `hidden` que o JS liga e desliga não fazia nada
   nesses elementos: "MEU CARRINHO 0" aparecia na página do livro com o carrinho
   vazio, e a barra do carrinho aparecia na vitrine pra quem nunca guardou nada,
   que é justamente o contrário do que o comentário no HTML de cada uma dizia.
   Passou despercebido na revisão de 20/08 porque quem revisa tem o carrinho
   cheio. Não remover: o `hidden` de três telas depende desta linha. */
[hidden] { display: none !important; }
body {
  background: var(--void);
  color: var(--silver);
  font-family: 'Cormorant Garamond', Georgia, serif;
  overflow-x: hidden;
}
a { color: var(--spectral); text-decoration: none; }
a:hover { color: var(--silver); }
/* Anel de foco pra quem navega por teclado. Era 2px na cor do acento, que é
   quase branca: virava um retângulo branco em volta do elemento inteiro, e o
   navegador restaura o foco ao voltar de uma página, então ele reaparecia
   sozinho sem ninguém ter apertado tecla nenhuma. Agora é fino e translúcido, e
   quem tem realce próprio (a capa na vitrine) desliga este e usa o dele. */
:focus-visible { outline: 1px solid oklch(0.86 0.09 285 / .5); outline-offset: 3px; border-radius: 4px; }

.page {
  position: relative;
  min-height: 100vh;
  /* Coluna flex por causa das PÁGINAS CURTAS (carrinho vazio, estados de erro
     da entrega). O `min-height: 100vh` estica o `.page` até o fim da tela, mas o
     conteúdo acaba antes: sem isto o rodapé legal para no meio da tela com um
     vão grande embaixo. Com a coluna e o `margin-top: auto` do rodapé, ele desce
     pro fim quando a página é curta e continua logo abaixo do conteúdo quando
     ela é longa. A vitrine nunca mostrou o problema porque nunca fica abaixo de
     100vh. (Achado do Yan em 21/08/2026, no carrinho vazio.) */
  display: flex;
  flex-direction: column;
  /* 20px, o MESMO respiro que separa o aviso legal dos links de Termos e
     Privacidade. Eram 60px, e o bloco inteiro ficava boiando longe do fim da
     página. Repetir a medida em vez de escolher um número novo é o que faz o
     fim da página ler como um bloco só, e não como três coisas soltas.
     A página do livro sobrescreve isto no celular: lá existe uma barra fixa no
     rodapé que precisa de espaço reservado. */
  padding-bottom: 20px;
  /* véu em camadas: gramática herdada do Cálice, invertida pro escuro */
  background:
    radial-gradient(ellipse 120% 42% at 50% -4%, var(--veil-1), transparent 66%),
    radial-gradient(ellipse 90% 34% at 8% 42%, oklch(0.15 0.06 300 / .5), transparent 70%),
    radial-gradient(ellipse 90% 34% at 96% 76%, var(--veil-2), transparent 70%);
}
.grain {
  position: fixed; inset: 0; pointer-events: none; z-index: 3; opacity: .05;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- poeira etérea: dezenas, não milhares, e só em transform ---------- */
.dust { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 1; }
.mote {
  position: absolute; bottom: -14px; border-radius: 50%;
  background: radial-gradient(circle, var(--spectral) 0%, transparent 68%);
  animation: rise linear infinite;
  will-change: transform, opacity;
}
@keyframes rise {
  0%   { transform: translate3d(0,0,0) scale(1); opacity: 0; }
  14%  { opacity: .7; }
  50%  { transform: translate3d(14px, -46vh, 0) scale(.86); }
  86%  { opacity: .22; }
  100% { transform: translate3d(-10px, -96vh, 0) scale(.55); opacity: 0; }
}

/* ---------- capa: mesma matéria na vitrine, no livro e no carrinho ---------- */
.capa {
  position: relative;
  aspect-ratio: 2 / 3;
  /* A largura da faixa colorida em volta da arte. Escala com o tamanho da capa:
     8px valem para os 186px da vitrine (4,3% da largura), e uma capa de 60px com
     8px de faixa vira quase so faixa. Cada tela que usa a capa menor redefine
     esta variavel; a linha branca fica em 1px em todo tamanho de proposito,
     porque fio de cabelo nao escala, ele so deixa de ser fio. */
  --borda: 8px;
  border-radius: 4px;
  overflow: hidden;
  display: flex; align-items: flex-end;
  background-color: var(--tone-a);
  background-image: linear-gradient(158deg, var(--tone-a), var(--tone-b) 92%);
  background-size: cover; background-position: center;
  /* luz volumétrica: várias sombras de raio crescente, todas tingidas: nunca uma preta só */
  box-shadow:
    0 1px 2px oklch(0.05 0.02 300 / .6),
    0 5px 10px oklch(0.05 0.02 300 / .45),
    0 14px 26px oklch(0.05 0.02 300 / .34),
    0 26px 46px oklch(0.05 0.02 300 / .24),
    inset 0 0 0 1px oklch(0.93 0.035 290 / .16);
  transition: transform .35s cubic-bezier(.2,.8,.3,1), box-shadow .35s ease;
}
/* superfície: luz de cima-esquerda + vinheta, pra o gradiente ler como matéria */
.capa::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background:
    radial-gradient(ellipse 78% 52% at 26% 12%, oklch(1 0 0 / .16), transparent 62%),
    radial-gradient(ellipse 110% 76% at 50% 62%, transparent 34%, oklch(0.05 0.02 300 / .58) 100%);
}
/* A arte entra recuada, dentro da moldura, e a faixa em volta continua sendo o
   gradiente de espera do próprio livro, o mesmo dos que ainda não têm capa.
   Até 26/08/2026 a arte sangrava até a borda e engolia a moldura, que some sobre
   desenho denso. Recuada, o livro volta a ter borda no trilho. */
.capa.com-arte::after {
  content: ''; position: absolute; inset: var(--borda); z-index: 0;
  background-image: var(--arte);
  background-size: cover; background-position: center;
  border-radius: 1px;
}

/* moldura fina: em código, nunca dentro da arte */
.moldura { position: absolute; inset: var(--borda); border: 1px solid oklch(0.93 0.035 290 / .3); border-radius: 1px; pointer-events: none; z-index: 2; }
.titulo {
  position: relative; width: 100%; z-index: 2;
  padding: 30px 11px 13px;
  text-align: center;
  background: linear-gradient(180deg, transparent, oklch(0.05 0.02 300 / .82) 62%);
  font-family: 'Cinzel', serif; font-weight: 500;
  font-size: clamp(13px, 3.8vw, 16px); line-height: 1.2; letter-spacing: .045em;
  color: var(--silver);
  text-shadow: 0 1px 8px oklch(0.05 0.02 300 / .95);
}

/* ---------- ornamento divisor ---------- */
.orn { display: flex; align-items: center; justify-content: center; gap: 13px; margin: 24px auto 0; max-width: 190px; color: var(--silver-dim); }
.orn .l { flex: 1; height: 1px; background: linear-gradient(90deg, transparent, var(--silver-dim), transparent); }
.orn svg { width: 13px; height: 13px; opacity: .85; }

/* ---------- botões ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: 'Cinzel', serif; font-size: 13.5px; letter-spacing: .13em;
  padding: 17px 26px; border-radius: 3px; border: 1px solid transparent;
  cursor: pointer; text-align: center; line-height: 1.2;
  transition: transform .2s ease, box-shadow .3s ease, background .3s ease, border-color .3s ease;
}
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .45; cursor: not-allowed; }

/* primário: o vidro iluminado: só um por tela, senão nenhum é primário */
.btn-selar {
  width: 100%;
  color: oklch(0.98 0.01 290);
  background: linear-gradient(168deg, oklch(0.36 0.15 300 / .95), oklch(0.24 0.11 290 / .95));
  border-color: oklch(0.86 0.09 285 / .45);
  box-shadow:
    0 2px 6px oklch(0.05 0.02 300 / .5),
    0 10px 24px oklch(0.4 0.16 300 / .3),
    inset 0 1px 0 oklch(1 0 0 / .18);
}
.btn-selar:hover {
  background: linear-gradient(168deg, oklch(0.42 0.17 300 / .98), oklch(0.28 0.13 290 / .98));
  border-color: oklch(0.86 0.09 285 / .75);
  box-shadow:
    0 2px 6px oklch(0.05 0.02 300 / .5),
    0 14px 34px oklch(0.45 0.18 300 / .42),
    inset 0 1px 0 oklch(1 0 0 / .26);
}
/* estado "já está no carrinho": confirma sem parecer um segundo primário */
.btn-selar.guardado {
  background: linear-gradient(168deg, oklch(0.22 0.05 290 / .9), oklch(0.16 0.04 288 / .9));
  border-color: oklch(0.86 0.09 285 / .3);
  color: var(--whisper);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / .08);
}

/* FECHAR A COMPRA: verde, e só ele (21/08/2026).
   O site inteiro é roxo e prata, então roxo virou a cor de "guardar mais um
   livro": é o que a pessoa faz a maior parte do tempo. Fechar o pedido é uma
   ação de natureza diferente, e o verde já significa confirmação em todo lugar
   daqui (desconto aplicado, selo da entrega, Pix confirmado) antes de significar
   isso em qualquer loja da internet.
   A regra que sustenta o efeito: UM verde por tela. No carrinho ele é o
   FINALIZAR COMPRA, e é por isso que o "QUERO ESTE" do trilho ficou roxo mesmo
   sendo botão preenchido. Dois verdes disputando o mesmo clique não somam. */
.btn-fechar {
  width: 100%;
  color: oklch(0.99 0.008 150);
  background: linear-gradient(168deg, oklch(0.55 0.15 152 / .95), oklch(0.38 0.12 155 / .95));
  border-color: oklch(0.8 0.15 152 / .5);
  box-shadow:
    0 2px 6px oklch(0.05 0.02 300 / .5),
    0 10px 24px oklch(0.55 0.15 152 / .28),
    inset 0 1px 0 oklch(1 0 0 / .2);
}
.btn-fechar:hover {
  background: linear-gradient(168deg, oklch(0.61 0.16 152 / .98), oklch(0.43 0.13 155 / .98));
  border-color: oklch(0.82 0.16 152 / .8);
  box-shadow:
    0 2px 6px oklch(0.05 0.02 300 / .5),
    0 14px 34px oklch(0.6 0.17 152 / .4),
    inset 0 1px 0 oklch(1 0 0 / .28);
}

/* secundário: contorno, sem preenchimento */
.btn-fantasma {
  color: var(--whisper);
  background: oklch(0.93 0.035 290 / .04);
  border-color: oklch(0.93 0.035 290 / .22);
}
.btn-fantasma:hover { color: var(--silver); border-color: oklch(0.93 0.035 290 / .5); background: oklch(0.93 0.035 290 / .08); }

/* ---------- barra de navegação da biblioteca ---------- */
.barra {
  position: sticky; top: 0; z-index: 6;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 18px;
  background: oklch(0.08 0.028 300 / .82);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid oklch(0.93 0.035 290 / .1);
}
.barra .voltar, .barra .grim {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: 'Cinzel', serif; font-size: 11px; letter-spacing: .14em;
  color: var(--silver-dim); padding: 7px 4px;
}
.barra .voltar:hover, .barra .grim:hover { color: var(--silver); }
.barra svg { width: 15px; height: 15px; }
/* O número dentro do círculo. Estava na Cormorant, cujos algarismos são
   antiquários: o 1 e o 2 descem abaixo da linha de base, e o número nascia
   colado na borda de baixo do círculo mesmo com o centramento certo. Fonte do
   sistema, `line-height: 1` e altura fixa resolvem, e `tabular-nums` mantém o
   círculo do mesmo tamanho de 1 pra 9. */
.contador {
  display: inline-grid; place-items: center;
  min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 999px;
  font-family: var(--fonte-ui); font-size: 11.5px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
  background: var(--spectral); color: oklch(0.12 0.05 300);
}
.contador[hidden] { display: none; }

/* ---------- aviso legal (roda em toda tela de venda) ----------
   Duas passadas nele no mesmo dia, e a segunda não desfaz a primeira.
   Primeira: estava em 12.5px de Cormorant num cinza fraco e não dava pra ler. É
   o texto que protege a operação, e ilegível ele não protege nada.
   Segunda e terceira: ficou grande demais pro papel dele, competindo com a
   venda. Desceu pra 13px e depois pra 11.5px, com o contraste baixando junto.
   O que sustenta as duas coisas ao mesmo tempo (menor E ainda legível) é ter
   saído da serifada: em Cormorant, 11.5px não se lê. Se precisar encolher de
   novo, o limite é este: abaixo daqui ele volta a ser decorativo, e aviso legal
   decorativo não protege nada. */
.rodape-legal {
  position: relative; z-index: 2;
  /* `auto` empurra o rodapé pro fim da coluna flex quando a página é curta. Em
     página longa não tem efeito nenhum: não sobra espaço pra distribuir. */
  margin: auto auto 0;
  max-width: 440px;
  padding: 54px 24px 0;
}
.rodape-legal::before {
  content: ''; display: block; width: 44px; height: 1px; margin: 0 auto 26px;
  background: linear-gradient(90deg, transparent, oklch(0.93 0.035 290 / .22), transparent);
}
/* O AVISO ENCOLHEU PELO TEXTO, NÃO PELA FONTE (21/08/2026).
   Ele já estava em 11,5px e continuava pesando na tela: eram duas frases longas
   ocupando três linhas no celular. Diminuir mais o corpo só deixaria ilegível um
   texto que existe pra proteger a operação. Cortar a redundância ("oferecidos
   para o seu bem-estar pessoal", "de pessoa para pessoa") tira metade do volume
   e não tira nada da proteção: o que protege é a ressalva, não o número de
   palavras. Se um dia isto voltar a crescer, cortar texto de novo antes de mexer
   no tamanho. */
.rodape-legal p {
  margin: 0; text-align: center;
  font-family: var(--fonte-ui);
  font-size: 11px; line-height: 1.55; color: oklch(0.56 0.022 293);
}
/* Os links continuam maiores e mais claros que o parágrafo de propósito: o
   aviso é para quem quiser ler, mas Termos e Privacidade precisam ser ACHÁVEIS
   por quem foi atrás deles. */
.rodape-legal nav { margin-top: 20px; text-align: center; font-family: var(--fonte-ui); font-size: 12.5px; }
.rodape-legal nav a { margin: 0 12px; color: oklch(0.8 0.05 292); }
.rodape-legal nav a:hover { color: var(--silver); }

/* ---------- toque no celular: NÃO EXISTE REALCE, e é decisão ----------
   Histórico curto, porque a tentação de "melhorar" isso volta:
   1) o realce era `:hover`, que em tela de toque dispara no toque, gruda depois
      que o dedo sai e às vezes nem dispara;
   2) virou classe `.tocado` por pointerdown, desligada quando o dedo andava
      mais que 8px. Ficou correto e continuou ruim de usar: quem arrasta a
      prateleira encosta num livro antes de puxar, então a capa subia e voltava
      no mesmo gesto. Um piscar que só existe quando a pessoa NÃO quis clicar.
   Num trilho horizontal o dedo pousa em cima de um item toda vez que rola. Não
   há limiar que separe "toquei" de "comecei a arrastar" no instante do pousar,
   porque a intenção ainda não aconteceu. O feedback de toque no celular é a
   página abrindo. `@media (hover: hover)` continua guardando o lift no desktop,
   onde o ponteiro passa sem tocar em nada. */

@media (prefers-reduced-motion: reduce) {
  /* A poeira PARA, mas não some. Antes ela sumia por inteiro, e como o Windows
     costuma vir com "efeitos de animação" desligado, o desktop do Yan ficava sem
     atmosfera nenhuma enquanto o celular tinha. Poeira parada continua sendo
     poeira; o que a regra pede é ausência de movimento, não de enfeite. */
  .mote { animation: none; opacity: .38; }
  .capa, .btn { transition: none; }
}
