/* ==========================================================================
   auth.css — Fluxo de autenticação (Onboarding + Auth Gate + Wizard)
   Depende de design-tokens.css
   ========================================================================== */

/* ─────────────────────────────────────────────────────────────
   0. SPLASH SCREEN — primeira tela do domínio raiz (pré-onboarding)
   HTML: view-customer-authentication-2.php linhas 19-27 (#authSplash)
   Some após 600ms via auth-gate.js quando o DOM está pronto.
   v4.77.8 — fundo escuro (preto azulado), logo maior, saída mais suave
───────────────────────────────────────────────────────────────*/
.auth-splash {
    position: fixed;
    inset: 0;
    z-index: 999999;
    background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-6, 24px);
    opacity: 1;
    transform: scale(1);
    transition: opacity 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94),
                transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    pointer-events: auto;
    will-change: opacity;
}

.auth-splash--hidden {
    opacity: 0;
    transform: scale(1.02);
    filter: blur(4px);
    pointer-events: none;
}

.auth-splash-logo {
    width: min(50vw, 200px);
    height: auto;
    max-height: 200px;
    object-fit: contain;
    border-radius: var(--radius-lg, 16px);
    box-shadow: 0 0 32px rgba(255, 255, 255, 0.12),
                0 8px 24px rgba(0, 0, 0, 0.35);
    animation: authSplashLogoPulse 1.6s var(--ease-out, cubic-bezier(0.4, 0, 0.2, 1)) infinite;
}

@keyframes authSplashLogoPulse {
    0%, 100% { transform: scale(1); opacity: 1; }
    50%      { transform: scale(0.96); opacity: 0.85; }
}

.auth-splash-dots {
    display: flex;
    gap: var(--space-2, 8px);
    align-items: center;
}

.auth-splash-dots span {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full, 9999px);
    background: #fff;
    opacity: 0.4;
    animation: authSplashDotBounce 1.2s infinite ease-in-out both;
}

.auth-splash-dots span:nth-child(1) { animation-delay: -0.32s; }
.auth-splash-dots span:nth-child(2) { animation-delay: -0.16s; }
.auth-splash-dots span:nth-child(3) { animation-delay: 0s; }

@keyframes authSplashDotBounce {
    0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
    40%           { transform: scale(1);   opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .auth-splash-logo,
    .auth-splash-dots span {
        animation: none;
    }
}

/* ─────────────────────────────────────────────────────────────
   0b. HEAD__APP — fundo sólido cor da marca (v4.77.30)
   Antes: banner-image do cliente + overlay dark para contraste.
   Agora: fundo chapado `var(--main-color)` igual ao header dos
   modais internos (.points-modal__header, .headModal canônico) —
   identidade visual unificada entre head do app e headers de modais.
   Sem background-image; background-color vence via !important pra
   anular style inline legado em caches antigos.
───────────────────────────────────────────────────────────────*/
.head__app {
    position: relative;
    isolation: isolate;
    background-color: var(--main-color, var(--color-brand, #3B82F6)) !important;
    background-image: none !important;
    color: #fff;
}
/* ::before desabilitado — não precisa de overlay quando fundo é sólido */
.head__app::before {
    content: none;
}
/* Garantia reforçada: TODO filho direto ou aninhado fica acima do overlay.
   Complementa `.head__app *{z-index:2}` do style.css:344 dando
   especificidade dedicada que cobre container-fluid, h2, p, logo, etc.
   v4.77.24: subiu para z-index:3 !important pra vencer qualquer overlay
   remanescente e blindar contra regressões (ex.: ::after do style.css:307
   que foi neutralizado, mas também contra qualquer nova pseudo-camada). */
.head__app > *,
.head__app .container-fluid,
.head__app .container-fluid > *,
.head__app h2,
.head__app p,
.head__app .logo,
.head__app .logo img,
.head__app .last__update,
.head__app #step-title,
.head__app #step-description {
    position: relative;
    z-index: 3 !important;
}

/* ─────────────────────────────────────────────────────────────
   1. BODY__APP no modo auth gate — ocupa a tela toda sem espaço vazio
───────────────────────────────────────────────────────────────*/
.body__app--auth-gate {
  min-height: 100dvh !important;
  padding: 0 !important;
  top: 0 !important;
  border-radius: 0 !important;
  display: flex;
  flex-direction: column;
}

.body__app--auth-gate > .container-fluid {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 0;
}

/* ─────────────────────────────────────────────────────────────
   2. AUTH GATE — container raiz
───────────────────────────────────────────────────────────────*/
.auth-gate {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* Remove outline azul do browser */
.auth-gate button,
.auth-gate button:focus,
.auth-gate button:focus-visible,
.onboarding-swiper button,
.onboarding-swiper button:focus,
.onboarding-swiper button:focus-visible {
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

/* ─────────────────────────────────────────────────────────────
   3. ONBOARDING SWIPER — layout split: visual top + card bottom
───────────────────────────────────────────────────────────────*/
.onboarding-swiper {
  flex: 1;
  display: flex;
  flex-direction: column;
  position: relative;
  height: 100dvh;
  min-height: 100dvh;
  overflow: hidden;
  background: var(--bg-primary);
}

@keyframes gateSlideUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

.onboarding-entering {
  animation: gateSlideUp 0.38s var(--ease-spring) both;
}

/* ── Visual area (top, brand color) ── */
.onboarding-visual {
  flex: 1 1 0;
  min-height: 0;
  position: relative;
  background: var(--main-color, var(--color-brand));
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: background 0.6s var(--ease-spring);
}
/* Variações de tom por slide — sutil, mantém a identidade */
/* v4.77.2 — fallbacks atualizados p/ --color-brand (design-tokens.css) */
.onboarding-visual[data-slide="1"] {
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 85%, #1a1aff 15%);
}
.onboarding-visual[data-slide="2"] {
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 75%, #00b894 25%);
}

/* Decorative soft blobs */
.onboarding-visual__blob {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}
.onboarding-visual__blob--1 {
  width: 260px; height: 260px;
  top: -80px; right: -60px;
  background: rgba(255,255,255,0.08);
  animation: blobDrift1 8s ease-in-out infinite alternate;
}
.onboarding-visual__blob--2 {
  width: 180px; height: 180px;
  bottom: -60px; left: -40px;
  background: rgba(255,255,255,0.06);
  animation: blobDrift2 10s ease-in-out infinite alternate;
}

@keyframes blobDrift1 {
  from { transform: translate(0,0) scale(1); }
  to   { transform: translate(12px,-16px) scale(1.08); }
}
@keyframes blobDrift2 {
  from { transform: translate(0,0) scale(1); }
  to   { transform: translate(-10px,14px) scale(1.05); }
}

/* Illustration wrapper — hero presente (v4.77.45 — agrandado ainda mais) */
.onboarding-visual__illus {
  position: relative;
  /* 82% da largura até 380px (antes 62vw/300px — visual pequeno em 375x812). */
  width: min(82vw, 380px);
  height: min(82vw, 380px);
  max-width: 100%;
  z-index: 1;
}
/* Em viewports baixos, segura altura pra não comer o card de texto. */
@media (max-height: 700px) {
  .onboarding-visual__illus {
    width: min(62vw, 260px);
    height: min(62vw, 260px);
  }
}

/* Per-slide illustration */
.ob-illus {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(0.82) translateY(10px);
  transition: opacity 0.42s var(--ease-spring), transform 0.42s var(--ease-spring);
  pointer-events: none;
}
.ob-illus svg {
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 12px 32px rgba(0,0,0,0.18));
}
.ob-illus.active {
  opacity: 1;
  transform: scale(1) translateY(0);
  pointer-events: auto;
  animation: illusEntry 0.5s var(--ease-spring) both;
}

/* Moedas e estrela do slide 0 são alvos de clique */
.ob-coin,
.ob-star-center {
  cursor: pointer;
}
@keyframes illusEntry {
  0%   { opacity: 0; transform: scale(0.78) translateY(16px); }
  60%  { transform: scale(1.04) translateY(-3px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}

/* Botão pular — pill perfeitamente arredondada (v4.77.8)
   !important p/ vencer reset global .btn ou similar na cascade */
.onboarding-skip {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 10;
  background: rgba(255,255,255,0.18);
  border: none;
  outline: none;
  color: #fff;
  font-size: var(--font-sm);
  font-family: var(--font-family);
  font-weight: var(--weight-medium);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* padding horizontal maior + altura fixa p/ pill perfeita */
  padding: 0 var(--space-4) !important;
  height: 36px !important;
  min-height: 36px !important;
  line-height: 1;
  border-radius: 9999px !important;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.onboarding-skip:hover  { background: rgba(255,255,255,0.28); }
.onboarding-skip:focus  { outline: none; }

/* ── Card area (bottom, white) ── */
.onboarding-card {
  flex: 0 0 auto;
  background: var(--bg-primary);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  margin-top: calc(var(--space-6) * -1);
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-6) var(--space-6) var(--space-8);
  box-shadow: 0 -4px 24px rgba(0,0,0,0.08);
}

/* Slides container */
.onboarding-slides {
  width: 100%;
  position: relative;
  height: 80px;
  overflow: hidden;
}

/* Slide individual */
.onboarding-slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  opacity: 0;
  transform: translateX(32px);
  transition: opacity 0.32s var(--ease-out), transform 0.32s var(--ease-out);
  pointer-events: none;
}

.onboarding-slide.active {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}

.onboarding-slide.leaving {
  opacity: 0;
  transform: translateX(-32px);
}

.onboarding-title {
  font-size: var(--font-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-2);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.onboarding-desc {
  font-size: var(--font-sm);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
  max-width: 260px;
  margin: 0 auto;
}

/* Dots */
.onboarding-dots {
  display: flex;
  gap: var(--space-2);
  margin: var(--space-4) 0 var(--space-4);
}

/* v4.77.5 — dots 100% redondos (ativo maior, inativo menor) */
.onboarding-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--gray-200);
  cursor: pointer;
  flex: 0 0 auto;
  transition: width 0.3s var(--ease-spring), height 0.3s var(--ease-spring), background 0.3s ease;
}

.onboarding-dot.active {
  width: 10px;
  height: 10px;
  background: var(--main-color, var(--color-brand));
}

/* Botão próximo */
.onboarding-next {
  width: 100%;
  margin-top: 0;
}

/* ─────────────────────────────────────────────────────────────
   4. AUTH GATE FORM — tela de entrada
───────────────────────────────────────────────────────────────*/
.auth-gate__form {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  padding: 0;
  /* v4.77.78 — Animação gateSlideUp (translateY 20→0) removida do elemento
     base: ela disparava automaticamente sempre que o gate mudava de
     display:none → display:flex (ao sair do crossfade), causando "tremida
     colando no topo". Agora a animação de entrada é orquestrada 100% pelo
     .gate-fade-in (só opacity). Classe .gate-entering mantida pra quem
     precisar do slide-up explícito. */
}

/* v4.77.73 — Anti-flash: classe aplicada no HTML (step-welcome.php) pra
   garantir que o gate nasça invisível e oculto antes de qualquer JS rodar.
   auth-gate.js remove a classe no momento do fade-in controlado. Substitui
   os styles inline `opacity:0;visibility:hidden;display:none` que violavam
   a regra de separação de assets. */
.auth-gate__form.is-hidden-initial {
  display: none !important;
  opacity: 0;
  visibility: hidden;
}

.gate-entering { animation: gateSlideUp 0.35s var(--ease-spring) both; }

/* v4.77.56 — Hero compacto estilo Apple/Revolut: logo menor, título e
   subtitle em tamanho médio, MENOS padding vertical. O body abaixo
   recebe flex:1 e o CTA fica fixo no bottom — elimina o espaço morto
   característico de layouts centralized-vertical. */
.auth-gate__hero {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-6, 24px) var(--space-6, 24px) var(--space-5, 20px);
  text-align: center;
  background: var(--main-color, var(--color-brand));
}

@keyframes logoSpring {
  0%   { transform: scale(0.5); opacity: 0; }
  65%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); }
}

