/* ==========================================================================
   PILHA DE CARDS COM SWIPE — prefixo swipe-
   Duas colunas: o argumento da dobra à esquerda, e à direita uma pilha de
   cinco fotos em que a de cima se arrasta, voa para fora e volta pelo fundo.

   Tokens usados:
     --display --sans     tipografia do número/título do card e do contador
     --ease               curva única do projeto — acomodação da pilha e voo
     --radius-media       canto do card
     --radius-pill        disco dos botões
     --accent             número do card e realce dos botões
     --dark-rgb           véu da legenda e sombra da pilha
     --light              texto sobre a foto (ilha escura, ver abaixo)
     --fg-2 --fg-muted    botões e contador, herdados do escopo de tom
     --rule --rule-2      cor de carregamento do card e borda dos botões

   O CARD É UMA ILHA ESCURA. O que está sobre a foto lê --light, e não --fg:
   assim a mesma pilha roda numa seção .sec-paper sem virar texto escuro
   sobre véu escuro. O que está fora da foto — botões, contador — continua
   lendo o escopo de tom da seção.

   A POSIÇÃO INTEIRA DE UM CARD SAI DE UM NÚMERO SÓ. Cada card carrega
   --swipe-n (0 = topo) e daí vêm deslocamento, escala, inclinação e z-index.
   O script não conhece a fórmula: ele reescreve os cinco números e o CSS
   remonta a pilha. Mesmo canal do midia/galeria-pasta (--i/--a) e do
   listas/baralho-sticky (--deck-i), pela mesma razão: mudar o desenho da
   pilha não pode exigir mexer no JavaScript.
   ========================================================================== */

.swipe{
  --swipe-max:420px;      /* largura do palco; 320px abaixo de 760px */
  --swipe-step:12px;      /* faixa que cada card deixa aparecer abaixo do de cima */
  --swipe-shrink:.045;    /* quanto cada nível encolhe (4,5% por degrau) */
  --swipe-depth:4;        /* cards à vista; os demais ficam em .is-back */
  /* A cauda da pilha sai por baixo da caixa do palco: (depth - 1) degraus.
     Reservada em margem para não invadir o que vem embaixo no mobile. */
  --swipe-tail:calc((var(--swipe-depth) - 1) * var(--swipe-step));

  /* Durações de INTERAÇÃO, locais por natureza (--dur do core é .9s, certo
     para entrada de seção e lento para um gesto responder). O script lê
     --swipe-fly-dur para dimensionar o próprio fallback de timeout: se você
     mudar a duração do voo, mude aqui e o script acompanha. Em segundos. */
  --swipe-fly-dur:.5s;    /* voo do card para fora */
  --swipe-back-dur:.55s;  /* acomodação da pilha e volta do card ao lugar */

  /* Fração da largura do palco a partir da qual soltar o card manda ele
     embora. .3 = 30%; abaixo de .18 o card escapa em qualquer tremida. */
  --swipe-threshold:.3;

  /* Troca sozinha, em SEGUNDOS. 0 = desligada, que é o padrão: a dobra não
     se mexe sem alguém pedir. Ver a variação "avanço automático" na ficha. */
  --swipe-auto:0;

  /* O card voa 140% da própria largura: passa da borda da coluna. Quem corta
     é este recorte, e é o mesmo recurso do midia/carrossel-perfis. Nada aqui
     é sticky, então overflow:hidden não custa nada. */
  overflow:hidden;
}

/* ---------------------------------------------------------------- grade */
/* Duas colunas de mesma largura. minmax(0,1fr) e não 1fr: sem o mínimo zero,
   uma linha longa do apoio empurra a coluna e o palco encolhe fora de hora. */
.swipe-grid{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(32px,5vw,80px);
  align-items:center;
}

.swipe-copy{min-width:0}

/* ---------------------------------------------------------------- navegação */
.swipe-nav{
  display:flex;align-items:center;gap:12px;
  margin-top:clamp(28px,3.6vw,42px);
}

/* Disco de ícone. Não é .btn do core: .btn é pílula de TEXTO com padding
   fixo, e espremer 42px nela seria brigar com a primitiva em vez de usá-la.
   Esta é a TERCEIRA aparição do mesmo disco na biblioteca (já existe em
   midia/galeria-scroll-horizontal e hero/duas-colunas-produto), ou seja, o
   gatilho do §6 do contrato — a proposta de promover ao core está registrada
   na ficha, em Gotchas. Enquanto ela não acontece, a regra fica aqui, com o
/* O disco de ícone é a primitiva .btn-disc do core (core/base.css): forma,
   cor, hover e estado desabilitado vêm de lá, e o markup traz as duas
   classes. Esta pasta escrevia as mesmas seis linhas — eram cinco cópias
   idênticas na biblioteca, e o §6 manda promover na terceira. */

/* Tabular para o contador não dançar ao passar de 1 para 4 — a fonte de
   display tem larguras diferentes por algarismo, e o bloco inteiro treme. */
