/* ==========================================================================
   Digiliza — Cartões de visita digitais
   Todo valor de cor, fonte, espaço e forma vem de tokens.css.
   Nenhum HEX e nenhum nome de fonte literal neste arquivo.

   Mobile-first: o layout base é o de 360px e vale em qualquer largura.
   Não há media query de largura — o cartão é fluido até --card-max-width.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* O body é flex, então main é item flex e encolhia ao conteúdo: os três
   cartões renderizavam com larguras diferentes (305/292/292px a 360px) e o
   --card-max-width nunca era atingido. A largura do cartão passava a ser
   decidida pelo comprimento do cargo.

   Escopado em .palco, não em `main` nu: a home tem o próprio layout e herdar
   display:flex daqui empilha a listagem na horizontal. */
.palco {
  width: 100%;
  display: flex;
  justify-content: center;
}

body {
  margin: 0;
  min-height: 100vh;
  padding: var(--space-4);
  display: flex;
  align-items: flex-start;
  justify-content: center;

  background: var(--color-bg-subtle);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-relaxed);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; height: auto; }

/* Superfícies que o navegador desenha por conta própria e que, deixadas no
   padrão, não pertencem a design system nenhum. */
::selection {
  background: var(--color-accent-soft);
  color: var(--color-text);
}

a { color: inherit; }

/* Foco visível e consistente em tudo que recebe teclado. */
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* --------------------------------------------------------------------------
   Cartão
   -------------------------------------------------------------------------- */

.cartao {
  width: 100%;
  max-width: var(--card-max-width);
  padding: 0 var(--space-5) var(--space-6);

  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  text-align: center;
}

/* ---- Topo: logo entre dois grafismos de pixel ---- */

.cartao__topo {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6) 0 var(--space-5);
}

.cartao__logo {
  /* Regra da marca: mínimo digital de 24px. Ficamos acima disso. */
  height: var(--logo-height);
  min-height: var(--logo-height-min);
  width: auto;
}

/* ---- Faixa de pixels: o grafismo da marca que monta o cartão ----

   Grade fixa de 36 colunas em fr, então a faixa acompanha a largura do
   cartão e o padrão não quebra. aspect-ratio mantém cada pixel quadrado. */

.cartao__faixa {
  display: grid;
  grid-template-columns: repeat(36, 1fr);
  grid-template-rows: repeat(3, auto);
  gap: 2px;
  /* Sangra até as bordas do cartão, por cima do padding lateral. */
  margin: 0 calc(var(--space-5) * -1);
  padding: var(--space-3) var(--space-3) 0;
}

.cartao__faixa span {
  grid-column: var(--x);
  grid-row: var(--y);
  aspect-ratio: 1;
  border-radius: 1px;
  background: var(--color-accent);
  opacity: var(--o);
}

/* ---- O momento: a faixa assenta e o conteúdo se resolve atrás dela ----

   Uma coreografia só, não efeitos espalhados. Ease-out exponencial, e o
   estado de repouso já é o final — sem animação, o cartão aparece pronto. */

@keyframes assentar-pixel {
  from {
    opacity: 0;
    transform: translate(var(--dx), var(--dy)) scale(0.3);
  }
  to {
    opacity: var(--o);
    transform: none;
  }
}

/* Sem fade. O opacity:0 era o custo inteiro do First Contentful Paint:
   medido em quatro variantes, as duas que começam transparentes ficam em
   ~610ms e as duas que mantêm opacidade 1 pintam junto com o primeiro pixel
   (~70ms). O Chrome não conta conteúdo transparente como "contentful".

   O borrão é inocente e fica: com o ease-out exponencial ele já caiu para
   ~1px aos 100ms, então o texto resolve rápido e continua legível o tempo
   todo — que era a razão de limitá-lo a 5px. */
@keyframes resolver {
  from {
    transform: translateY(12px);
    filter: blur(5px);
  }
  to {
    transform: none;
    filter: blur(0);
  }
}

.cartao__faixa span {
  animation: assentar-pixel 620ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
  animation-delay: calc(var(--i) * 13ms);
}