.auth-gate__logo-img {
  width: 88px;
  height: 88px;
  object-fit: contain;
  border-radius: var(--radius-lg, 16px);
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  margin-bottom: var(--space-3, 12px);
  animation: logoSpring 0.5s var(--ease-spring) both;
  background: #fff;
  padding: var(--space-2, 8px);
}

.auth-gate__title {
  font-size: var(--font-2xl, 24px) !important;
  font-weight: var(--weight-bold) !important;
  letter-spacing: -0.02em !important;
  color: #fff !important;
  margin: 0 0 var(--space-1, 4px) !important;
  line-height: var(--leading-tight) !important;
  text-align: center !important;
}

.auth-gate__subtitle {
  font-size: var(--font-sm, 13px);
  color: rgba(255,255,255,0.8);
  margin: 0;
  line-height: var(--leading-normal, 1.5);
}

/* Wave SVG entre hero e body */
.auth-gate__wave {
  display: block;
  width: 100%;
  margin-top: -20px;
  margin-bottom: -8px;
  position: relative;
  z-index: 2;
}

/* v4.77.72 — Ordem natural do DOM: social (primary, 1-tap) → divisor →
   CPF (fallback) → benefícios (âncora inferior). Sem `order` nem
   `margin-top:auto` — a lista de benefícios preenche o bottom com
   valor, não com ar. Gap uniforme distribui o respiro. */
.auth-gate__body {
  flex: 1;
  background: var(--bg-primary);
  border-radius: 0;
  padding: var(--space-6, 24px) var(--space-6, 24px) calc(var(--space-6, 24px) + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 16px);
  justify-content: flex-start;
}

/* Benefícios — âncora inferior, empurrada pro final pra respirar
   mesmo em telas altas e colar próximo ao safe-area em telas baixas. */
.auth-gate__benefits {
  list-style: none;
  margin: auto 0 0;
  padding: var(--space-4, 16px);
  display: flex;
  flex-direction: column;
  gap: var(--space-3, 12px);
  background: var(--gray-50, #f7f8fa);
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--gray-100, #eef0f3);
}

.auth-gate__benefit {
  display: flex;
  align-items: center;
  gap: var(--space-3, 12px);
  font-size: var(--font-sm, 13px);
  color: var(--text-primary);
  line-height: var(--leading-normal, 1.4);
}

.auth-gate__benefit-icon {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm, 8px);
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 10%, transparent);
  color: var(--main-color, var(--color-brand));
}

.auth-gate__benefit-icon svg {
  width: 18px;
  height: 18px;
}

.auth-gate__benefit-text {
  flex: 1;
  font-weight: var(--weight-medium, 500);
}

/* ─────────────────────────────────────────────────────────────
   5. BOTÕES SOCIAIS CUSTOMIZADOS
───────────────────────────────────────────────────────────────*/
/* v5.3.36 — botões sociais lado a lado (row). Cada botão divide o espaço
   igualmente via flex:1. Em telas muito estreitas (<340px), volta pra coluna
   pra não espremer o texto. */
.auth-gate__social {
  display: flex;
  flex-direction: row;
  gap: var(--space-2);
}
@media (max-width: 339px) {
  .auth-gate__social { flex-direction: column; gap: var(--space-3); }
}

/* v4.77.2 — altura normalizada p/ 48px (igual --button-height primário)
   v5.3.36 — width:100% trocado por flex:1 pra dividir espaço quando lado a lado.
   white-space:nowrap + min-width:0 evita quebra de linha + overflow. */
.auth-btn-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  flex: 1 1 0;
  min-width: 0;
  height: 48px;
  min-height: var(--touch-target);
  border-radius: var(--radius-md);
  font-size: var(--font-md);
  font-family: var(--font-family);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
  border: 1.5px solid var(--gray-200);
  background: var(--bg-primary);
  color: var(--text-primary);
  transition: background var(--transition-fast), transform var(--transition-fast), box-shadow var(--transition-fast);
  -webkit-tap-highlight-color: transparent;
  outline: none;
}
@media (max-width: 339px) {
  .auth-btn-social { flex: 0 0 auto; width: 100%; }
}

.auth-btn-social:hover  { background: var(--gray-50); box-shadow: var(--shadow-sm); }
.auth-btn-social:active { transform: scale(0.98); background: var(--gray-100); }
.auth-btn-social:focus  { outline: none; }

.auth-btn-social__icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* v5.3.38 — labels longa/curta. Default mostra a longa (desktop e telas largas).
   Em telas estreitas (≤480px), troca pra label curta ("Google" / "Apple")
   pra caber lado a lado sem cortar o texto.
   `!important` é necessário porque o reset do tema mobile aplica `display: block`
   em spans dentro de buttons e venceria a regra simples por especificidade. */
.auth-btn-social .auth-btn-social__label-long  { display: inline !important; }
.auth-btn-social .auth-btn-social__label-short { display: none   !important; }
@media (max-width: 480px) {
  .auth-btn-social .auth-btn-social__label-long  { display: none   !important; }
  .auth-btn-social .auth-btn-social__label-short { display: inline !important; }
}

/* Apple: fundo preto */
.auth-btn-apple {
  background: #000;
  border-color: #000;
  color: #fff;
}
.auth-btn-apple:hover  { background: #1a1a1a; box-shadow: var(--shadow-sm); }
.auth-btn-apple:active { background: #333; }
.auth-btn-apple .auth-btn-social__icon { color: #fff; }

/* ─────────────────────────────────────────────────────────────
   6. DIVIDER
───────────────────────────────────────────────────────────────*/
.auth-gate__divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text-muted);
  font-size: var(--font-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.auth-gate__divider::before,
.auth-gate__divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--gray-200);
}

/* ─────────────────────────────────────────────────────────────
   7. INPUT CPF + BOTÃO CONTINUAR
───────────────────────────────────────────────────────────────*/
.auth-gate__cpf-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.auth-gate__input-wrap {
  position: relative;
  border-radius: var(--radius-md);
  /* v4.77.70: altura fixa igual ao input — antes o wrap crescia além de 48px
     (quando havia erro/feedback abaixo) e o scan-line ::after com height:100%
     herdava essa altura, vazando além do input até quase o botão Continuar. */
  height: 48px;
}

/* Scan line: linha que varre o campo quando em foco.
   v4.77.70: agora posicionada com inset:0 e overflow clipado pelo clip-path
   do wrap — impossível vazar pra fora do input. */
.auth-gate__input-wrap::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, transparent, color-mix(in srgb, var(--main-color, var(--color-brand)) 60%, transparent), transparent)
    no-repeat left top / 100% 2px;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s;
  clip-path: inset(0 round var(--radius-md));
}
.auth-gate__input-wrap:focus-within::after {
  opacity: 1;
  animation: scanLine 1.2s ease-in-out forwards;
}
@keyframes scanLine {
  0%   { background-position: left 0; }
  /* v4.77.70: para exatamente no bottom do input (calc(100% - 2px) garante
     que o último frame não ultrapasse a altura do wrap). */
  100% { background-position: left calc(100% - 2px); }
}