.swipe-count{
  margin-left:6px;
  font-family:var(--display);font-weight:700;font-size:12px;
  letter-spacing:.14em;color:var(--fg-muted);
  font-variant-numeric:tabular-nums;
}

/* ---------------------------------------------------------------- palco */
/* A caixa do palco é o card de cima, e só ele: 4/5, que é o recorte de
   retrato das fotos do showroom. A cauda da pilha (os degraus de baixo)
   fica FORA dessa caixa, e é por isso que existe a margem de baixo — sem
   ela, no mobile, o quarto degrau cai por cima do olho da coluna de texto. */
.swipe-stage{
  position:relative;
  width:100%;
  max-width:var(--swipe-max);
  aspect-ratio:4/5;
  margin-inline:auto;
  margin-block-end:var(--swipe-tail);
}
/* Sem perspective aqui, de propósito: nenhum card gira em rotateX/rotateY,
   e perspective sobre transformações 2D não muda um pixel — medido, a caixa
   do card sai idêntica com e sem. No midia/galeria-pasta ela é obrigatória
   porque lá a aba tomba de verdade; aqui seria enfeite de folha de estilo. */

/* O <ul> cobre o palco inteiro e é ele que recebe o foco: assim o anel do
   core (3px para fora) desenha em volta do card de cima, e não em volta de
   uma caixa maior que ninguém vê. Nenhum overflow aqui — o card precisa
   sair da caixa para voar; quem corta é a seção. */
.swipe-stack{
  position:absolute;inset:0;
  cursor:grab;
  /* O gesto horizontal é do card; o vertical continua rolando a página.
     Sem isto, arrastar de lado no celular trava a rolagem — e arrastar de
     cima para baixo deixaria de rolar a página. */
  touch-action:pan-y;
  /* Arrastar sobre a foto e a legenda selecionaria as duas. */
  user-select:none;-webkit-user-select:none;
  -webkit-tap-highlight-color:transparent;
}
.swipe-stack:active{cursor:grabbing}

/* ---------------------------------------------------------------- card */
/* transform-origin na BASE, e isso não é gosto. Com a origem no centro, o
   encolhimento come exatamente o deslocamento: num card de 525px de altura,
   scale(.955) sobe a borda de baixo em 11,8px contra os 12px que o
   translateY desceu — sobra 0,2px de faixa e a pilha lê como um card só.
   Ancorada na base, a faixa que aparece é exatamente --swipe-step por
   degrau, em qualquer tamanho de tela, e a conta não depende da altura. */
.swipe-card{
  position:absolute;inset:0;
  overflow:hidden;
  border-radius:var(--radius-media);
  background:var(--rule);
  /* Fio de 1px: é ele que separa um card do outro na faixa de 12px que
     sobra. Sem o fio, quatro fotos escuras empilhadas leem como uma mancha
     só — a pilha existe na tela mas não se conta. Fica em --light a 14% e
     não em --rule-2 porque o fio está sobre FOTO, não sobre a seção: em
     .sec-paper, --rule-2 é quase preto e o fio some contra a imagem. */
  border:1px solid color-mix(in srgb,var(--light) 14%,transparent);
  box-shadow:0 22px 54px rgba(var(--dark-rgb),.5);
  transform-origin:50% 100%;
  z-index:calc(10 - var(--swipe-n,0));
  /* min(--swipe-n,1) zera a inclinação do card de cima. Não é capricho: o
     arrasto escreve rotate() a partir de zero, e um card em repouso a -2°
     daria um salto visível de 2° no pointerdown. Do segundo degrau em
     diante a inclinação entra inteira, e é ela que faz a pilha ler como
     cartas jogadas na mesa e não como uma sanfona. */
  transform:translateY(calc(var(--swipe-n,0) * var(--swipe-step)))
            scale(calc(1 - var(--swipe-n,0) * var(--swipe-shrink)))
            rotate(calc(var(--swipe-rot,0deg) * min(var(--swipe-n,0),1)));
  transition:transform var(--swipe-back-dur) var(--ease),
             opacity var(--swipe-back-dur) var(--ease);
  /* Repetidos aqui, e não só no .swipe-stack: touch-action NÃO se herda —
     o navegador percorre os ancestrais do alvo do toque, então o valor da
     pilha já valeria, mas quem lê o card isolado não tem como saber disso.
     user-select desce por herança e está aqui pelo mesmo motivo de leitura. */
  touch-action:pan-y;
  user-select:none;-webkit-user-select:none;
}

/* Fora da pilha visível. É a vaga de pouso: o card que voou vira este e
   reaparece parado, invisível, sem cruzar a pilha de volta. pointer-events
   fecha o alvo — opacity:0 continua clicável, e um card invisível comendo o
   clique da faixa de baixo é o tipo de defeito que ninguém encontra. */