.cartao > *:not(.cartao__faixa) {
  animation: resolver 520ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
  /* Sem atraso na base. A versão anterior somava 180ms antes do primeiro
     bloco e empurrava o First Contentful Paint para 785ms — contra 58ms com
     movimento reduzido. Quem escaneia um QR via tela branca por quase um
     segundo antes de qualquer coisa aparecer.

     Agora a cascata começa no frame zero e só escalona a partir daí: o
     conteúdo pinta de imediato e a faixa assenta em volta dele. */
  animation-delay: calc(var(--ordem) * 45ms);
}

/* ---- Foto ---- */

/* O invólucro recorta e carrega o anel; a imagem se move e aproxima dentro
   dele. Sem isto não dá para dar zoom: transform e clip aplicados ao próprio
   <img> escalam também o recorte, aumentando o círculo em vez do rosto.

   Retrato de meio corpo em quadro quadrado é o caso comum de foto
   corporativa, e nele o rosto ocupa pouco do quadro. --foto-zoom aproxima,
   --foto-pos escolhe para onde. Ambos opcionais, por pessoa. */
.cartao__retrato {
  display: block;
  width: var(--foto-size);
  height: var(--foto-size);
  /* Largura fixa em bloco ignora o text-align:center do cartão; o auto
     lateral é o que traz o retrato para o meio. */
  margin-block: var(--space-2) var(--space-5);
  margin-inline: auto;
  border-radius: var(--radius-full);
  overflow: hidden;
  background: var(--color-surface-sunken);
  box-shadow: 0 0 0 3px var(--color-surface), 0 0 0 6px var(--color-accent);
}

.cartao__foto {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--foto-pos, 50% 50%);
  transform: scale(var(--foto-zoom, 1));
  transform-origin: var(--foto-pos, 50% 50%);
}

/* ---- Nome e cargo ---- */