/* v4.77.2 — ícone tokenizado + altura input/botão normalizada p/ 48px (primary canônico) */
.auth-gate__input-icon {
  position: absolute;
  left: var(--space-4);
  top: 24px; /* 48px input height / 2 */
  transform: translateY(-50%);
  width: 16px;
  line-height: 1;
  color: var(--text-muted);
  font-size: var(--font-md);
  pointer-events: none;
  z-index: 1;
}

.auth-gate__input {
  padding-left: var(--space-10) !important;
  height: 48px !important;
  font-size: var(--font-md);
  border-radius: var(--radius-md) !important;
}

.auth-gate__input.is-invalid {
  border-color: var(--color-error) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 12%, transparent) !important;
}

.auth-gate__btn-continue {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 48px;
  font-size: var(--font-md);
  font-weight: var(--weight-semibold);
  position: relative;
  overflow: hidden;
}

/* Shimmer: brilho deslizando da esquerda para direita */
.auth-gate__btn-continue::after {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 60%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
  animation: shimmer 2.2s ease-in-out infinite;
}
@keyframes shimmer { to { left: 160%; } }

/* Spinner */
.auth-gate__spinner {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid rgba(255,255,255,0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.65s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ─────────────────────────────────────────────────────────────
   8. WIZARD PROGRESS V2
───────────────────────────────────────────────────────────────*/
.wizard-progress-v2 {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2) 0 var(--space-4);
}

.wizard-step-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

/* v4.77.2 — font-size tokenizado (antes 16px) */
.wizard-step-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  background: var(--gray-100);
  border: 2px solid var(--gray-200);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: var(--font-md);
  transition: background 0.3s var(--ease-spring), border-color 0.3s ease, color 0.3s ease, transform 0.3s var(--ease-spring);
}

.wizard-step-label {
  font-size: var(--font-xs);
  color: var(--text-muted);
  font-weight: var(--weight-medium);
  transition: color 0.3s ease;
}

.wizard-step-item.active .wizard-step-icon {
  background: var(--main-color, var(--color-brand));
  border-color: var(--main-color, var(--color-brand));
  color: #fff;
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.wizard-step-item.active .wizard-step-label {
  color: var(--main-color, var(--color-brand));
  font-weight: var(--weight-semibold);
}

.wizard-step-item.done .wizard-step-icon {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #fff;
}
.wizard-step-item.done .wizard-step-label { color: var(--color-success); }

/* v4.77.2 — margin-bottom tokenizado */
.wizard-step-connector {
  flex: 1;
  height: 2px;
  background: var(--gray-200);
  margin: 0 var(--space-2);
  margin-bottom: var(--space-4);
  border-radius: 2px;
  min-width: var(--space-6);
}

/* ─────────────────────────────────────────────────────────────
   9. GENDER CHIPS
───────────────────────────────────────────────────────────────*/
.gender-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.gender-chips--nowrap {
  flex-wrap: nowrap;
  gap: var(--space-2);
}

/* v4.77.8 — pill perfeita: radius-full forçado na cascade */
.gender-chips--nowrap .gender-chip {
  flex: 1;
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-xs);
  white-space: nowrap;
  text-align: center;
  min-height: var(--touch-target);
  border-radius: 9999px !important;
}

/* v4.77.8 — min-height garante touch target 44px; radius-full forçado */
.gender-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2) var(--space-4);
  min-height: var(--touch-target);
  border-radius: 9999px !important;
  border: 1.5px solid var(--gray-200);
  background: var(--gray-50);
  color: var(--text-secondary);
  font-size: var(--font-sm);
  font-family: var(--font-family);
  line-height: 1;
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.gender-chip:focus { outline: none; }
.gender-chip:hover { border-color: var(--main-color, var(--color-brand)); color: var(--main-color, var(--color-brand)); }
.gender-chip.selected {
  border-color: var(--main-color, var(--color-brand));
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 10%, transparent);
  color: var(--main-color, var(--color-brand));
  font-weight: var(--weight-semibold);
}
.chips-invalid .gender-chip { border-color: var(--color-error); }

/* v4.77.20 — ícone do chip (FontAwesome) proporcional ao texto.
   Antes: sem declaração, herdava 1em sem ajuste visual → ícone parecia pequeno.
   Agora: 18px alinhado ao baseline do texto + gap consistente. */
.gender-chip i,
.gender-chips--nowrap .gender-chip i {
  font-size: 18px;
  line-height: 1;
  margin-right: var(--space-2);
  vertical-align: middle;
  flex-shrink: 0;
}

/* ─────────────────────────────────────────────────────────────
   10. CEP MÁGICO
───────────────────────────────────────────────────────────────*/
.cep-field-wrap { position: relative; }

/* v4.77.2 — right + font-size tokenizados */
.cep-status {
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--font-md);
  pointer-events: none;
}
.cep-status.success { color: var(--color-success); }
.cep-status.error   { color: var(--color-error); }

.cep-loading { display: flex; gap: 3px; align-items: center; }
.cep-loading span {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--main-color, var(--color-brand));
  animation: cepDot 1s ease-in-out infinite;
}
.cep-loading span:nth-child(2) { animation-delay: 0.16s; }
.cep-loading span:nth-child(3) { animation-delay: 0.32s; }
@keyframes cepDot {
  0%,80%,100% { transform: scale(0.6); opacity: 0.4; }
  40%         { transform: scale(1);   opacity: 1; }
}

.address-field-animated {
  transition: opacity 0.3s ease, transform 0.3s var(--ease-spring);
}

/* ─────────────────────────────────────────────────────────────
   11. PASSWORD STRENGTH
───────────────────────────────────────────────────────────────*/
.password-strength-bar {
  margin-top: var(--space-2);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.password-strength-fill {
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--gray-200);
  width: 0%;
  transition: width 0.4s var(--ease-spring), background 0.3s ease;
  flex: 1;
}
.password-strength-label {
  font-size: var(--font-xs);
  color: var(--text-muted);
  min-width: 56px;
  text-align: right;
}

/* ─────────────────────────────────────────────────────────────
   12. LGPD + FORM-CHECK CANÔNICO (v4.77.20)
   Regras prefixadas com .register-wizard-step / .step-6 / .auth-gate
   pra vencer Bootstrap (.form-check padrão) sem !important.
   Cobre o bloco "aceito os termos" (classe .lgpd) e qualquer .form-check
   dentro dos steps de cadastro. Corrige: checkbox fora do padrão,
   texto longo saindo da tela, desalinhamento vertical, gap estranho.
───────────────────────────────────────────────────────────────*/
.col-12.mb-3:has(.form-check.lgpd) {
  padding-left: 0;
  padding-right: 0;
}

/* Container .form-check — alinhado no topo, gap adequado, sem overflow lateral */
.register-wizard-step .form-check,
.step-6 .form-check,
.auth-gate .form-check,
.form-check.lgpd {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: 0;
  margin: var(--space-3) 0;
  max-width: 100%;
  min-height: unset;
}

/* Checkbox customizado — square 22x22, sem appearance nativo.
   v4.77.70: refinado pra cara de iOS/app — cantos mais arredondados (6px
   em vez de --radius-xs 2-4px), borda 1.5px (antes 2px parecia chunky),
   sombra interna sutil no unchecked pra dar profundidade, animação de
   scale no check pra sensação de toque responsivo. */
.register-wizard-step .form-check .form-check-input,
.step-6 .form-check .form-check-input,
.auth-gate .form-check .form-check-input,
.form-check.lgpd .form-check-input,
.register-wizard-step .form-check .form-check-input[type="checkbox"],
.step-6 .form-check .form-check-input[type="checkbox"],
.auth-gate .form-check .form-check-input[type="checkbox"],
.form-check.lgpd .form-check-input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 22px !important;
  height: 22px !important;
  /* v4.77.80 — !important necessário porque há regras legadas com !important
     em `input[type="checkbox"] { height: 20px }` e `.form-check input[type="checkbox"] { height: 18px }`
     que senão venceriam. min-height:0 vence o `min-height: var(--touch-target)`
     global (44px) que estava esticando o checkbox. */
  min-width: 22px !important;
  min-height: 0 !important;
  max-height: 22px !important;
  margin: 0;
  margin-top: 1px;
  flex-shrink: 0;
  border: 1.5px solid var(--gray-300, #d4d4d8);
  border-radius: 6px;
  background: var(--bg-primary);
  cursor: pointer;
  position: relative;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.04);
  transition:
    background 0.18s cubic-bezier(0.16, 1, 0.3, 1),
    border-color 0.18s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.12s ease-out,
    box-shadow 0.18s ease-out;
}

/* Hover desktop: dica visual sutil de que é clicável */
.register-wizard-step .form-check .form-check-input:hover,
.step-6 .form-check .form-check-input:hover,
.auth-gate .form-check .form-check-input:hover,
.form-check.lgpd .form-check-input:hover {
  border-color: var(--main-color, var(--color-brand));
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.04),
              0 0 0 3px color-mix(in srgb, var(--main-color, var(--color-brand)) 8%, transparent);
}

.register-wizard-step .form-check .form-check-input:active,
.step-6 .form-check .form-check-input:active,
.auth-gate .form-check .form-check-input:active,
.form-check.lgpd .form-check-input:active {
  transform: scale(0.92);
}