.swipe-card.is-back{opacity:0;pointer-events:none}

/* Durante o arrasto quem escreve transform é o script, inline. A transição
   sai da frente para o card não ficar 0,55s atrás do dedo. */
.swipe-card.is-dragging{transition:none;z-index:30;will-change:transform}

/* O voo. 140% da própria largura tira o card da coluna; a opacidade cai em
   70% do tempo para ele não atravessar o texto da esquerda ainda opaco
   quando o gesto foi para esse lado. --swipe-fly (1 ou -1) é o único valor
   que o script escreve aqui: a direção. */
.swipe-card.is-out{
  z-index:20;opacity:0;
  transform:translateX(calc(var(--swipe-fly,1) * 140%))
            rotate(calc(var(--swipe-fly,1) * 22deg));
  transition:transform var(--swipe-fly-dur) var(--ease),
             opacity calc(var(--swipe-fly-dur) * .7) var(--ease);
}

/* Um quadro sem transição, para o card ser teleportado sem desenhar o
   caminho: é como ele volta da posição de voo para a vaga do fundo, e como
   o "anterior" o joga para fora antes de trazê-lo de volta. Vem DEPOIS de
   .is-out de propósito — as duas têm a mesma especificidade, e é a ordem
   que decide quem manda no transition. */
.swipe-card.is-instant{transition:none}

.swipe-img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;
  /* O corte é por card, no style do <li>: retrato de estúdio tem o assunto
     no terço de cima e foto de ambiente tem no meio. Cravar um valor único
     decapitaria uma das duas famílias. */
  object-position:var(--swipe-focus,50% 38%);
  pointer-events:none;
}

/* ---------------------------------------------------------------- legenda */
/* Dentro da foto, ancorada embaixo, sobre gradiente mais desfoque mascarado
   (contrato §6). Véu em caixa reta abre borda dura e lê chapado; a máscara
   é o que dissolve a quina de cima do véu. */
.swipe-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;flex-direction:column;align-items:flex-start;gap:7px;
  padding:84px 24px 22px;
  background:linear-gradient(to top,
    rgba(var(--dark-rgb),.94) 0%,
    rgba(var(--dark-rgb),.58) 46%,
    transparent 100%);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 44%,transparent 100%);
  -webkit-mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 44%,transparent 100%);
}

.swipe-num{
  font-family:var(--display);font-weight:700;
  font-size:clamp(28px,3.2vw,42px);line-height:1;letter-spacing:-.02em;
  color:var(--accent);
}
.swipe-title{
  font-family:var(--display);font-weight:700;
  font-size:clamp(19px,1.7vw,24px);line-height:1.15;letter-spacing:-.02em;
  color:var(--light);
}
/* Sem max-width: quem define a medida é a largura do card, e ela já é
   estreita. Um teto em ch aqui quebrava em duas linhas frases que cabiam
   numa — medido a 420px de palco, onde a caixa da legenda tem 372px e as
   cinco linhas do padrão editorial cabem inteiras. O limite real é
   editorial e está na ficha: até ~46 caracteres. */
.swipe-line{
  font-family:var(--sans);
  font-size:clamp(13px,1.15vw,15px);line-height:1.45;
  color:color-mix(in srgb,var(--light) 76%,transparent);
}

/* ---------------------------------------------------------------- movimento reduzido */
/* Sem voo e sem acomodação: a troca é instantânea. O gesto continua inteiro
   — arrastar é coisa pedida pela pessoa, não movimento imposto a ela — só
   que o card volta seco ao lugar em vez de deslizar. O script lê a mesma
   preferência e pula a sequência do voo, senão ficaria esperando um
   transitionend que nunca chega. */
@media(prefers-reduced-motion:reduce){
  .swipe-card{transition:none}
  .swipe-card.is-out{transition:none}
  .swipe-btn{transition:none}
}

/* ---------------------------------------------------------------- toque */
/* Sem ponteiro não existe hover nem cursor de arrasto. Os botões continuam
   sendo a alternativa visível para quem não descobre o gesto. */
@media(hover:none){
  .swipe-stack{cursor:default}
  .swipe-stack:active{cursor:default}
}

/* ---------------------------------------------------------------- mobile */
/* Uma coluna, e a PILHA VEM PRIMEIRO: ela é o que faz parar de rolar. O
   texto vem embaixo, onde é lido por quem já parou. A ordem do DOM continua
   texto → pilha, que é a ordem de leitura correta para teclado e leitor de
   tela; quem troca é só a pintura. */
@media(max-width:760px){
  .swipe-grid{grid-template-columns:1fr;gap:clamp(28px,5vh,44px)}
  .swipe-stage{order:1;--swipe-max:320px}
  .swipe-copy{order:2}
}

@media(max-width:420px){
  .swipe{--swipe-step:10px}
  .swipe-cap{padding:70px 18px 18px;gap:6px}
  .swipe-nav{gap:10px}
}