.cartao__nome {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  /* Escala entre o H3 e o H2 do portal, conforme a largura da tela.
     O piso é 1.75rem e não o H3 cheio: a 360px o nome ficava em 24px,
     só 1,7x o cargo. Em 28px a distância vira 2x e o nome volta a ser
     o herói do cartão, sem empurrar o cargo para duas linhas. */
  font-size: clamp(1.75rem, 7.5vw, var(--text-h2));
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

.cartao__cargo {
  margin: 0 0 var(--space-6);
  color: var(--color-text-muted);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* Uma linha sobre o que a empresa faz. Sem ela o cartão é um catálogo de
   links: quem escaneia no corredor não tem como decidir se vale responder. */
.cartao__proposta {
  margin: 0 0 var(--space-6);
  color: var(--color-text);
  font-size: var(--text-caption);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* --------------------------------------------------------------------------
   Botões — alvo de toque mínimo de 44px (--tap-target-min)
   -------------------------------------------------------------------------- */

.cartao__acoes {
  display: grid;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.botao {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);

  /* Altura fixa, não mínima: o ícone do secundário difere do primário e os
     botões acabavam com 48 e 50px. */
  min-height: 3rem;
  padding: var(--space-3) var(--space-4);

  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: var(--text-button);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
  text-decoration: none;

  transition: background-color var(--duration) var(--ease),
              border-color var(--duration) var(--ease),
              transform var(--duration) var(--ease);
}

/* Tiffany como protagonista, conforme a regra da marca.
   Texto Cinza, não branco: branco sobre Tiffany dá 1,80:1 e reprova em AA.
   Cinza sobre Tiffany dá 7,35:1 (AAA). Ver BRANDING.md §3.5. */
.botao--principal {
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  border: 2px solid var(--color-accent);
}

.botao--secundario {
  background: var(--color-surface);
  color: var(--color-text);
  border: 2px solid var(--color-border-strong);
}

@media (hover: hover) {
  .botao--principal:hover { background: var(--color-accent-hover);
                            border-color: var(--color-accent-hover); }
  .botao--secundario:hover { border-color: var(--color-accent);
                             background: var(--color-bg-subtle); }
}

.botao:active { transform: translateY(1px); }

.icone { flex: none; }

/* Diz o que o botão faz antes de a pessoa arriscar o toque. Baixar arquivo
   de um site alcançado por QR de desconhecido é o ponto de maior hesitação
   do cartão, e era o único sem nenhuma palavra de tranquilização. */
.cartao__dica-acao {
  margin: calc(var(--space-2) * -1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--text-micro);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* --------------------------------------------------------------------------
   LinkedIn pessoal — separado das redes da empresa, de propósito
   -------------------------------------------------------------------------- */

.pessoal {
  display: flex;
  align-items: center;
  gap: var(--space-3);

  min-height: var(--tap-target-min);
  padding: var(--space-3) var(--space-4);

  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface-sunken);
  text-align: left;
  text-decoration: none;

  transition: border-color var(--duration) var(--ease),
              background-color var(--duration) var(--ease);
}

@media (hover: hover) {
  .pessoal:hover { border-color: var(--color-accent); background: var(--color-bg-subtle); }
}

.icone--pessoal { color: var(--color-text); }

.pessoal__texto { display: flex; flex-direction: column; }

.pessoal__rotulo {
  font-size: var(--text-caption);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

.pessoal__dica {
  color: var(--color-text-muted);
  font-size: var(--text-micro);
  line-height: var(--leading-snug);
}

/* --------------------------------------------------------------------------
   Redes da empresa
   -------------------------------------------------------------------------- */

.cartao__redes { margin-top: var(--space-6); }

.cartao__subtitulo {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  font-family: var(--font-sans);
  font-size: var(--text-micro);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* Grade fixa em vez de flex-wrap: com cinco redes a fileira quebrava 4+1 a
   320px, deixando um ícone órfão na segunda linha. Três colunas cabem em
   qualquer largura que suportamos, e o comportamento passa a ser
   determinístico em vez de emergente. */
.redes {
  display: grid;
  grid-template-columns: repeat(3, var(--tap-target-min));
  justify-content: center;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rede {
  display: flex;
  align-items: center;
  justify-content: center;

  /* Cada ícone é um alvo de toque cheio, não só o glifo. */
  width: var(--tap-target-min);
  height: var(--tap-target-min);

  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  color: var(--color-text);

  transition: border-color var(--duration) var(--ease),
              background-color var(--duration) var(--ease),
              color var(--duration) var(--ease);
}

@media (hover: hover) {
  .rede:hover {
    border-color: var(--color-accent);
    background: var(--color-accent);
    color: var(--color-text-on-accent);
  }
}

/* --------------------------------------------------------------------------
   Rodapé
   -------------------------------------------------------------------------- */

.cartao__rodape {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);

  color: var(--color-text-muted);
  font-size: var(--text-caption);
  line-height: var(--leading-snug);
}

.cartao__rodape p { margin: 0 0 var(--space-2); }
.cartao__rodape p:last-child { margin-bottom: 0; }

.cartao__rodape a {
  /* Empilhados e com altura de alvo real: antes eram dois links de 18px de
     altura separados por 10px, lado a lado. Num corredor, com o celular
     numa mão só, isso é erro de toque garantido. */
  display: inline-block;
  min-height: var(--tap-target-min);
  padding-block: var(--space-3);
  color: var(--color-text);
  text-decoration-color: var(--color-accent);
  text-underline-offset: 3px;
}

@media (hover: hover) {
  .cartao__rodape a:hover { color: var(--color-accent-hover); }
}

.cartao__evento {
  margin-top: var(--space-3);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Acessibilidade: corta o movimento, preserva o feedback

   Some o deslocamento (único movimento real do cartão) e qualquer animação.
   As transições de cor ficam: são elas que sinalizam hover e foco, e cor não
   é gatilho vestibular. Ver a nota da seção 9 de tokens.css.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    /* Zerar o delay junto é obrigatório: com animation-fill-mode backwards, o
       elemento segura o estado inicial durante o delay. Zerar só a duração
       deixaria o cartão em branco esperando o delay passar. */
    animation-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* A montagem é o movimento; sem ela o cartão simplesmente já está pronto. */
  .cartao__faixa span,
  .cartao > *:not(.cartao__faixa) {
    animation: none;
  }

  /* O botão para de deslocar ao ser pressionado; a cor segue respondendo. */
  .botao {
    transition-property: background-color, border-color;
  }
  .botao:active {
    transform: none;
  }
}