.register-wizard-step .form-check .form-check-input:checked,
.step-6 .form-check .form-check-input:checked,
.auth-gate .form-check .form-check-input:checked,
.form-check.lgpd .form-check-input:checked,
.register-wizard-step .form-check .form-check-input[type="checkbox"]:checked,
.step-6 .form-check .form-check-input[type="checkbox"]:checked,
.auth-gate .form-check .form-check-input[type="checkbox"]:checked,
.form-check.lgpd .form-check-input[type="checkbox"]:checked {
  background: var(--main-color, var(--color-brand));
  border-color: var(--main-color, var(--color-brand));
}

.register-wizard-step .form-check .form-check-input:checked::after,
.step-6 .form-check .form-check-input:checked::after,
.auth-gate .form-check .form-check-input:checked::after,
.form-check.lgpd .form-check-input:checked::after,
.register-wizard-step .form-check .form-check-input[type="checkbox"]:checked::after,
.step-6 .form-check .form-check-input[type="checkbox"]:checked::after,
.auth-gate .form-check .form-check-input[type="checkbox"]:checked::after,
.form-check.lgpd .form-check-input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 2px;
  width: 6px;
  height: 11px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  animation: checkPop 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes checkPop {
  0%   { transform: rotate(45deg) scale(0.4); opacity: 0; }
  60%  { transform: rotate(45deg) scale(1.1); opacity: 1; }
  100% { transform: rotate(45deg) scale(1); opacity: 1; }
}

.register-wizard-step .form-check .form-check-input:focus-visible,
.step-6 .form-check .form-check-input:focus-visible,
.auth-gate .form-check .form-check-input:focus-visible,
.form-check.lgpd .form-check-input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--main-color, var(--color-brand)) 25%, transparent);
}

/* Label — flex:1 pra ocupar espaço restante, word-break pra texto longo
   (ex: termos LGPD) não sair da tela. */
.register-wizard-step .form-check .form-check-label,
.step-6 .form-check .form-check-label,
.auth-gate .form-check .form-check-label,
.form-check.lgpd .form-check-label {
  flex: 1;
  min-width: 0;
  font-size: var(--font-sm);
  line-height: var(--leading-normal);
  color: var(--text-secondary, var(--text-muted));
  cursor: pointer;
  word-break: break-word;
  overflow-wrap: anywhere;
  margin: 0;
  padding: 0;
}

/* ─────────────────────────────────────────────────────────────
   13. STEP 6 PÓS-OAUTH
───────────────────────────────────────────────────────────────*/
.step6-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
}
/* v4.77.2 — font-size tokenizado (antes 28px => --font-2xl 24px mais próximo) */
.step6-icon {
  width: 64px; height: 64px;
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 10%, transparent);
  border-radius: var(--radius-full);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--font-2xl);
  color: var(--main-color, var(--color-brand));
  animation: logoSpring 0.5s var(--ease-spring) both;
}
.step6-intro p { font-size: var(--font-md); color: var(--text-secondary); margin: 0; }

/* ─────────────────────────────────────────────────────────────
   14. VALIDAÇÃO DE CAMPOS
───────────────────────────────────────────────────────────────*/
/* v4.77.2 — box-shadow com color-mix (antes rgba(239,68,68,...) hardcoded) + font-size tokenizado */
.field-invalid {
  border-color: var(--color-error) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 12%, transparent) !important;
}

/* Task #307 item 2 — margin-top -10px fazia a mensagem colar na borda vermelha
   do input (confirmado pelo usuário no print image (32).png). Trocado por
   espaçamento positivo mínimo (var(--space-1) ≈ 4px) — respiro visual que
   separa claramente a borda do erro do texto. Override pra gender-chips
   permanece abaixo pra manter a distância maior onde já era correta. */
.field-error {
  display: block;
  margin-top: var(--space-1);
  margin-bottom: var(--space-1);
  font-size: var(--font-xs);
  color: var(--color-error);
  padding-left: 2px;
}
/* v4.77.40: quando o field-error vem logo depois dos gender-chips,
   anula o margin-top negativo — os chips já têm altura própria e o -10px
   faz o erro colar na borda inferior dos chips. Também dá um respiro
   mínimo (var(--space-2)) pra leitura. */
.gender-chips + .field-error,
.chips-invalid + .field-error {
  margin-top: var(--space-2);
}
/* Quando visível, o col-12 mb-3 não precisa de tanto espaço embaixo */
.register-wizard-step .col-12.mb-3:has(.field-error:not([style*="display: none"])) {
  margin-bottom: var(--space-1) !important;
}

/* ─────────────────────────────────────────────────────────────
   14b. WIZARD — LINHA DE BOTÕES NAVEGAÇÃO (Voltar + Próximo)
   Substitui `d-flex gap-2` + `style="flex:X"` hardcoded nos steps
   Classes aplicadas em: step-register.php, step-register-complete.php
───────────────────────────────────────────────────────────────*/
/* v4.77.19: height fixo 48px em ambos os botões + alinhamento vertical
   garantido via align-items:stretch no container + display:inline-flex
   center no btn. Remove bugs de altura divergente entre Voltar e Próximo
   quando texto quebra linha ou padding herda do .btn global.
   v4.77.70: force mesma baseline visual — padding vertical zero,
   align-items:center (não baseline), font-size canônico pra Voltar
   e Próximo, !important no height pra vencer Bootstrap .btn global. */
.wizard-btn-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.wizard-btn-row .btn {
  height: 48px !important;
  min-height: 48px !important;
  max-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  line-height: 1;
  font-size: var(--font-md, 15px);
  font-weight: var(--weight-semibold, 600);
  white-space: nowrap;
  margin: 0;
  vertical-align: middle;
  box-sizing: border-box;
}

/* Icon dentro dos botões do wizard: tamanho e gap fixos pra não empurrar
   a baseline do texto e desalinhar com o outro botão. */
.wizard-btn-row .btn > i,
.wizard-btn-row .btn > svg {
  font-size: 14px;
  line-height: 1;
  margin-right: var(--space-1, 4px);
}
.wizard-btn-row .wizard-btn-back--icon > i {
  margin-right: 0;
  font-size: 16px;
}

/* Secundário (Voltar) — proporção 1 */
.wizard-btn-back {
  flex: 1;
}
/* Voltar só-ícone (step-register-complete step 2) — quadrado 48x48 */
.wizard-btn-back--icon {
  flex: 0 0 48px;
  width: 48px;
  padding-left: 0;
  padding-right: 0;
}
/* Primário (Próximo/Criar) — proporção 2 */
.wizard-btn-next {
  flex: 2;
}
/* Variante mais larga (step 6 Finalizar) */
.wizard-btn-next--wide {
  flex: 3;
}

/* Footer minimalista */
footer {
  padding: 0;
}
/* v4.77.2 — gap/padding/font tokenizados */
.footer-minimal {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-5);
  border-top: 1px solid var(--gray-100);
  line-height: 1;
}
.footer-minimal__link,
.footer-minimal__sep,
.footer-minimal__brand {
  font-size: var(--font-xs);
  line-height: 1;
  vertical-align: middle;
}
.footer-minimal__link {
  color: var(--text-muted, #9ca3af) !important;
  text-decoration: none !important;
  min-height: unset !important;
  display: inline !important;
  line-height: 1 !important;
}
.footer-minimal__link:hover {
  color: var(--text-secondary, #6b7280) !important;
}
.footer-minimal__sep {
  color: var(--gray-300, #d1d5db);
}
.footer-minimal__brand {
  color: var(--text-muted, #9ca3af);
}

/* LGPD links (termos + privacidade) */
.form-check.lgpd .form-check-label a,
.form-check.lgpd .form-check-label a:visited,
.form-check.lgpd .form-check-label a:hover {
  color: var(--main-color, var(--color-brand)) !important;
  text-decoration: underline !important;
}

/* ─────────────────────────────────────────────────────────────
   15. SLIDE 0 — PONTOS: órbita de moedas + interatividade
───────────────────────────────────────────────────────────────*/

/* Anel da órbita rotacionando lentamente — viewBox 220x220 → centro 110,110 */
.ob-orbit-ring {
  animation: orbitRingRotate 20s linear infinite;
  transform-origin: 110px 110px;
}
@keyframes orbitRingRotate {
  to { transform: rotate(360deg); }
}

/* Troféu central: pulso de escala suave */
.ob-trophy {
  animation: starPulse 2.8s ease-in-out infinite;
  transform-origin: 110px 110px;
}
@keyframes starPulse {
  0%, 100% { transform: scale(1); }
  50%       { transform: scale(1.06); }
}

/* Moedas orbitando em torno do centro 110,110 */
.ob-coin--1 {
  animation: coinOrbit1 5s linear infinite;
  transform-origin: 110px 110px;
}
.ob-coin--2 {
  animation: coinOrbit2 5s linear infinite;
  transform-origin: 110px 110px;
}
.ob-coin--3 {
  animation: coinOrbit3 5s linear infinite;
  transform-origin: 110px 110px;
}

@keyframes coinOrbit1 {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes coinOrbit2 {
  from { transform: rotate(-130deg); }
  to   { transform: rotate(230deg); }
}
@keyframes coinOrbit3 {
  from { transform: rotate(-240deg); }
  to   { transform: rotate(120deg); }
}

/* Bounce ao tocar/clicar nas moedas */
.ob-coin.ob-coin--bounce {
  animation: coinBounce 0.45s var(--ease-spring) both !important;
}
@keyframes coinBounce {
  0%   { transform: rotate(0deg) scale(1); }
  35%  { transform: rotate(0deg) scale(1.5); }
  65%  { transform: rotate(0deg) scale(0.88); }
  100% { transform: rotate(0deg) scale(1); }
}

/* Partículas piscando */
.ob-spark--1 { animation: sparkBlink 2.1s ease-in-out infinite; }
.ob-spark--2 { animation: sparkBlink 3.0s ease-in-out 0.6s infinite; }
.ob-spark--3 { animation: sparkBlink 2.5s ease-in-out 1.2s infinite; }
.ob-spark--4 { animation: sparkBlink 1.9s ease-in-out 0.3s infinite; }
.ob-spark--5 { animation: sparkBlink 2.7s ease-in-out 0.9s infinite; }
@keyframes sparkBlink {
  0%, 100% { opacity: 0.3; r: 0; transform: scale(0.7); }
  50%       { opacity: 1;   transform: scale(1.3); }
}

/* Parallax: inclinação leve ao arrastar/tiltar */
.ob-illus--0[data-parallax] {
  transition: transform 0.12s linear;
}

/* SVG pontos: tamanho responsivo */
.ob-illus__svg--points {
  width: 100%;
  height: 100%;
}

/* ─────────────────────────────────────────────────────────────
   15b. SLIDE 1 — OFERTAS: tags flutuando
───────────────────────────────────────────────────────────────*/

/* Tag 1: flutua para cima e para baixo levemente */
.ob-tag--1 {
  animation: tagFloat1 3.2s ease-in-out infinite;
}
@keyframes tagFloat1 {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%       { transform: translateY(-8px) rotate(1deg); }
}

/* Tag 2: flutua na direção oposta */
.ob-tag--2 {
  animation: tagFloat2 3.8s ease-in-out 0.5s infinite;
}
@keyframes tagFloat2 {
  0%, 100% { transform: translateY(0) rotate(2deg); }
  50%       { transform: translateY(-6px) rotate(-1deg); }
}

/* Tag 3 (relâmpago): pulsa e gira levemente */
.ob-tag--3 {
  animation: tagPulse3 2.4s ease-in-out 0.8s infinite;
  transform-origin: 155px 145px;
}
@keyframes tagPulse3 {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50%       { transform: scale(1.12) rotate(-5deg); }
}

/* Clique no smartphone — shake */
#illusOffers.ob-shake {
  animation: smartphoneShake 0.4s var(--ease-spring) both !important;
}
@keyframes smartphoneShake {
  0%   { transform: rotate(0deg); }
  20%  { transform: rotate(-6deg) scale(1.05); }
  40%  { transform: rotate(5deg)  scale(1.08); }
  60%  { transform: rotate(-3deg) scale(1.04); }
  80%  { transform: rotate(2deg)  scale(1.02); }
  100% { transform: rotate(0deg)  scale(1); }
}

/* ─────────────────────────────────────────────────────────────
   15c. SLIDE 2 — CASHBACK: moedas caindo na carteira
───────────────────────────────────────────────────────────────*/

/* Arco de retorno: dash-offset animado (linha se desenha) */
.ob-illus--2.active .ob-return-arc path {
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
  animation: arcDraw 1.2s var(--ease-spring) 0.2s both;
}
.ob-illus--2.active .ob-return-arc polyline {
  stroke-dasharray: 50;
  stroke-dashoffset: 50;
  animation: arcDraw 0.4s ease-out 1.1s both;
}
@keyframes arcDraw {
  to { stroke-dashoffset: 0; }
}

/* Moedas caindo: animação em loop de queda e desaparecimento */
.ob-cashcoin--1 {
  animation: coinFall 2.4s ease-in-out 0.4s infinite;
}
.ob-cashcoin--2 {
  animation: coinFall 2.4s ease-in-out 1.0s infinite;
}
.ob-cashcoin--3 {
  animation: coinFall 2.4s ease-in-out 1.6s infinite;
}
@keyframes coinFall {
  0%   { transform: translateY(0); opacity: 1; }
  60%  { transform: translateY(28px); opacity: 0.9; }
  80%  { transform: translateY(38px); opacity: 0; }
  100% { transform: translateY(0); opacity: 0; }
}

/* Clique na carteira — bounce */
#illusCashback.ob-wallet-bounce {
  animation: walletBounce 0.45s var(--ease-spring) both !important;
  transform-origin: 110px 145px;
}
@keyframes walletBounce {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.1) translateY(-6px); }
  65%  { transform: scale(0.96) translateY(2px); }
  100% { transform: scale(1) translateY(0); }
}

/* Flash sutil no card ao avançar slide */
.ob-card-progress {
  animation: cardProgressFlash 0.45s var(--ease-spring) both;
}
@keyframes cardProgressFlash {
  0%   { box-shadow: 0 -4px 24px rgba(0,0,0,0.08); }
  40%  { box-shadow: 0 -4px 32px color-mix(in srgb, var(--main-color, var(--color-brand)) 30%, transparent); }
  100% { box-shadow: 0 -4px 24px rgba(0,0,0,0.08); }
}

/* Tag clicada: escala */
.ob-tag--clicked {
  animation: tagClick 0.4s var(--ease-spring) both;
  transform-origin: center;
}
@keyframes tagClick {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.2) rotate(-3deg); }
  100% { transform: scale(1) rotate(0deg); }
}

/* ─────────────────────────────────────────────────────────────
   16. TRANSIÇÃO ONBOARDING → AUTH (cross-fade sem reflow)
   v4.77.77 — estratégia refinada: o GATE permanece SEMPRE no fluxo
   normal (flex:1, min-height:100dvh). Apenas o SWIPER sobe em
   position:absolute sobre ele durante a transição. Assim:
   (1) o gate nunca muda de modo de layout → sem "salto/tremida"
   (2) o swiper flutua por cima e dissolve → sem gap branco
   v4.77.76 tinha o bug de colocar AMBOS em absolute durante a
   transição e depois tirar → causava reflow visível no gate.
───────────────────────────────────────────────────────────────*/

/* Pai vira palco com position:relative pra ancorar o swiper absoluto. */
.auth-gate.is-crossfading {
  position: relative;
  overflow: hidden;
}

/* Durante o crossfade, o swiper flutua sobre o gate (que permanece
   no fluxo normal ocupando tudo). */
.auth-gate.is-crossfading > .onboarding-swiper {
  position: absolute;
  inset: 0;
  z-index: 2;
  min-height: 100dvh;
}

/* Estado de saída do swiper — v4.77.76: fade puro (sem scale/translateY
   que causavam sensação de "salto"). A camada gate já está pronta por
   baixo, então basta o swiper dissolver em opacidade. */
.onboarding-swiper.onboarding-exiting {
  animation: swiperFadeOut 0.45s var(--ease-out) both;
  pointer-events: none;
  will-change: opacity;
}
@keyframes swiperFadeOut {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

/* Auth gate: fade-in suave (só opacity, sem movimento — o hero já está
   no lugar por trás do swiper saindo). */
.auth-gate__form.gate-fade-in {
  animation: gateFadeIn 0.45s ease-out both;
  will-change: opacity;
}
@keyframes gateFadeIn {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

/* Garante que o form não pisca antes de entrar */
.auth-gate__form[data-hidden] {
  visibility: hidden;
  opacity: 0;
}

/* ─────────────────────────────────────────────────────────────
   16b. INPUTS DOS STEPS — alinhamento ao canônico pharus-field
   (v4.77.5) aplica o visual canônico aos .form-control /
   .auth-gate__input dentro das seções .step-1 .. .step-7 e
   dos wizards .register-wizard-step, sem renomear classes.
───────────────────────────────────────────────────────────────*/

/* Labels dos steps — tipografia consistente */
.step-1 label,
.step-2 label,
.step-3 label,
.step-6 label,
.step-7 label,
.register-wizard-step label {
  display: block;
  font-size: var(--font-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  margin-bottom: var(--space-2);
  letter-spacing: var(--tracking-wide, 0.01em);
}

/* Inputs base — altura, radius, cores, foco */
.auth-gate .form-control,
.step-1 .form-control,
.step-2 .form-control,
.step-3 .form-control,
.step-6 .form-control,
.step-7 .form-control,
.register-wizard-step .form-control,
.auth-gate__input {
  height: 48px;
  min-height: var(--touch-target);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default, var(--gray-200));
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-primary);
  /* 16px evita zoom iOS no foco — manter literal */
  font-size: 16px;
  font-family: var(--font-family);
  line-height: 1.2;
  width: 100%;
  box-shadow: none;
  transition: border-color var(--transition-normal), box-shadow var(--transition-normal);
  -webkit-appearance: none;
  appearance: none;
}

.auth-gate .form-control::placeholder,
.step-1 .form-control::placeholder,
.step-2 .form-control::placeholder,
.step-3 .form-control::placeholder,
.step-6 .form-control::placeholder,
.step-7 .form-control::placeholder,
.register-wizard-step .form-control::placeholder,
.auth-gate__input::placeholder {
  color: var(--text-muted);
  opacity: 1;
}

.auth-gate .form-control:focus,
.step-1 .form-control:focus,
.step-2 .form-control:focus,
.step-3 .form-control:focus,
.step-6 .form-control:focus,
.step-7 .form-control:focus,
.register-wizard-step .form-control:focus,
.auth-gate__input:focus {
  border-color: var(--main-color, var(--color-brand)) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--main-color, var(--color-brand)) 20%, transparent) !important;
  outline: none !important;
  background: var(--bg-primary);
}

/* Estado de erro canônico */
.auth-gate .form-control.is-invalid,
.step-1 .form-control.is-invalid,
.step-2 .form-control.is-invalid,
.step-3 .form-control.is-invalid,
.step-6 .form-control.is-invalid,
.step-7 .form-control.is-invalid,
.register-wizard-step .form-control.is-invalid {
  border-color: var(--color-error) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 15%, transparent) !important;
}

/* Selects nativos — seta customizada (evita estilo default do browser).
   v4.77.70: alinhamento completo com .form-control — mesmo bg, mesma
   altura, mesmo padding vertical, line-height coerente. Antes o select
   ficava ligeiramente diferente dos inputs (padding/line-height nativo
   do <select> vazia). */
.step-2 select.form-control,
.step-6 select.form-control,
.register-wizard-step select.form-control {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2371717a' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3, 12px) center;
  background-color: var(--bg-primary);
  padding-right: calc(var(--space-3, 12px) + 20px);
  padding-left: var(--space-4);
  /* line-height alinhado com inputs (select nativo tem lh intrínseco diferente) */
  line-height: 1.2;
  /* garante mesma altura em iOS Safari (ignora padding vertical em select) */
  height: 48px !important;
  min-height: 48px !important;
  appearance: none;
  -webkit-appearance: none;
  text-overflow: ellipsis;
}

/* UF (2 chars, col-2): encolhe padding lateral pra caber a seta sem cortar texto */
.register-wizard-step #uf,
.register-wizard-step select#uf.form-control {
  padding-left: var(--space-3, 12px);
  padding-right: 28px;
  text-align-last: left;
}

/* v4.77.79 — Select2 override: UF/Cidade no step de cadastro são
   transformados em widget Select2 pelo plugin (main.js: initCidadesSelect).
   Por default Select2 renderiza 38px altura, border #aaa, radius 8px —
   NÃO bate com o .form-control canônico (48px, border --gray-200, radius 12px).
   Aqui forçamos o wrapper e seus filhos pra ficarem visualmente IDÊNTICOS
   aos inputs/selects nativos irmãos. Escopo limitado ao .register-wizard-step
   pra não vazar pro web-panel que também usa Select2. */
.register-wizard-step .select2-container--default .select2-selection--single {
  height: 48px !important;
  min-height: 48px;
  border: 1px solid var(--border-default, var(--gray-200)) !important;
  border-radius: var(--radius-md, 12px) !important;
  background: var(--bg-primary);
  /* !important necessário pra vencer main.css:322 que zera padding horizontal
     com `padding: 5px 0 3px 0 !important` aplicado ao Select2 global do mobile. */
  padding: 0 var(--space-4) !important;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  transition: border-color var(--transition-normal), box-shadow var(--transition-normal);
}

.register-wizard-step .select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: 1.2;
  padding: 0;
  color: var(--text-primary);
  font-size: 16px;
  font-family: var(--font-family);
}

.register-wizard-step .select2-container--default .select2-selection--single .select2-selection__placeholder {
  color: var(--text-muted);
}

/* Seta: alinha com a estética da seta nativa usada nos selects non-Select2 */
.register-wizard-step .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 46px;
  top: 1px;
  right: var(--space-3, 12px);
}
.register-wizard-step .select2-container--default .select2-selection--single .select2-selection__arrow b {
  border-color: #71717a transparent transparent transparent;
}

/* Estado de foco — borda na cor da marca, igual inputs irmãos */
.register-wizard-step .select2-container--default.select2-container--focus .select2-selection--single,
.register-wizard-step .select2-container--default.select2-container--open .select2-selection--single {
  border-color: var(--main-color, var(--color-brand)) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--main-color, var(--color-brand)) 20%, transparent) !important;
  outline: none;
}

/* Estado de erro (quando o <select> original tem .is-invalid, Select2 não
   reflete automaticamente — o validate adiciona a classe no wrapper via JS).
   Como fallback, permite via parent-has: */
.register-wizard-step .form-control.is-invalid + .select2-container .select2-selection--single {
  border-color: var(--color-error) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 15%, transparent) !important;
}

/* Dropdown (menu aberto): radius e cor coerentes com o restante */
.select2-container--default.select2-container--open .select2-dropdown {
  border: 1px solid var(--border-default, var(--gray-200));
  border-radius: var(--radius-md, 12px);
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  overflow: hidden;
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
  background: var(--main-color, var(--color-brand));
  color: #fff;
}

/* Input group (senha + olho) — v4.77.8 borda UNIFICADA no container,
   input e botão sem bordas próprias. v4.77.19: altura canônica 48px
   fixa no container (antes herdava do child 46px + borda 2px = 48px
   fragil). Input e botão internos stretchem em 100% height. */
.step-1 .input-group,
.step-3 .input-group,
.register-wizard-step .input-group {
  display: flex;
  align-items: stretch;
  width: 100%;
  height: 48px;
  min-height: var(--touch-target);
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-default, var(--gray-200));
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  overflow: hidden;
  transition: border-color var(--transition-normal), box-shadow var(--transition-normal);
}

/* Estado de foco e erro vão no container, não no input/botão */
.step-1 .input-group:focus-within,
.step-3 .input-group:focus-within,
.register-wizard-step .input-group:focus-within {
  border-color: var(--main-color, var(--color-brand));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--main-color, var(--color-brand)) 20%, transparent);
}

.step-1 .input-group.is-invalid,
.step-3 .input-group.is-invalid,
.register-wizard-step .input-group.is-invalid,
.step-1 .input-group:has(.form-control.is-invalid),
.step-3 .input-group:has(.form-control.is-invalid),
.register-wizard-step .input-group:has(.form-control.is-invalid) {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 15%, transparent);
}

/* Input interno: sem borda, sem bg (herda do container).
   v4.77.19 height 100% pra stretch ao container de 48px. */
.step-1 .input-group .form-control,
.step-3 .input-group .form-control,
.register-wizard-step .input-group .form-control {
  border: 0 !important;
  background: transparent !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  height: 100% !important;
  min-height: 0 !important;
  margin: 0;
  padding: 0 var(--space-4);
  font-size: 16px;
  line-height: 1.2;
  color: var(--text-primary);
  flex: 1;
  min-width: 0;
  outline: none;
}
.step-1 .input-group .form-control:focus,
.step-3 .input-group .form-control:focus,
.register-wizard-step .input-group .form-control:focus {
  border: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
}

.step-1 .input-group-append,
.step-3 .input-group-append,
.register-wizard-step .input-group-append {
  display: flex;
  align-items: stretch;
  height: 100%;
  margin: 0;
  padding: 0;
}

/* Olho: 48x48 quadrado, sem bordas, centralizado.
   v4.77.19 height 100% pra stretch ao container de 48px; width fixo. */
.step-1 .input-group-text.eye,
.step-3 .input-group-text.eye,
.register-wizard-step .input-group-text.eye,
.step-1 .input-group .btn,
.step-3 .input-group .btn,
.register-wizard-step .input-group .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  min-width: 48px;
  flex: 0 0 48px;
  height: 100%;
  min-height: 0;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  margin: 0;
  transition: color var(--transition-normal);
}
.step-1 .input-group-text.eye i,
.step-3 .input-group-text.eye i,
.register-wizard-step .input-group-text.eye i {
  font-size: var(--font-md);
  line-height: 1;
}
.step-1 .input-group-text.eye:hover,
.step-3 .input-group-text.eye:hover,
.register-wizard-step .input-group-text.eye:hover,
.step-1 .input-group-text.eye:focus,
.step-3 .input-group-text.eye:focus,
.register-wizard-step .input-group-text.eye:focus {
  color: var(--main-color, var(--color-brand));
}

/* ─────────────────────────────────────────────────────────────
   16c. TOGGLE SWITCH — reset + canônico (v4.77.8 — compacto 36x20)
   Usado em step-login "Lembrar acesso" e no extended-profile.
   Container é <label>; texto alinha com centro da track.
───────────────────────────────────────────────────────────────*/
.toggle-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-sm);
  color: var(--text-secondary);
  font-weight: var(--weight-medium);
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  line-height: 1;
  margin-bottom: 0;
}

/* Esconde o checkbox nativo mas mantém acessível */
.toggle-switch input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

/* Track (fundo da pílula) — v4.77.8 compacto 36x20 */
.toggle-switch .toggle-track {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
  background: var(--gray-200);
  border-radius: 9999px;
  flex-shrink: 0;
  vertical-align: middle;
  transition: background 0.2s var(--ease-out);
}

/* Thumb (círculo que desliza) — 16px com 2px de respiro dos dois lados */
.toggle-switch .toggle-track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: #fff;
  border-radius: 9999px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  transition: transform 0.2s var(--ease-out);
}

/* Estado ativo — thumb translada 16px (36 - 16 - 2 - 2) */
.toggle-switch input[type="checkbox"]:checked + .toggle-track {
  background: var(--main-color, var(--color-brand));
}
.toggle-switch input[type="checkbox"]:checked + .toggle-track::after {
  transform: translateX(16px);
}

/* Focus visível acessível */
.toggle-switch input[type="checkbox"]:focus-visible + .toggle-track {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--main-color, var(--color-brand)) 25%, transparent);
}

/* ─────────────────────────────────────────────────────────────
   16d. WIZARD STEP VISIBILITY (v4.77.5)
   Garante que só o step .active é exibido no wizard de cadastro.
───────────────────────────────────────────────────────────────*/
.register-wizard-step {
  display: none;
  animation: wizardStepIn 0.32s var(--ease-spring) both;
}
.register-wizard-step.active {
  display: block;
}
@keyframes wizardStepIn {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* v4.77.19: espaçamento uniforme entre grupos de campo do wizard.
   Bootstrap .mb-3 (16px) em cada col + gap implícito entre rows
   produzia blocos visualmente afastados no step de endereço
   (CEP/Nº → Rua → Cidade/Bairro/UF). Reduz espaçamento vertical
   dos rows internos do wizard e iguala padding/altura em TODOS os
   form-control dentro de qualquer [class^="col-"] para paridade
   Cidade / UF / Bairro / Nº / CEP. */
.register-wizard-step .row {
  margin-left: 0;
  margin-right: 0;
  row-gap: 0;
}
.register-wizard-step .row > [class^="col-"],
.register-wizard-step .row > [class*=" col-"] {
  padding-left: 0;
  padding-right: 0;
}
.register-wizard-step .row > [class^="col-"] + [class^="col-"],
.register-wizard-step .row > [class*=" col-"] + [class^="col-"] {
  padding-left: var(--space-2);
}
/* Uniformiza altura dos inputs/selects em qualquer coluna do wizard */
.register-wizard-step [class^="col-"] .form-control,
.register-wizard-step [class*=" col-"] .form-control {
  height: 48px;
  min-height: var(--touch-target);
  width: 100%;
  box-sizing: border-box;
}
/* Tighten vertical spacing: mb-3 dentro do wizard vira 12px (antes 16px)
   pra reduzir distância entre blocos de campo. */
.register-wizard-step .col-12.mb-3,
.register-wizard-step [class^="col-"].mb-3,
.register-wizard-step [class*=" col-"].mb-3 {
  margin-bottom: var(--space-3) !important;
}

/* Wizard step title + desc (headers visuais do wizard) */
.wizard-step-title {
  font-size: var(--font-lg, 17px);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-1);
  text-align: center;
}
.wizard-step-desc {
  font-size: var(--font-sm);
  color: var(--text-secondary);
  margin: 0 0 var(--space-4);
  text-align: center;
}

/* Checkbox LGPD — regras consolidadas na seção 12 (v4.77.20).
   Bloco antigo removido pra evitar cascade duplicada com seletor menos
   específico sobrescrevendo partes do canônico (width do ::after, border). */

/* ─────────────────────────────────────────────────────────────
   16e. GROUP-RADIO — cards selecionáveis (v4.77.8)
   Originalmente usado em step-forgot-password.php (.step-3) p/ escolher
   canal de recuperação. Em v4.90.x (task #307 item 4) o seletor foi
   removido do forgot-password (único canal = e-mail). Mantemos a regra
   apenas para .register-wizard-step, que ainda usa o padrão.
   .group-radio > .tab > input[type=radio] + label
───────────────────────────────────────────────────────────────*/
.register-wizard-step .group-radio {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-2);
  width: 100%;
  margin: 0 0 var(--space-3);
  align-items: stretch;
  justify-content: flex-start;
}

/* Cada .tab vira um card selecionável */
.register-wizard-step .group-radio .tab {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default, var(--gray-200));
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-primary);
  cursor: pointer;
  min-height: var(--touch-target);
  margin: 0;
  transition: border-color 0.2s var(--ease-out), background 0.2s var(--ease-out), color 0.2s var(--ease-out);
}

.register-wizard-step .group-radio .tab:hover {
  border-color: var(--main-color, var(--color-brand));
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 5%, var(--bg-primary));
}

/* Radio input dentro do card */
.register-wizard-step .group-radio .tab input[type="radio"] {
  width: 18px !important;
  height: 18px !important;
  margin: 0 !important;
  flex-shrink: 0;
  accent-color: var(--main-color, var(--color-brand));
  cursor: pointer;
}

/* Label interna do card */
.register-wizard-step .group-radio .tab label {
  width: auto !important;
  margin: 0 !important;
  font-size: var(--font-sm);
  font-weight: var(--weight-medium);
  color: inherit;
  cursor: pointer;
  line-height: 1;
  flex: 1;
}

/* Estado ativo — .tab.active (aplicada via JS) ou :has(input:checked) */
.register-wizard-step .group-radio .tab.active,
.register-wizard-step .group-radio .tab:has(input[type="radio"]:checked) {
  border-color: var(--main-color, var(--color-brand));
  background: color-mix(in srgb, var(--main-color, var(--color-brand)) 10%, var(--bg-primary));
  color: var(--main-color, var(--color-brand));
}
.register-wizard-step .group-radio .tab.active label,
.register-wizard-step .group-radio .tab:has(input[type="radio"]:checked) label {
  font-weight: var(--weight-semibold);
  color: var(--main-color, var(--color-brand));
}

/* ─────────────────────────────────────────────────────────────
   16f. ONBOARDING → AUTH: sem flash branco (v4.77.8)
   Garante que os dois containers ficam sobre o mesmo background
   da app (ou do gradient escuro do splash se estiver ativo),
   evitando o "clarão" durante o cross-fade.
───────────────────────────────────────────────────────────────*/
.body__app--auth-gate,
.body__app--auth-gate > .container-fluid {
  background: var(--bg-primary);
}

/* Cross-fade: swiper sai em 0.45s e form entra em paralelo (v4.77.45 —
   tempos aproximados pra sumir "gap branco" e glitch de re-entrada). */
.onboarding-swiper.onboarding-exiting {
  animation: swiperFadeOut 0.45s var(--ease-out) both;
}

/* ─────────────────────────────────────────────────────────────
   17. REDUCED MOTION
───────────────────────────────────────────────────────────────*/
@media (prefers-reduced-motion: reduce) {
  .onboarding-slide, .onboarding-icon, .auth-gate__logo-img,
  .wizard-step-icon, .gender-chip,
  .auth-gate__hero::before, .auth-gate__hero::after,
  .auth-gate__ring,
  .auth-gate__btn-continue::after,
  .auth-gate__input-wrap::after,
  #authGateCanvas,
  .ob-coin--1, .ob-coin--2, .ob-coin--3,
  .ob-star-center, .ob-orbit-ring,
  .ob-spark--1, .ob-spark--2, .ob-spark--3, .ob-spark--4, .ob-spark--5,
  .onboarding-swiper.onboarding-exiting,
  .auth-gate__form.gate-fade-in,
  .register-wizard-step,
  .toggle-switch .toggle-track,
  .toggle-switch .toggle-track::after,
  .pharus-celebration-overlay,
  .pharus-celebration-overlay__icon,
  .pharus-celebration-overlay__title,
  .pharus-celebration-overlay__subtitle { animation: none !important; transition: none !important; }
}

/* ═══════════════════════════════════════════════════
   CELEBRATION — tela de sucesso full-screen (v4.77.71 redesign)
   ────────────────────────────────────────────────────
   Design premium: gradient da marca com glow radial, ícone check com
   halo pulsante + spring bounce, título 32px com stagger fadeUp,
   subtítulo respirado, confetes estourando do centro + chuva de
   cima. Auto-redirect configurável (sem depender do botão).
═══════════════════════════════════════════════════ */

/* v4.77.84 — Quando a celebração está ativa, esconder a "camada de baixo"
   (header do step e conteúdo do wizard). Elimina definitivamente o flicker
   "form reaparece antes do redirect": mesmo que o overlay seja removido por
   qualquer motivo antes da navegação completar, não há nada visível por
   baixo. `visibility: hidden` preserva o layout (sem reflow no unmount).
   A flag é removida pelo JS se o redirect for cancelado/falhar. */
body.pharus-celebration-active .head__app,
body.pharus-celebration-active #step-content {
    visibility: hidden !important;
}

.pharus-celebration-overlay {
    position: fixed;
    inset: 0;
    z-index: 999999997;
    background:
        radial-gradient(circle at 50% 20%,
            color-mix(in srgb, var(--main-color, #3B82F6) 25%, transparent) 0%,
            transparent 55%),
        linear-gradient(180deg,
            color-mix(in srgb, var(--main-color, #3B82F6) 96%, #fff) 0%,
            var(--main-color, #3B82F6) 55%,
            color-mix(in srgb, var(--main-color, #3B82F6) 78%, #000) 100%);
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    padding: 32px 24px;
    text-align: center;
    opacity: 0;
    transition: opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1);
    overflow: hidden;
    isolation: isolate;
    font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display',
                 'Inter', system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.pharus-celebration-overlay.is-visible { opacity: 1; }

/* v4.77.80 — Variante milestone: celebração intermediária mais sutil.
   Usada após o cadastro (primeiro passo) antes do extended-profile.
   Diferenças: gradient mais claro (menos dramático), ícone em cor neutra
   (não verde de sucesso) — reserva o visual "congrats máximo" pra celebração
   final do fluxo. Mesmo layout base, só tokens de cor trocados. */
.pharus-celebration-overlay--milestone {
    background: linear-gradient(135deg,
            color-mix(in srgb, var(--main-color, #3B82F6) 92%, #fff) 0%,
            var(--main-color, #3B82F6) 60%,
            color-mix(in srgb, var(--main-color, #3B82F6) 85%, #000) 100%);
}
.pharus-celebration-overlay--milestone .pharus-celebration-overlay__icon {
    color: var(--main-color, var(--color-brand, #3B82F6));
    /* Ícone de avanço fica menor ainda (seta é mais "leve" que check). */
    width: 64px;
    height: 64px;
    font-size: 28px;
}

/* v4.77.80 — Título e subtítulo da milestone: menores que os do final.
   Final: título 32px "Bem-vindo ao clube!" — momento auge.
   Milestone: título 22px "Primeiro passo dado!" — momento transição. */
.pharus-celebration-overlay--milestone .pharus-celebration-overlay__title {
    font-size: 22px;
    margin-bottom: 8px;
}
.pharus-celebration-overlay--milestone .pharus-celebration-overlay__subtitle {
    font-size: 14px;
    max-width: 320px;
}

/* Halo radial pulsante atrás do ícone — amplia o glow da marca */
.pharus-celebration-overlay::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 400px;
    height: 400px;
    border-radius: 50%;
    background: radial-gradient(
        circle,
        rgba(255, 255, 255, 0.18) 0%,
        rgba(255, 255, 255, 0) 60%
    );
    transform: translate(-50%, -115%);
    animation: pharusCelHalo 2.8s ease-in-out infinite;
    z-index: -1;
    pointer-events: none;
}

@keyframes pharusCelHalo {
    0%, 100% { opacity: 0.6; transform: translate(-50%, -115%) scale(1); }
    50%      { opacity: 1;   transform: translate(-50%, -115%) scale(1.15); }
}

.pharus-celebration-overlay__icon {
    /* v4.77.80 — Reduzido de 104x104 (font 52) pra 72x72 (font 36).
       Antes dominava demais a tela e parecia desproporcional. Halos
       reduzidos (8+16→6+12) pra manter hierarquia visual. */
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.95);
    color: var(--color-success, #10B981);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 36px;
    margin-bottom: 24px;
    box-shadow:
        0 12px 36px rgba(0, 0, 0, 0.22),
        0 0 0 6px rgba(255, 255, 255, 0.12),
        0 0 0 12px rgba(255, 255, 255, 0.06);
    animation:
        pharusCelIconPop 0.65s cubic-bezier(0.34, 1.56, 0.64, 1) both,
        pharusCelIconFloat 3.2s ease-in-out 0.65s infinite;
}

@keyframes pharusCelIconPop {
    0%   { transform: scale(0) rotate(-180deg); opacity: 0; }
    60%  { transform: scale(1.15) rotate(10deg); opacity: 1; }
    100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

@keyframes pharusCelIconFloat {
    0%, 100% { transform: translateY(0) scale(1); }
    50%      { transform: translateY(-6px) scale(1.02); }
}

.pharus-celebration-overlay__title {
    font-size: 32px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: #fff;
    margin: 0 0 12px;
    line-height: 1.15;
    text-shadow: 0 2px 16px rgba(0, 0, 0, 0.2);
    opacity: 0;
    transform: translateY(14px);
    animation: pharusCelFadeUp 0.55s 0.28s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.pharus-celebration-overlay__subtitle {
    font-size: 15px;
    font-weight: 400;
    letter-spacing: -0.005em;
    color: rgba(255, 255, 255, 0.88);
    margin: 0 0 36px;
    max-width: 300px;
    line-height: 1.5;
    opacity: 0;
    transform: translateY(14px);
    animation: pharusCelFadeUp 0.55s 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Botão "Ver ofertas" — opcional, geralmente o overlay auto-redireciona.
   Se aparecer, fica discreto (ghost com border branca translucente). */
.pharus-celebration-overlay .btn {
    margin-top: 8px;
    min-height: 48px;
    height: 48px;
    max-width: 280px;
    width: 100%;
    background: rgba(255, 255, 255, 0.16) !important;
    border: 1.5px solid rgba(255, 255, 255, 0.3) !important;
    color: #fff !important;
    font-weight: 600;
    letter-spacing: -0.005em;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-radius: 14px !important;
    opacity: 0;
    transform: translateY(14px);
    animation: pharusCelFadeUp 0.55s 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
    transition: background 0.2s ease-out, transform 0.1s ease-out;
}
.pharus-celebration-overlay .btn:hover {
    background: rgba(255, 255, 255, 0.24) !important;
}
.pharus-celebration-overlay .btn:active {
    transform: translateY(0) scale(0.98);
}

/* Progress ring de auto-redirect (se setado via JS) */
.pharus-celebration-overlay__progress {
    position: absolute;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    width: 140px;
    height: 3px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.18);
    overflow: hidden;
    opacity: 0;
    animation: pharusCelFadeUp 0.4s 1s ease-out both;
}
.pharus-celebration-overlay__progress::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.9);
    transform-origin: left center;
    transform: scaleX(0);
    animation: pharusCelProgressFill var(--pharus-cel-redirect, 3s) linear 1s forwards;
}
@keyframes pharusCelProgressFill {
    to { transform: scaleX(1); }
}

/* Confetes estourando do centro (burst) */
.pharus-celebration-overlay__burst {
    position: absolute;
    top: 38%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 0;
    height: 0;
    pointer-events: none;
    z-index: 5;
}
.pharus-celebration-overlay__burst span {
    position: absolute;
    top: 0;
    left: 0;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    transform-origin: center;
    animation: pharusCelBurst 1.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes pharusCelBurst {
    0%   {
        transform:
            translate(-50%, -50%)
            rotate(var(--cel-rot, 0deg))
            translateX(0)
            scale(0);
        opacity: 1;
    }
    20%  {
        transform:
            translate(-50%, -50%)
            rotate(var(--cel-rot, 0deg))
            translateX(20px)
            scale(1);
        opacity: 1;
    }
    100% {
        transform:
            translate(-50%, -50%)
            rotate(calc(var(--cel-rot, 0deg) + 360deg))
            translateX(var(--cel-dist, 220px))
            translateY(var(--cel-fall, 200px))
            scale(0.6);
        opacity: 0;
    }
}

@keyframes pharusCelFadeUp {
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .pharus-celebration-overlay::before,
    .pharus-celebration-overlay__icon,
    .pharus-celebration-overlay__burst span {
        animation: none !important;
    }
}

/* ─────────────────────────────────────────────────────────────
   v4.77.25 — step-login: botões sociais padronizados com o auth-gate.
   Containers do SDK (#googleBtn / #appleBtn) ficam escondidos;
   usamos botões custom (#googleBtnCustom / #appleBtnCustom) com a
   mesma classe canônica .auth-btn-social já usada no welcome.
───────────────────────────────────────────────────────────────*/
.auth-social-sdk-hidden,
.step-1 #googleBtn,
.step-1 #appleBtn {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    opacity: 0 !important;
    pointer-events: none !important;
    overflow: hidden !important;
    clip: rect(0 0 0 0);
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
}

/* v5.3.36 — botões agora vivem dentro de .step-1__social (.auth-gate__social),
   que cuida de gap/direção. Mantemos só o espaço externo do bloco. */
.step-1 .step-1__social {
    margin: var(--space-3) 0;
}

/* ───────────────────────────────────────────────────────────────
   OTP — Input de 6 dígitos (estilo banco)
   v5.13.x — usado no step-verify-code-forgot-password.php
─────────────────────────────────────────────────────────────── */
.otp-wrap { display: flex; flex-direction: column; align-items: stretch; }

.otp-hint {
    font-size: 14px;
    color: var(--color-text-muted, #6b7280);
    text-align: center;
    line-height: 1.5;
    margin: 0 0 16px;
}

.otp-fields {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    margin: 16px 0 8px;
    direction: ltr;
}

.otp-fields .otp-digit {
    width: 44px;
    height: 56px;
    padding: 0;
    text-align: center;
    font-size: 26px;
    font-weight: 700;
    color: var(--color-text, #111827);
    background: #ffffff;
    border: 2px solid var(--color-border, #e5e7eb);
    border-radius: 12px;
    outline: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, background .15s ease;
    -moz-appearance: textfield;
    appearance: textfield;
}
.otp-fields .otp-digit::-webkit-outer-spin-button,
.otp-fields .otp-digit::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.otp-fields .otp-digit:focus {
    border-color: var(--color-primary, #2563eb);
    box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
    transform: translateY(-1px);
}
.otp-fields .otp-digit.filled {
    border-color: var(--color-primary, #2563eb);
    background: #f8fafc;
}

.otp-fields.error .otp-digit {
    border-color: #ef4444;
    background: #fef2f2;
    color: #b91c1c;
    box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.10);
}
.otp-fields.success .otp-digit {
    border-color: #10b981;
    background: #ecfdf5;
    color: #047857;
    box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.10);
}

@keyframes pharusOtpShake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}
.otp-fields.shake { animation: pharusOtpShake 0.4s ease; }

.otp-message {
    font-size: 13px;
    line-height: 1.4;
    margin: 4px 0 0;
    text-align: center;
    display: none;
}
.otp-message.error   { color: #b91c1c; }
.otp-message.success { color: #047857; }

.otp-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}
.otp-actions a {
    color: var(--color-primary, #2563eb);
    font-size: 14px;
    text-decoration: none;
    cursor: pointer;
    padding: 6px 8px;
}
.otp-actions a:hover { text-decoration: underline; }
.otp-actions .otp-back { color: var(--color-text-muted, #6b7280); }

/* Telas estreitas — encolhe quadrados sem quebrar layout */
@media (max-width: 380px) {
    .otp-fields { gap: 6px; }
    .otp-fields .otp-digit { width: 40px; height: 52px; font-size: 22px; border-radius: 10px; }
}


