/* ============================================================
   ExpoCommerce Uberaba — tela do evento
   Paleta e tipografia herdadas do tema oficial do evento:
   navy do CDL Hall + ciano do circuito de neon da cenografia.
   ============================================================ */
:root{
  --bg-0:#050B24;
  --bg-1:#0A1640;
  --bg-2:#122055;

  --ink:#F5F7FF;
  --ink-dim:#A9B4D6;
  --ink-faint:#8189AD;
  --rule:rgba(255,255,255,.14);
  --rule-strong:rgba(255,255,255,.26);

  --accent:#2BE0FF;      /* ciano do neon — estrutura, texto de destaque */
  --accent-2:#3D5CFF;    /* azul royal do logotipo — massa, preenchimento */
  --accent-warm:#FF6A3D; /* coral — só oferta/urgência */

  --font-display:'Space Grotesk', 'Inter Tight', system-ui, sans-serif;
  --font-body:'Inter Tight', system-ui, sans-serif;
  --font-mono:'IBM Plex Mono', ui-monospace, monospace;

  --radius:14px;
  /* viewport-fit=cover (no <meta>) deixa a página desenhar embaixo do
     notch/ilha dinâmica/cantos arredondados do iPhone — sem isso a gente
     assume essa responsabilidade de volta manualmente. Usa o MAIOR entalhe
     dos dois lados nos dois lados (em vez de padding-left/right
     separados): um pouco de padding "sobrando" do lado sem entalhe é
     inofensivo, faltar do lado que tem é que corta conteúdo de verdade. */
  --safe:max(clamp(20px, 4vw, 80px), env(safe-area-inset-left), env(safe-area-inset-right));

  /* elevação/superfície reaproveitadas nos cartões "premium" (palestrante,
     patrocínio, modal de evento) — um único lugar pra manter a mesma
     profundidade e o mesmo gradiente sutil de superfície em todo o site. */
  --shadow-card:0 24px 50px -18px rgba(2,4,16,.6);
  --shadow-card-hover:0 30px 64px -16px rgba(2,4,16,.72), 0 0 0 1px rgba(43,224,255,.16);
  --surface-gradient:linear-gradient(160deg, var(--bg-1) 0%, var(--bg-2) 150%);
}

*{box-sizing:border-box;}
/* sem barra de rolagem visível (tela de evento, sem chrome de navegador à
   mostra) — a página continua rolável por toque, roda do mouse ou teclado,
   só a barra em si é que não aparece. Isso também evita o salto horizontal
   que a barra causava ao aparecer/desaparecer entre a splash e a página. */
html{
  scroll-behavior:smooth;
  scrollbar-width:none;
  -ms-overflow-style:none;
}
::-webkit-scrollbar{width:0;height:0;display:none;}
body{
  position:relative;
  margin:0;
  background:var(--bg-0);
  color:var(--ink);
  font-family:var(--font-body);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block;}
a{color:inherit;}
h1,h2,h3{font-family:var(--font-display);margin:0 0 .3em;}

/* ---------- splash de abertura ----------
   Câmera assimétrica (punch rápido + settle bem mais longo — a mesma
   lógica de dois tempos do cameraPush do motor de apresentações, só que
   aqui num keyframe só: o stop em 30% troca a curva de "entrada" (rápida,
   acelerando) pra "assentamento" (lenta, desacelerando bastante), então
   a câmera "chega correndo e desacelera devagar" em vez de um ease único.
   Por cima: vinheta + scanlines (textura de lente, paradas, não empurram
   com a câmera) e o texto entra em blocos mascarados (eyebrow → UBERABA →
   data/local → régua), como um card de abertura de verdade, não só logo
   + cidade. Saída: a câmera continua empurrando pra frente (mais um
   avanço + blur) ao mesmo tempo que funde — não é só um dissolve. */
body.tem-splash{overflow:hidden;}
.splash{
  position:fixed;inset:0;z-index:999;
  display:flex;align-items:center;justify-content:center;
  background:radial-gradient(120% 100% at 50% 40%, #0A1230 0%, #030309 70%, #010104 100%);
  overflow:hidden;
  opacity:1;
  transition:opacity .85s cubic-bezier(.4,0,1,1);
}
.splash.is-saindo{opacity:0;pointer-events:none;}
.splash.is-saindo .splash__camera{
  transition:transform .85s cubic-bezier(.4,0,1,1), filter .85s cubic-bezier(.4,0,1,1);
  transform:scale(1.14);
  filter:blur(7px);
}

.splash__camera{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  transform-origin:50% 50%;
  animation:splashCameraPush 2s both;
}
@keyframes splashCameraPush{
  0%{transform:scale(1.18);filter:blur(15px);animation-timing-function:cubic-bezier(.7,0,.84,0);}
  30%{transform:scale(1.015);filter:blur(1.5px);animation-timing-function:cubic-bezier(.16,1,.3,1);}
  100%{transform:scale(1);filter:blur(0);}
}

/* vinheta + scanlines: textura de lente sobre a cena, fixas (não escalam
   com o push da câmera) — igual o motor de apresentações usa como "post"
   em vez de fazer parte do movimento da cena. */
.splash__vinheta{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(120% 92% at 50% 45%, transparent 48%, rgba(1,1,4,.62) 100%);
  mix-blend-mode:multiply;
}
.splash__scanlines{
  position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.3;
  background:repeating-linear-gradient(to bottom, rgba(255,255,255,.06) 0 1px, transparent 1px 3px);
  mix-blend-mode:soft-light;
}

@media (prefers-reduced-motion: reduce){
  .splash__camera{animation:none;}
  .splash.is-saindo .splash__camera{transition:none;transform:none;filter:none;}
}

.splash__estrelas{
  position:absolute;inset:-10%;
  background-repeat:repeat;
  animation:splashPiscar 5s ease-in-out infinite;
}
.splash__estrelas--1{
  background-image:
    radial-gradient(1px 1px at 12% 22%, #fff, transparent 100%),
    radial-gradient(1px 1px at 78% 58%, #fff, transparent 100%),
    radial-gradient(1.5px 1.5px at 45% 82%, #fff, transparent 100%),
    radial-gradient(1px 1px at 63% 12%, #fff, transparent 100%),
    radial-gradient(1px 1px at 25% 48%, #fff, transparent 100%),
    radial-gradient(1.5px 1.5px at 92% 30%, #fff, transparent 100%);
  background-size:240px 240px;
  opacity:.55;
}
.splash__estrelas--2{
  background-image:
    radial-gradient(1px 1px at 30% 10%, #cfe6ff, transparent 100%),
    radial-gradient(1.5px 1.5px at 55% 65%, #cfe6ff, transparent 100%),
    radial-gradient(1px 1px at 85% 85%, #cfe6ff, transparent 100%),
    radial-gradient(1px 1px at 8% 75%, #cfe6ff, transparent 100%),
    radial-gradient(1.5px 1.5px at 70% 40%, #cfe6ff, transparent 100%);
  background-size:340px 340px;
  opacity:.4;
  animation-delay:1.6s;
}
.splash__estrelas--3{
  background-image:
    radial-gradient(1px 1px at 20% 60%, #fff, transparent 100%),
    radial-gradient(1px 1px at 50% 20%, #fff, transparent 100%),
    radial-gradient(1.5px 1.5px at 88% 12%, #fff, transparent 100%),
    radial-gradient(1px 1px at 38% 90%, #fff, transparent 100%),
    radial-gradient(1px 1px at 95% 68%, #fff, transparent 100%);
  background-size:170px 170px;
  opacity:.5;
  animation-delay:3s;
}
@keyframes splashPiscar{
  0%,100%{opacity:.3;}
  50%{opacity:.75;}
}

/* mesmo motivo de vidro flutuante do herói, só que em repouso (a splash
   dura pouco demais pra flutuação contínua valer a pena) — a ideia é dar
   ao olho uma "âncora" visual que atravessa o corte splash → herói, como
   se fosse a mesma cena revelada aos poucos. */
.splash__forma{
  position:absolute;
  border-radius:22px;
  opacity:0;
  border:1px solid rgba(61,92,255,.2);
  background:linear-gradient(135deg, rgba(61,92,255,.1) 0%, rgba(13,63,181,.02) 100%);
  box-shadow:inset 0 0 100px rgba(61,92,255,.14);
  animation:splashFormaIn 1.4s cubic-bezier(.16,1,.3,1) .5s both;
}
.splash__forma--1{
  top:16%;right:10%;
  width:min(22vw, 220px);height:min(22vw, 220px);
  transform:rotate(-10deg);
}
.splash__forma--2{
  bottom:12%;left:9%;
  width:min(13vw, 130px);height:min(13vw, 130px);
  border-color:rgba(43,224,255,.18);
  background:linear-gradient(135deg, rgba(43,224,255,.09) 0%, rgba(43,224,255,.02) 100%);
  box-shadow:inset 0 0 80px rgba(43,224,255,.12);
  transform:rotate(15deg);
  animation-delay:.68s;
}
@keyframes splashFormaIn{ to{opacity:.9;} }

.splash__conteudo{
  position:relative;z-index:1;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  text-align:center;
}

/* logo: alvo do push da câmera + um glint de luz que cruza a arte uma vez,
   depois de tudo assentado — como se a luz pegasse no metal/vidro da marca.
   Duas camadas separadas de propósito: o wrap não corta nada (senão o
   drop-shadow/glow da logo, que se espalha bem além da própria arte, seria
   cortado em uma caixa retangular visível); só o .splash__logo-clip por
   cima (do tamanho exato da img, via inset:0) recorta o glint. */
.splash__logo-wrap{position:relative;display:inline-block;margin-bottom:8px;}
.splash__logo-wrap img{
  width:min(60vw, 380px);height:auto;display:block;
  filter:drop-shadow(0 0 40px rgba(43,224,255,.25));
}
.splash__logo-clip{position:absolute;inset:0;overflow:hidden;pointer-events:none;}
.splash__sweep{
  position:absolute;top:-50%;left:0;width:36%;height:200%;
  background:linear-gradient(78deg, transparent, rgba(255,255,255,.5), transparent);
  transform:translateX(-220%) rotate(10deg);
  animation:splashSweep 1s cubic-bezier(.4,0,.2,1) 1.6s both;
}
@keyframes splashSweep{
  0%{transform:translateX(-220%) rotate(10deg);opacity:0;}
  18%{opacity:1;}
  70%{opacity:1;}
  100%{transform:translateX(220%) rotate(10deg);opacity:0;}
}

/* eyebrow → UBERABA → data/local: cada linha mora num "mask" que esconde a
   parte de baixo e a texto sobe de dentro dele — o mesmo bloco pra reveal
   de headline do motor de apresentações, sem SplitText/GSAP: aqui é só
   overflow:hidden no container + translateY no span de dentro. */
.splash__eyebrow, .splash__cidade, .splash__meta{
  margin:0;overflow:hidden;
}
.splash__eyebrow span, .splash__cidade span, .splash__meta span{
  display:block;
  transform:translateY(130%);
  opacity:0;
  animation:splashLinha .7s cubic-bezier(.16,1,.3,1) both;
}
@keyframes splashLinha{
  to{transform:translateY(0);opacity:1;}
}
.splash__eyebrow{
  font-family:var(--font-mono);font-size:12px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--accent);
}
.splash__eyebrow span{animation-delay:.68s;}
.splash__cidade{
  font-family:var(--font-mono);font-size:14px;letter-spacing:.5em;
  text-transform:uppercase;color:var(--ink-dim);padding-left:.5em;
}
.splash__cidade span{animation-delay:.95s;}
.splash__meta{
  font-family:var(--font-mono);font-size:12px;letter-spacing:.03em;
  color:var(--ink-faint);
}
.splash__meta span{animation-delay:1.32s;}

.splash__regua{
  display:block;width:56px;height:1px;margin-top:6px;
  background:linear-gradient(90deg, transparent, var(--accent), transparent);
  transform:scaleX(0);opacity:0;
  animation:splashRegua .6s cubic-bezier(.16,1,.3,1) 1.62s both;
}
@keyframes splashRegua{
  to{transform:scaleX(1);opacity:1;}
}

@media (prefers-reduced-motion: reduce){
  .splash__estrelas{animation:none;opacity:.45;}
  .splash__sweep{animation:none;opacity:0;}
  .splash__forma{animation:none;opacity:.9;}
  .splash__eyebrow span, .splash__cidade span, .splash__meta span{animation:none;transform:none;opacity:1;}
  .splash__regua{animation:none;transform:scaleX(1);opacity:1;}
}

/* absolute (não fixed) e ancorado no body, não no viewport: assim os halos
   rolam junto com a página em vez de ficarem presos à janela — era isso
   que criava aquela faixa de cor visível toda vez que a borda de uma seção
   cruzava por cima de um halo parado no mesmo ponto da tela.
   Altura travada em 100vh (não `inset:0`/100% da página): o degradê da
   grade abaixo é calculado em % da altura desta caixa, então esticá-la
   pelo tamanho do documento inteiro faz a grade ficar "ligada" em opacidade
   quase total por milhares de pixels — e é isso que cria a segunda quebra
   de cor, bem visível assim que o hero (opaco) termina. */
.bg-glow{
  position:absolute;top:0;left:0;right:0;height:100vh;z-index:-1;
  overflow:hidden;
  background:var(--bg-0);
  /* o corte de `overflow:hidden` cai bem no meio do brilho do orb--b (o
     centro do radial-gradient fica perto o bastante da borda inferior da
     caixa para ainda estar bem aceso ali) — sem essa máscara, o corte vira
     uma faixa clara e reta bem no meio da página. A máscara apaga tudo
     para transparente antes de chegar na borda, então o corte acontece em
     cima de algo que já não tem mais brilho nenhum. */
  mask-image:linear-gradient(to bottom, #000 0%, #000 85%, transparent 100%);
  -webkit-mask-image:linear-gradient(to bottom, #000 0%, #000 85%, transparent 100%);
}
.bg-glow__orb{
  position:absolute;
  width:70vmax;height:70vmax;
  border-radius:50%;
  filter:blur(80px);
  will-change:transform;
}
.bg-glow__orb--a{
  top:-25vmax;left:-20vmax;
  background:radial-gradient(circle, rgba(43,224,255,.22), transparent 65%);
  animation:driftA 26s ease-in-out infinite;
}
.bg-glow__orb--b{
  bottom:-30vmax;right:-20vmax;
  background:radial-gradient(circle, rgba(61,92,255,.26), transparent 65%);
  animation:driftB 32s ease-in-out infinite;
}
.bg-glow__grid{
  position:absolute;inset:-2px;
  background-image:
    linear-gradient(rgba(43,224,255,.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(43,224,255,.06) 1px, transparent 1px);
  background-size:64px 64px;
  mask-image:radial-gradient(80% 60% at 50% 0%, #000 0%, transparent 75%);
  animation:gridDrift 40s linear infinite;
}
@keyframes driftA{
  0%,100%{transform:translate(0,0) scale(1);}
  50%{transform:translate(6vw,8vh) scale(1.12);}
}
@keyframes driftB{
  0%,100%{transform:translate(0,0) scale(1);}
  50%{transform:translate(-7vw,-6vh) scale(1.15);}
}
@keyframes gridDrift{
  0%{background-position:0 0, 0 0;}
  100%{background-position:64px 128px, 64px 128px;}
}
@media (prefers-reduced-motion: reduce){
  .bg-glow__orb, .bg-glow__grid{animation:none;}
}

/* kicker: pequeno traço em degradê antes do texto — mesma assinatura visual
   da régua da splash (splashRegua), só que em repouso — costura a
   identidade "circuito" em toda cabeça de seção, não só na abertura. */
.eyebrow{
  display:inline-flex;align-items:flex-start;gap:9px;
  font-family:var(--font-mono);
  font-size:13px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--accent);
  margin:0 0 12px;
}
/* align-items:flex-start (não center) + este offset: se o eyebrow quebrar
   em 2 linhas numa tela estreita, o traço fica alinhado com a primeira
   linha em vez de flutuar no meio do bloco inteiro. */
.eyebrow::before{
  content:'';
  width:18px;height:1px;flex:none;margin-top:.6em;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow:0 0 8px rgba(43,224,255,.6);
}
/* variante "isso está acontecendo agora": o traço vira um ponto pulsante
   em vez da barra estática — só usada no eyebrow "Ao vivo" do mapa, pra
   não competir com o mesmo tracinho repetido em toda outra seção. */
.eyebrow--vivo::before{
  width:6px;height:6px;margin-top:5px;border-radius:50%;
  background:var(--accent);
  animation:timelinePulso 1.8s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce){
  .eyebrow--vivo::before{animation:none;}
}

/* ---------- topbar ---------- */
.topbar{
  position:sticky;top:0;z-index:40;
  background:rgba(5,11,36,.92);
  backdrop-filter:blur(10px);
  border-bottom:1px solid var(--rule);
}
.topbar__inner{
  max-width:1280px;margin:0 auto;
  display:flex;align-items:center;gap:32px;
  padding:22px var(--safe);
  /* topo da página = onde o notch/status bar do iPhone realmente cai;
     sem isso a logo/relógio nasceriam parcialmente atrás dele. */
  padding-top:max(22px, env(safe-area-inset-top));
}
.topbar__brand{display:inline-flex;transition:opacity .2s ease;}
.topbar__brand:hover{opacity:.8;}
.topbar__brand img{height:40px;}
.topbar__nav{display:flex;gap:30px;margin-left:auto;font-size:15.5px;}
.topbar__nav a{
  position:relative;
  text-decoration:none;color:var(--ink-dim);
  padding-bottom:3px;
  transition:color .15s;
}
/* sublinhado em degradê que "abre" da esquerda pro hover — mesmo par de
   cores do kicker do eyebrow, então o mesmo gesto de marca aparece tanto
   parado (cabeça de seção) quanto em interação (navegação). */
.topbar__nav a::after{
  content:'';position:absolute;left:0;right:100%;bottom:0;height:1px;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  transition:right .25s cubic-bezier(.16,1,.3,1);
}
.topbar__nav a:hover{color:var(--accent);}
.topbar__nav a:hover::after{right:0;}
.topbar__clock{
  display:flex;flex-direction:column;align-items:flex-end;
  font-family:var(--font-mono);line-height:1.2;
}
.topbar__clock-time{font-size:20px;color:var(--accent);font-weight:600;transition:color .2s;}
.topbar__clock-time.is-zerado{color:var(--accent-warm);}
.topbar__clock-label{font-size:12px;color:var(--ink-faint);}
/* só aparece com ?atraso= aplicado (ver app.js) — avisa que o "agora" da
   tela foi deslocado de propósito, pra não parecer relógio errado. */
.topbar__clock-atraso{font-size:10px;color:var(--accent-warm);white-space:nowrap;}

.topbar__burger{
  display:none;
  flex-direction:column;justify-content:center;gap:5px;
  width:38px;height:38px;padding:0;
  background:transparent;border:1px solid var(--rule-strong);border-radius:8px;
  cursor:pointer;
}
.topbar__burger span{
  display:block;width:18px;height:2px;margin:0 auto;
  background:var(--ink);border-radius:2px;
  transition:transform .2s, opacity .2s;
}
.topbar__burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.topbar__burger[aria-expanded="true"] span:nth-child(2){opacity:0;}
.topbar__burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}

@media (max-width:760px){
  .topbar__inner{flex-wrap:wrap;}
  .topbar__burger{display:flex;order:3;margin-left:12px;}
  .topbar__clock{order:2;margin-left:auto;}

  /* painel do menu: sobrepõe o conteúdo (não empurra o layout), acima de
     tudo na página. Fundo praticamente opaco (não só semitransparente +
     blur) — com blur puro, o hero (foto clara + título grande) ficava
     visível/"sangrando" por trás dos links em navegadores sem suporte real
     a backdrop-filter, uma mistura ilegível. O blur continua como reforço
     onde suportado, mas a legibilidade não depende mais dele. */
  .topbar__nav{
    order:4;
    position:absolute;
    top:100%;left:0;right:0;
    display:flex;
    flex-direction:column;
    width:auto;
    gap:2px;
    margin:0;
    padding:10px var(--safe) 22px;
    background:linear-gradient(180deg, rgba(6,13,40,.98), rgba(4,9,30,.99));
    backdrop-filter:blur(16px);
    -webkit-backdrop-filter:blur(16px);
    border-bottom:1px solid var(--rule);
    box-shadow:0 24px 40px -16px rgba(0,0,0,.7);
    z-index:60;
    opacity:0;
    visibility:hidden;
    transform:translateY(-10px);
    pointer-events:none;
    transition:opacity .3s ease, transform .3s ease, visibility .3s;
  }
  .topbar__nav.is-open{
    opacity:1;
    visibility:visible;
    transform:translateY(0);
    pointer-events:auto;
  }
  .topbar__nav a{
    padding:12px 4px;font-size:16px;
    border-bottom:1px solid var(--rule);
    opacity:0;transform:translateY(-6px);
    transition:opacity .3s ease, transform .3s ease;
  }
  .topbar__nav a:last-child{border-bottom:none;}
  .topbar__nav.is-open a{opacity:1;transform:translateY(0);}
  .topbar__nav.is-open a:nth-child(1){transition-delay:.05s;}
  .topbar__nav.is-open a:nth-child(2){transition-delay:.1s;}
  .topbar__nav.is-open a:nth-child(3){transition-delay:.15s;}
  .topbar__nav.is-open a:nth-child(4){transition-delay:.2s;}
  @media (prefers-reduced-motion: reduce){
    .topbar__nav, .topbar__nav a{transition:none;}
  }
}

/* ---------- hero ---------- */
.hero{
  position:relative;
  min-height:min(84vh, 760px);
  display:flex;align-items:center;
  overflow:hidden;
}
/* mancha de luz ancorada no topo: o espaço entre a topbar e o crachá
   ficava vazio demais só com o .bg-glow global (que é bem sutil nessa
   altura da página) — isso dá peso/profundidade logo na primeira
   dobra, sem virar mais um "objeto" decorativo solto, é luz ambiente. */
.hero::before{
  content:'';
  position:absolute;top:-18%;left:50%;z-index:0;
  transform:translateX(-50%);
  width:min(75vw, 980px);height:65%;
  background:radial-gradient(ellipse at center, rgba(43,224,255,.16) 0%, rgba(61,92,255,.07) 45%, transparent 72%);
  pointer-events:none;
}
/* rede de nós/fios à deriva (js/app.js, initHeroGrafo) — mesma técnica do
   grafo do cronograma, só que em escala de herói: mais densa, com "pulsos"
   de dado viajando por uma ligação de vez em quando (a metáfora é tráfego
   de e-commerce, não decoração gratuita) e um leve paralaxe por mouse.
   Fica por trás do conteúdo (z-index:0 < .hero__grid), sempre por cima do
   .bg-glow global (que é o pano de fundo da página inteira). */
.hero__grafo{
  position:absolute;inset:0;z-index:0;
  width:100%;height:100%;
  pointer-events:none;
}
/* traço em degradê no rodapé do hero — mesma assinatura "circuito" do
   kicker/rodapé, costurando a transição pra próxima seção em vez de um
   corte seco. */
.hero::after{
  content:'';
  position:absolute;left:0;right:0;bottom:0;height:1px;z-index:1;
  background:linear-gradient(90deg, transparent, rgba(43,224,255,.5) 20%, rgba(43,224,255,.5) 80%, transparent);
}
.hero__grid{
  position:relative;z-index:1;
  width:100%;max-width:1280px;margin:0 auto;
  padding:104px var(--safe) 88px;
}
.hero__content{
  position:relative;
  max-width:640px;
}
/* entrada em blocos: cada filho direto (badge, título, subtítulo, meta,
   contagem, selo, CTA, scroll cue) sobe, desfoca e some do zero em cascata
   assim que a splash funde por cima — o desfoque extra (em relação ao
   resto do site) ecoa o "assentamento" da câmera da splash, só que mais
   discreto, pra dar a mesma sensação de fluidez na chegada ao conteúdo
   real. */
.hero__content > *{
  opacity:0;
  transform:translateY(22px);
  filter:blur(6px);
  transition:opacity .9s cubic-bezier(.16,1,.3,1), transform .9s cubic-bezier(.16,1,.3,1), filter .9s cubic-bezier(.16,1,.3,1);
}
body:not(.tem-splash) .hero__content > *{opacity:1;transform:translateY(0);filter:blur(0);}
.hero__content > *:nth-child(1){transition-delay:.05s;}
.hero__content > *:nth-child(2){transition-delay:.15s;}
.hero__content > *:nth-child(3){transition-delay:.26s;}
.hero__content > *:nth-child(4){transition-delay:.37s;}
.hero__content > *:nth-child(5){transition-delay:.48s;}
.hero__content > *:nth-child(6){transition-delay:.59s;}
.hero__content > *:nth-child(7){transition-delay:.7s;}
/* forma de crachá/ticket (ponta cortada à direita) em vez do pill
   arredondado padrão de "badge de anúncio" que qualquer site usa — faz
   mais sentido num evento físico (crachá/ingresso) do que uma pílula
   genérica. clip-path corta caixa, borda e sombra juntos, então a borda
   só fica visível nas arestas retas — é intencional, não bug. */
.hero__badge{
  position:relative;
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--font-mono);
  font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);
  padding:10px 34px 10px 16px;
  border:1px solid rgba(43,224,255,.35);
  background:rgba(43,224,255,.08);
  box-shadow:0 0 24px rgba(43,224,255,.14);
  margin:0 0 22px;
  clip-path:polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%);
}
.hero__badge-dot{
  width:6px;height:6px;flex:none;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 10px rgba(43,224,255,.85);
}
.hero__badge-sep{opacity:.4;margin:0 1px;}
.hero__title{
  font-size:clamp(44px, 7.8vw, 104px);
  line-height:1.01;
  letter-spacing:-.025em;
  font-weight:700;
}
/* "Uberaba" em degradê ciano→azul — o mesmo par de cores do kicker/CTA,
   só que aplicado como acento de título em vez de traço/botão; é a
   assinatura visual da marca subindo pro elemento mais importante da tela. */
.hero__title-accent{
  background:linear-gradient(135deg, var(--accent-2) 0%, var(--accent) 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 30px rgba(43,224,255,.22));
}
.hero__subtitle{
  font-size:clamp(16px, 2vw, 22px);
  color:var(--ink-dim);
  max-width:600px;
  margin:16px 0 34px;
}
/* linha divisória sutil: separa o bloco "o quê/quando/onde" (badge, título,
   subtítulo, meta) do bloco "ação" logo abaixo (contagem/status + CTA) —
   organiza os dois grupos em vez de empilhar 8 elementos soltos sem
   hierarquia visual entre eles. */
.hero__meta{
  display:flex;flex-wrap:wrap;gap:14px;
  margin-bottom:34px;
  padding-bottom:30px;
  border-bottom:1px solid var(--rule);
}
.hero__meta-item{
  display:flex;align-items:center;gap:13px;
  padding:11px 18px 11px 12px;
  border:1px solid var(--rule);
  border-radius:13px;
  background:rgba(255,255,255,.03);
  backdrop-filter:blur(6px);
  -webkit-backdrop-filter:blur(6px);
}
.hero__meta-icon{
  flex:none;
  display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;
  border-radius:9px;
  background:rgba(43,224,255,.1);
  color:var(--accent);
}
.hero__meta-icon svg{width:16px;height:16px;}
.hero__meta-text{display:flex;flex-direction:column;gap:4px;}
.hero__meta-label{font-size:12px;color:var(--ink-faint);font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.1em;}
.hero__meta-value{font-size:17px;font-weight:600;}

/* wrap + gap: antes só um filho (agendar OU selo) ficava visível por vez —
   agora, ao vivo, o selo e o link "Agora: …" aparecem juntos e precisam de
   espaço pra quebrar linha em telas estreitas sem se sobrepor. */
.status-panel{display:inline-flex;flex-wrap:wrap;align-items:center;gap:10px 16px;}
.status-panel__badge{
  font-family:var(--font-mono);
  font-size:12px;letter-spacing:.08em;text-transform:uppercase;
  background:var(--accent);color:var(--bg-0);
  padding:12px 20px;border-radius:999px;font-weight:600;
  white-space:nowrap;
}
.status-panel__badge.is-live{background:var(--accent-warm);}
.status-panel__badge.is-done{background:var(--ink-faint);color:var(--bg-0);}
/* o selo "AO VIVO AGORA" sozinho não diz o quê — este link some junto
   até o cronograma (tickStatus em app.js) com o título da etapa atual. */
.status-panel__agora[hidden]{display:none;}
.status-panel__agora{
  display:inline-flex;align-items:center;gap:8px;
  font-size:13.5px;color:var(--ink-dim);text-decoration:none;
  padding:6px 2px;
  border-bottom:1px dashed var(--rule-strong);
  transition:color .15s,border-color .15s;
}
.status-panel__agora:hover{color:var(--ink);border-color:var(--accent);}

/* margin-top (não bottom no elemento anterior): countdown e status-panel
   nunca ficam visíveis ao mesmo tempo (tickStatus), então a única forma de
   garantir sempre o mesmo respiro antes do CTA — sem duplicar espaço
   quando o painel de status está vazio (inline-flex não colapsa margem
   como um bloco vazio colapsaria) — é o próximo elemento sempre fornecer
   o próprio gap, nunca o anterior. */
.hero__cta{margin:26px 0 0;}
.hero__cta-primary{
  display:inline-flex;align-items:center;gap:10px;
  font-size:15px;font-weight:600;
  background:linear-gradient(120deg, var(--accent-2), var(--accent));
  color:var(--bg-0);
  padding:15px 26px 15px 24px;border-radius:999px;
  text-decoration:none;
  box-shadow:0 16px 34px -12px rgba(43,224,255,.55);
  transition:transform .18s ease, box-shadow .18s ease;
}
.hero__cta-primary:hover{transform:translateY(-2px);box-shadow:0 20px 40px -10px rgba(43,224,255,.7);}
.hero__cta-primary svg{width:16px;height:16px;flex:none;transition:transform .18s ease;}
.hero__cta-primary:hover svg{transform:translateX(3px);}

/* dica discreta de "tem mais abaixo": trilho + ponto descendo em loop.
   Fica escondida perto do rodapé do hero em telas baixas, pra nunca
   empurrar ou sobrepor o botão de agendar. */
.hero__scroll-cue{
  display:flex;align-items:center;gap:10px;
  margin-top:44px;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-faint);text-decoration:none;
  transition:color .2s ease;
}
.hero__scroll-cue:hover{color:var(--accent);}
.hero__scroll-cue-track{
  position:relative;
  width:1px;height:26px;
  background:var(--rule-strong);
}
.hero__scroll-cue-dot{
  position:absolute;left:50%;top:0;
  width:5px;height:5px;margin-left:-2px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 8px rgba(43,224,255,.8);
  animation:scrollCueDesce 2s cubic-bezier(.4,0,.2,1) infinite;
}
@keyframes scrollCueDesce{
  0%{top:0;opacity:0;}
  15%{opacity:1;}
  85%{opacity:1;}
  100%{top:calc(100% - 5px);opacity:0;}
}
@media (max-width:760px){ .hero__scroll-cue{display:none;} }
@media (prefers-reduced-motion: reduce){
  .hero__content > *{transition:opacity .3s ease;transform:none;filter:none;}
  .hero__scroll-cue-dot{animation:none;top:calc(50% - 2.5px);opacity:1;}
}

/* ---------- sections ---------- */
.section{
  max-width:1280px;margin:0 auto;
  padding:96px var(--safe);
  /* header fixo (.topbar) não deve cobrir o topo da seção ao navegar por
     #âncora do menu — sem isso "Programação"/"Palestrantes" etc. abriam
     com o título parcialmente escondido atrás da barra. */
  scroll-margin-top:96px;
}
.section--grafo{position:relative;z-index:0;overflow:hidden;}
.cronograma-grafo{position:absolute;inset:0;z-index:-1;}
.section__head{max-width:680px;margin-bottom:48px;}
.section__head h2{font-size:clamp(28px,3.4vw,42px);}
.section__lede{color:var(--ink-dim);font-size:16px;margin:0;}

/* legenda de tamanho por cor do mapa 3D: mesmas cores dos estandes
   (js/floorplan-data.js, TIER_COLOR) — fora do viewport, no fluxo normal
   da página, pra nunca competir por espaço com o pill de modo/dica/
   controles lá dentro, em tela nenhuma. Cada ponto ganha um glow na cor
   correspondente — a mesma linguagem "indicador aceso" do resto do site
   (kicker, régua da splash) — em vez de uma bolinha lisa. */
.mapa3d__legenda{
  list-style:none;margin:22px 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:11px 28px;
}
.mapa3d__legenda-item{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--font-mono);font-size:13px;letter-spacing:.03em;
  color:var(--ink-dim);
}
.mapa3d__legenda-cor{width:9px;height:9px;border-radius:50%;flex:none;}
.mapa3d__legenda-cor--p{background:var(--accent);box-shadow:0 0 7px rgba(43,224,255,.6);}
.mapa3d__legenda-cor--m{background:var(--accent-2);box-shadow:0 0 7px rgba(61,92,255,.6);}
.mapa3d__legenda-cor--g{background:#8B6BFF;box-shadow:0 0 7px rgba(139,107,255,.6);}
.mapa3d__legenda-cor--a{background:var(--accent-warm);box-shadow:0 0 7px rgba(255,106,61,.6);}

/* cronograma e mapa têm botão(ões) no cabeçalho — precisam da largura
   toda, não dos 680px padrão de section__head (pensados pra parágrafo de
   texto). */
#cronograma .section__head,
#mapa .section__head{max-width:none;}
.section__head-linha{
  display:flex;align-items:flex-start;justify-content:space-between;gap:24px;flex-wrap:wrap;
}

/* botão que abre a lista/busca de estandes — com 10+ expositores só
   navegáveis girando a câmera 3D, achar um estande específico de vista é
   lento; ver .mapa3d__lista abaixo e a lógica em app.js. */
.mapa3d__buscar-btn{
  display:inline-flex;align-items:center;gap:8px;align-self:center;
  font-family:var(--font-body);font-size:13px;color:var(--ink-dim);
  background:transparent;border:1px solid var(--rule);border-radius:999px;
  padding:9px 16px;cursor:pointer;white-space:nowrap;
  transition:border-color .15s,color .15s,background .15s;
}
.mapa3d__buscar-btn:hover{color:var(--ink);border-color:var(--rule-strong);}
.mapa3d__buscar-btn[aria-expanded="true"]{background:var(--accent-2);border-color:var(--accent-2);color:#fff;}

/* ---------- mapa 3D (WebGL via three.js — js/mapa3d.js) ---------- */
.mapa3d-viewport{
  position:relative;
  min-height:460px;
  isolation:isolate;
  overflow:hidden;
  touch-action:none;
  cursor:grab;
  border-radius:var(--radius);
  border:1px solid var(--rule-strong);
  /* moldura de "monitor ao vivo": respiro contínuo e sutil no brilho —
     box-shadow não é cortado pelo overflow:hidden do próprio elemento
     (isso só afeta o conteúdo interno), então a moldura acende por fora
     normalmente. Reforça que o mapa é uma tela viva, não um bloco estático. */
  animation:mapaViewportRespiro 4.5s ease-in-out infinite;
}
@keyframes mapaViewportRespiro{
  0%,100%{box-shadow:var(--shadow-card), 0 0 0 1px rgba(43,224,255,.14), 0 0 42px -14px rgba(43,224,255,.3);}
  50%{box-shadow:var(--shadow-card), 0 0 0 1px rgba(43,224,255,.32), 0 0 60px -10px rgba(43,224,255,.5);}
}
@media (prefers-reduced-motion: reduce){
  .mapa3d-viewport{animation:none;box-shadow:var(--shadow-card), 0 0 0 1px rgba(43,224,255,.2);}
}
.mapa3d-viewport.is-arrastando{cursor:grabbing;}
/* three.js chega via CDN num <script defer> à parte — em conexão mais
   lenta (comum num evento com Wi-Fi compartilhado) a seção pode ficar
   preta por um instante antes do primeiro frame. Este skeleton cobre
   esse vão; js/mapa3d.js marca is-pronto assim que a cena está montada
   e o loop de render começa. */
.mapa3d__carregando{
  position:absolute;inset:0;z-index:3;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;
  background:var(--bg-0);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.04em;color:var(--ink-faint);
  transition:opacity .4s ease;
}
.mapa3d__carregando.is-pronto{opacity:0;pointer-events:none;}
.mapa3d__carregando.is-erro .mapa3d__spinner{display:none;}
.mapa3d__carregando-retry{
  font-family:var(--font-mono);font-size:12px;letter-spacing:.04em;
  color:var(--accent);background:rgba(43,224,255,.12);
  border:1px solid rgba(43,224,255,.4);border-radius:999px;
  padding:8px 18px;cursor:pointer;
}
.mapa3d__carregando-retry:hover{background:rgba(43,224,255,.2);}
.mapa3d__carregando-reportar{
  font-family:var(--font-mono);font-size:11px;color:var(--ink-faint);
  text-decoration:underline;text-underline-offset:2px;
}
.mapa3d__carregando-reportar:hover{color:var(--ink-dim);}
.mapa3d__spinner{
  width:26px;height:26px;border-radius:50%;
  border:2px solid rgba(43,224,255,.18);border-top-color:var(--accent);
  animation:mapaSpinnerGira .8s linear infinite;
}
@keyframes mapaSpinnerGira{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion: reduce){
  .mapa3d__carregando{transition:none;}
  .mapa3d__spinner{animation-duration:1.6s;}
}
/* celular deitado (e qualquer tela baixa em geral): os 460px mínimos
   sobram da altura visível do navegador, empurrando parte do mapa (e o
   card de detalhe, que vive dentro deste container) pra fora da área que
   dá pra ver sem rolar. Encolhe o piso nesse cenário. */
@media (max-height:500px) and (pointer:coarse){
  .mapa3d-viewport{min-height:min(82vh,320px);}
}
#tela3d{position:absolute;inset:0;z-index:1;display:block;width:100%;height:100%;}
/* camada dos rótulos CSS2D (three.js CSS2DRenderer) — fica por cima do
   canvas mas abaixo do hint/controles/card de detalhe. */
.rotulos3d-camada{z-index:2;}

/* painel de busca/lista de estandes — cobre o viewport do mapa (não é um
   popover pequeno) porque a lista de 10+ itens precisa de espaço real pra
   rolar, principalmente em celular. */
.mapa3d__lista[hidden]{display:none;}
.mapa3d__lista{
  position:absolute;inset:0;z-index:7;
  display:flex;flex-direction:column;
  background:rgba(5,11,36,.94);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  animation:mapaListaEntra .18s ease both;
}
@keyframes mapaListaEntra{from{opacity:0;}to{opacity:1;}}
.mapa3d__lista-topo{
  display:flex;align-items:center;gap:10px;
  padding:16px;border-bottom:1px solid var(--rule);flex:none;
}
.mapa3d__lista-input{
  flex:1;min-width:0;
  font-family:var(--font-body);font-size:15px;color:var(--ink);
  background:var(--bg-1);border:1px solid var(--rule-strong);border-radius:999px;
  padding:10px 16px;
}
.mapa3d__lista-input:focus{outline:none;border-color:var(--accent);}
.mapa3d__lista-input::placeholder{color:var(--ink-faint);}
.mapa3d__lista-fechar{
  flex:none;width:32px;height:32px;border-radius:50%;
  border:1px solid var(--rule);background:transparent;color:var(--ink-dim);
  font-size:18px;line-height:1;cursor:pointer;
}
.mapa3d__lista-fechar:hover{color:var(--accent);border-color:var(--accent);}
.mapa3d__lista-itens{
  list-style:none;margin:0;padding:8px;overflow-y:auto;flex:1;
}
.mapa3d__lista-itens button{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-family:var(--font-body);font-size:14.5px;color:var(--ink);text-align:left;
  background:transparent;border:none;border-radius:10px;
  padding:13px 14px;cursor:pointer;
  transition:background .15s;
}
.mapa3d__lista-itens button:hover,
.mapa3d__lista-itens button:focus-visible{background:rgba(43,224,255,.1);outline:none;}
.mapa3d__lista-tier{font-family:var(--font-mono);font-size:11.5px;color:var(--ink-faint);white-space:nowrap;}
.mapa3d__lista-vazio{padding:20px 14px;color:var(--ink-faint);font-size:14px;}

/* alternância perspectiva/planta baixa — mesmo pill do modo de câmera do
   ExpoCommerce-Mapa3D, só que posicionado dentro do viewport (aqui não há
   um cabeçalho próprio pro mapa como naquele projeto). */
.mapa3d__modo{
  position:absolute;left:18px;top:18px;z-index:5;
  display:flex;border:1px solid var(--rule);border-radius:999px;padding:3px;
  background:rgba(10,22,64,.85);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
}
.mapa3d__modo-botao{
  border:none;background:transparent;color:var(--ink-dim);
  font-family:var(--font-body);font-size:12px;padding:6px 12px;border-radius:999px;cursor:pointer;
  transition:background .15s, color .15s;
}
.mapa3d__modo-botao.is-ativo{background:var(--accent-2);color:#fff;}
.mapa3d__modo-botao:not(.is-ativo):hover{color:var(--ink);}

/* rótulos flutuando sobre os estandes — minimalistas, sem fundo: só o
   texto em branco com sombra escura pra continuar legível em cima de
   qualquer cor de estande ou do piso. */
.rotulo3d{
  font-family:var(--font-mono);font-size:11px;font-weight:600;color:#fff;
  text-shadow:0 1px 2px rgba(5,11,36,.9), 0 0 6px rgba(5,11,36,.7);
  pointer-events:none;white-space:nowrap;transform:translateY(-4px);
}
.rotulo3d--zona{
  color:var(--accent);
  letter-spacing:.05em;text-transform:uppercase;font-size:10px;
}
/* logo de patrocinador (estandes 03/37/sebrae) no lugar do número — sem
   placa de fundo, mesma linha minimalista: a arte já vem clara, pensada
   pra ficar em cima de fundo escuro. */
.rotulo3d-logo{
  pointer-events:none;transform:translateY(-4px);
  display:flex;align-items:center;justify-content:center;
  filter:drop-shadow(0 2px 4px rgba(5,11,36,.75));
}
/* max-width vem do JS (js/mapa3d.js, atualizarLogosEstande) — acompanha a
   largura real do estande projetada em tela a cada quadro. max-height aqui
   é só o teto de legibilidade. */
.rotulo3d-logo img{height:auto;width:auto;max-height:60px;display:block;}

.assento3d{
  position:absolute;border-radius:2px;
  box-shadow:0 -2px 0 rgba(0,0,0,.35) inset, 0 1px 0 rgba(255,255,255,.22) inset;
}

.mapa3d__hint{
  position:absolute;left:18px;bottom:18px;z-index:4;
  /* reserva espaço suficiente pros 4 botões de girar/zoom em ponteiro
     grosso (40px cada, maior alvo de toque) + a folga entre eles — sem
     isso, o texto truncado (ellipsis) ainda podia terminar visualmente
     por baixo do primeiro botão em telas estreitas. */
  max-width:calc(100% - 210px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.04em;color:var(--ink-faint);
  pointer-events:none;
}
/* o texto sozinho é fácil de ignorar, principalmente em telas pequenas —
   o glyph balança algumas vezes só na entrada (não continuamente, pra não
   virar ruído visual) pra chamar atenção de que o mapa é arrastável. */
.mapa3d__hint-icone{
  display:inline-block;
  animation:mapaHintBalanca 1.1s ease-in-out 1.4s 3;
}
@keyframes mapaHintBalanca{
  0%,100%{transform:translateX(0);}
  50%{transform:translateX(3px);}
}
@media (prefers-reduced-motion: reduce){
  .mapa3d__hint-icone{animation:none;}
}
.mapa3d__hint, .mapa3d__controles{transition:opacity .2s ease;}
/* o card de detalhe pode nascer bem em cima da dica/dos botões (ele ocupa
   uma faixa generosa perto de onde o estande foi tocado) — sem isso, eles
   ficavam visualmente cobertos e inacessíveis por trás do card. */
.mapa3d-viewport.tem-card-aberto .mapa3d__hint,
.mapa3d-viewport.tem-card-aberto .mapa3d__controles{opacity:0;pointer-events:none;}
@media (prefers-reduced-motion:reduce){
  .mapa3d__hint, .mapa3d__controles{transition:none;}
}
.mapa3d__controles{position:absolute;right:18px;bottom:18px;z-index:5;display:flex;gap:8px;}
.mapa3d__controles button{
  width:32px;height:32px;border-radius:50%;
  border:1px solid var(--rule);background:rgba(10,22,64,.85);color:var(--accent);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  font-size:15px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;
  transition:border-color .15s;
}
.mapa3d__controles button:hover{border-color:var(--accent);}
/* em ponteiro grosso (dedo) o alvo de 32px fica abaixo do recomendado —
   a área de toque cresce sem aumentar o ícone visualmente, via padding
   compensado por box-sizing. */
@media (pointer:coarse){
  .mapa3d__controles button{width:40px;height:40px;font-size:16px;}
}

.mapa-detalhe__fluxo[hidden]{display:none;}
.mapa-detalhe__fluxo{
  align-self:flex-start;display:flex;align-items:center;gap:7px;
  font-family:var(--font-mono);font-size:12px;color:var(--ink-dim);
}
.mapa-detalhe__fluxo-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);}
.mapa-detalhe__fluxo-dot.is-alto{background:var(--accent-warm);}
.mapa-detalhe__compartilhar{
  align-self:flex-start;margin-top:2px;
  font-family:var(--font-mono);font-size:11.5px;color:var(--ink-faint);
  background:transparent;border:none;padding:0;cursor:pointer;
  text-decoration:underline;text-underline-offset:2px;
}
.mapa-detalhe__compartilhar:hover{color:var(--accent);}

.mapa-flutuante[hidden]{display:none;}
.mapa-flutuante{
  position:absolute;z-index:6;
  left:0;top:0; /* reposicionado via JS a cada seleção, ancorado no estande */
  transform:translate(-50%,-100%) translateY(-14px);
}
/* perto do topo do viewport o card não cabe acima — vira pra baixo do
   estande em vez de deslocar a âncora (o que desalinharia a seta). */
.mapa-flutuante.mapa-flutuante--abaixo{
  transform:translate(-50%,0) translateY(14px);
}
.mapa-flutuante__caixa{
  position:relative;
  width:min(250px, calc(100vw - 48px));
  max-height:var(--flutuante-max-altura, none);
  background:var(--bg-1);
  border:1px solid var(--rule-strong);
  border-radius:var(--radius);
  padding:18px 20px;
  display:flex;flex-direction:column;gap:10px;
  overflow-y:auto;
  box-shadow:0 20px 44px rgba(5,11,36,.6);
  pointer-events:auto;
  transform-origin:50% 100%; /* cresce a partir da ponta que toca o estande */
  animation:flutuanteEntra .22s cubic-bezier(.34,1.56,.64,1) both;
}
.mapa-flutuante--abaixo .mapa-flutuante__caixa{
  transform-origin:50% 0%;
}
.mapa-flutuante__caixa::after{
  content:'';
  position:absolute;left:calc(50% + var(--seta-x, 0px));bottom:-7px;width:14px;height:14px;
  background:var(--bg-1);border-right:1px solid var(--rule-strong);border-bottom:1px solid var(--rule-strong);
  transform:translateX(-50%) rotate(45deg);
}
.mapa-flutuante--abaixo .mapa-flutuante__caixa::after{
  bottom:auto;top:-7px;
  border-right:none;border-bottom:none;
  border-left:1px solid var(--rule-strong);border-top:1px solid var(--rule-strong);
}
@keyframes flutuanteEntra{from{opacity:0;transform:scale(.25);}to{opacity:1;transform:scale(1);}}
.mapa-flutuante__fechar{
  position:absolute;top:8px;right:10px;
  width:22px;height:22px;border:none;border-radius:50%;background:transparent;
  color:var(--ink-faint);font-size:16px;line-height:1;cursor:pointer;
}
.mapa-flutuante__fechar:hover{color:var(--accent);background:rgba(43,224,255,.12);}
.mapa-detalhe__eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);margin:0;}
.mapa-flutuante h3{font-size:20px;margin:0;padding-right:16px;}
/* quando o h3 é só a logo (não o título em texto), o padding-right acima
   (reservado pro botão de fechar, que a essa altura do card já ficou pra
   trás — o eyebrow vem antes) empurrava a imagem pro lado esquerdo mesmo
   com margin:auto, porque ela enchia 100% da largura disponível (que
   ficava menor só de um lado). Zerando aqui, a imagem centraliza de
   verdade nos dois casos (logo estreita com sobra de espaço, ou larga
   o bastante pra ocupar tudo). */
.mapa-flutuante h3:has(> .mapa-detalhe__logo){padding-right:0;}
.mapa-detalhe__logo{display:block;height:112px;width:auto;max-width:100%;object-fit:contain;margin:0 auto;}
.mapa-flutuante p{color:var(--ink-dim);font-size:13.5px;margin:0;}
.mapa-detalhe__status{
  align-self:flex-start;
  font-family:var(--font-mono);font-size:12px;
  padding:6px 12px;border-radius:999px;
  background:rgba(43,224,255,.15);color:var(--accent);
  border:1px solid rgba(43,224,255,.4);
}
.mapa-detalhe__status.is-pico{background:rgba(255,106,61,.15);color:var(--accent-warm);border-color:rgba(255,106,61,.4);}
/* fechado/antes-do-evento/encerrado: neutro, sem o cyan de "ao vivo" —
   evita o card soar animado (ex.: "Fechado") na mesma cor de "tudo certo". */
.mapa-detalhe__status.is-fechado{background:rgba(255,255,255,.06);color:var(--ink-dim);border-color:var(--rule);}

/* ---------- cronograma: botão "ver agora" + filtros por tipo ---------- */
/* só aparece com o evento ao vivo (tickStatus/tickTimeline em app.js) —
   rola até o item is-agora, útil se a lista já saiu da viewport. */
.timeline-agora-btn[hidden]{display:none;}
.timeline-agora-btn{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--font-mono);font-size:12.5px;color:var(--accent);
  background:rgba(43,224,255,.1);border:1px solid rgba(43,224,255,.35);
  border-radius:999px;padding:9px 16px;cursor:pointer;white-space:nowrap;
  transition:background .15s,border-color .15s;
}
.timeline-agora-btn:hover{background:rgba(43,224,255,.18);border-color:var(--accent);}
.timeline-agora-btn__dot{
  width:7px;height:7px;border-radius:50%;background:var(--accent-warm);
  box-shadow:0 0 0 3px rgba(255,106,61,.3);
  animation:timelinePulso 1.6s ease-in-out infinite;
}
@keyframes timelinePulso{0%,100%{opacity:1;}50%{opacity:.35;}}

.timeline-filtros{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px;}
.timeline-filtro{
  font-family:var(--font-body);font-size:13px;color:var(--ink-dim);
  background:transparent;border:1px solid var(--rule);border-radius:999px;
  padding:7px 15px;cursor:pointer;transition:border-color .15s,color .15s,background .15s;
}
.timeline-filtro:hover{color:var(--ink);border-color:var(--rule-strong);}
.timeline-filtro.is-ativo{background:var(--accent-2);border-color:var(--accent-2);color:#fff;}
/* dourado em vez do azul padrão dos outros filtros — a mesma cor da
   estrela marcada no item, pra ligar visualmente os dois. */
.timeline-filtro--favoritos.is-ativo{background:#F5B942;border-color:#F5B942;color:var(--bg-0);}

/* ---------- timeline ---------- */
.timeline{
  list-style:none;margin:32px 0 0;padding:0;
  position:relative;
  display:flex;flex-direction:column;gap:10px;
}
/* três camadas empilhadas na mesma régua vertical, cada uma com um
   significado diferente — igual "assistido vs. carregado" de um player de
   vídeo:
   1. trilho = a régua inteira, fixa, dim — só a escala de fundo.
   2. trilha = "até onde você já leu": cresce conforme os itens vão sendo
      revelados na rolagem (ver app.js) — ciano fraco, sem glow, é o que dá
      a sensação de progressão pela programação enquanto o usuário rola.
   3. progresso = "o que já aconteceu de verdade hoje": o preenchimento
      vivo/com glow, na frente de tudo, atualizado a cada segundo com a
      hora real do evento — continua sendo o sinal principal quando o
      evento está de fato ao vivo. Ganha uma ponta acesa (::after) que
      respira — o "você está aqui" do dia, não só uma barra enchendo. */
.timeline__trilho{
  position:absolute;left:0;top:6px;bottom:6px;width:2px;
  background:var(--rule);
}
.timeline__trilha{
  position:absolute;left:0;top:0;width:100%;height:0%;
  background:var(--accent);opacity:.3;
  transition:height .6s cubic-bezier(.16,1,.3,1);
}
.timeline__progresso{
  position:absolute;left:0;top:0;width:100%;height:0%;
  background:linear-gradient(180deg, var(--accent), var(--accent-2));
  box-shadow:0 0 10px rgba(43,224,255,.55);
  transition:height 1s linear;
}
.timeline.tem-agora .timeline__progresso::after{
  content:'';
  position:absolute;left:50%;bottom:0;
  width:11px;height:11px;border-radius:50%;
  transform:translate(-50%, 50%);
  background:var(--accent);
  animation:timelinePonteiroRespiro 1.8s ease-in-out infinite;
}
@keyframes timelinePonteiroRespiro{
  0%,100%{box-shadow:0 0 0 4px rgba(43,224,255,.25), 0 0 16px rgba(43,224,255,.7);}
  50%{box-shadow:0 0 0 8px rgba(43,224,255,.1), 0 0 22px rgba(43,224,255,.9);}
}
/* entrada item a item: cada <li> é observado individualmente (não a lista
   inteira — ver app.js) e ganha .is-revelado sozinho, exatamente quando
   ele cruza a viewport durante a rolagem. O resultado é o cronograma
   "se construindo" conforme o usuário desce a página, não um único burst
   quando a seção aparece — desfoque + leve escala, junto com o
   deslocamento, reforçam essa sensação de chegada (mesma linguagem do
   herói). is-filtrado/is-passado, declarados mais abaixo no arquivo,
   continuam com a mesma especificidade (.timeline li.is-x) e por ordem de
   cascata vencem sobre este estado revelado sempre que os dois se aplicam
   ao mesmo item. Virou cartão (era só linha com borda inferior): cada
   etapa agora tem seu próprio contorno/fundo, então dá pra destacar a
   atual (.is-agora) de um jeito que realmente salta aos olhos. */
.timeline li{
  position:relative;
  /* padding-right 46px (era 22px): dá espaço pra estrela de favorito não
     ficar em cima do número de duração — os dois disputavam o mesmo canto
     superior direito (ver .timeline__favorito, position:absolute). */
  padding:18px 46px 18px 46px;
  display:grid;grid-template-columns:auto 1fr;gap:4px 16px;align-items:center;
  border-radius:12px;
  border:1px solid transparent;
  cursor:pointer;
  opacity:0;
  transform:translateY(28px) scale(.98);
  filter:blur(5px);
  transition:background .2s ease, border-color .2s ease, box-shadow .25s ease, transform .35s cubic-bezier(.16,1,.3,1), opacity .6s cubic-bezier(.16,1,.3,1), filter .6s cubic-bezier(.16,1,.3,1);
}
.timeline li.is-revelado{opacity:1;transform:translateY(0) scale(1);filter:blur(0);}
.timeline li:hover,
.timeline li:focus-visible{
  background:rgba(255,255,255,.035);
  border-color:var(--rule);
  box-shadow:var(--shadow-card-hover);
  transform:translateY(-2px) scale(1);
}
.timeline li:focus-visible{outline:1px solid var(--accent);outline-offset:-1px;}
/* item filtrado pra fora (timeline-filtros): apagado, sem sair do lugar —
   evita a lista pulando/reajustando altura numa tela de totem. */
.timeline li.is-filtrado{opacity:.22;filter:saturate(.4);}

/* seta que "abre" no hover/foco — mesmo gesto do sublinhado do menu e do
   ↗ do rodapé: reforça que a linha inteira é clicável antes mesmo do
   usuário clicar. */
.timeline li::after{
  content:'›';
  position:absolute;right:14px;top:50%;
  font-family:var(--font-display);font-size:20px;line-height:1;color:var(--accent);
  transform:translate(-6px,-54%);
  opacity:0;
  transition:opacity .2s ease, transform .2s ease;
  pointer-events:none;
}
.timeline li:hover::after,
.timeline li:focus-visible::after{opacity:1;transform:translate(0,-54%);}

/* o marcador nasce pequeno (escala .5) e "salta" pro tamanho normal quando
   o item revela — não anima opacity aqui (só transform): a opacity de
   verdade já é controlada pela <li> inteira (que é o pai), então animar
   as duas em paralelo com curvas diferentes ia criar um flicker. O salto
   (easing com overshoot) é o que dá o "vivo" — cada parada da linha do
   tempo parece se acender com um pulinho, não só desvanecer. */
.timeline__marca{
  position:absolute;left:-15px;top:50%;
  transform:translateY(-50%) scale(.5);
  width:30px;height:30px;border-radius:50%;
  background:var(--bg-1);border:2px solid var(--rule-strong);color:var(--ink-dim);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06);
  display:flex;align-items:center;justify-content:center;
  transition:background .15s,border-color .15s,color .15s,box-shadow .3s,transform .5s cubic-bezier(.34,1.56,.64,1);
}
.timeline li.is-revelado .timeline__marca{transform:translateY(-50%) scale(1);}
.timeline li:hover .timeline__marca{transform:translateY(-50%) scale(1.1);}
/* ping: um anel ciano que se expande e some no instante em que o item
   revela — como se aquele ponto da linha do tempo tivesse acabado de ser
   "ligado". Roda só uma vez (a classe .is-revelado não é removida depois,
   então a keyframe não repete) e não deixa resíduo: termina em
   transparente, então o box-shadow volta a ser o que a cascata normal
   definir (nenhum, ou o anel permanente de .is-agora). Delay pequeno pra
   o anel sair depois que o marcador já "pousou" no tamanho normal. */
.timeline li.is-revelado .timeline__marca{animation:marcaPing .7s cubic-bezier(.16,1,.3,1) .15s both;}
@keyframes marcaPing{
  0%{box-shadow:0 0 0 0 rgba(43,224,255,.55);}
  70%{box-shadow:0 0 0 10px rgba(43,224,255,0);}
  100%{box-shadow:0 0 0 10px rgba(43,224,255,0);}
}
/* mesmo ping, mas disparado pelo relógio real (ver tickTimeline em
   app.js) quando uma etapa vira "agora" de verdade — não o reveal de
   rolagem. Cor quente (a mesma do "ao vivo"), pra marcar a virada mesmo
   com a página parada e já lida. */
.timeline li.is-ativado .timeline__marca{animation:marcaAgoraPing .8s cubic-bezier(.16,1,.3,1) both;}
@keyframes marcaAgoraPing{
  0%{box-shadow:0 0 0 0 rgba(255,106,61,.6);}
  70%{box-shadow:0 0 0 14px rgba(255,106,61,0);}
  100%{box-shadow:0 0 0 14px rgba(255,106,61,0);}
}
.timeline__marca svg{width:14px;height:14px;display:block;}
.timeline li[data-tipo="palestra"] .timeline__marca{color:var(--accent);border-color:rgba(43,224,255,.45);}

/* estrela de favorito — fora do grid (como .timeline__marca), canto
   superior direito; separada do resto do <li> pra tocar nela não abrir o
   modal de detalhe junto (ver stopPropagation em app.js). */
.timeline__favorito{
  position:absolute;top:8px;right:8px;z-index:1;
  width:28px;height:28px;border-radius:50%;
  border:none;background:transparent;color:var(--ink-faint);
  font-size:16px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:color .15s,background .15s,transform .15s;
}
.timeline__favorito:hover{background:rgba(245,185,66,.14);color:#F5B942;}
.timeline__favorito.is-ativo{color:#F5B942;transform:scale(1.05);}
.timeline li.is-favorito{border-color:rgba(245,185,66,.35);}

.timeline__time{grid-row:1;font-family:var(--font-mono);color:var(--ink-faint);font-size:14px;}
.timeline__duracao{
  grid-row:1;grid-column:2;justify-self:end;
  font-family:var(--font-mono);color:var(--ink-faint);font-size:11px;
  opacity:.75;
}
.timeline__title{grid-row:2;grid-column:1 / -1;font-size:16px;}
/* etapas-chave (abertura, encerramento): título em degradê — o mesmo
   acento do título do herói, aplicado ao ponto mais importante da lista
   em vez de um simples texto colorido. */
.timeline li[data-key="true"] .timeline__title{
  font-weight:700;
  background:linear-gradient(135deg, var(--accent-2) 0%, var(--accent) 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
}
.timeline li.is-passado{opacity:.45;}
.timeline li.is-passado .timeline__marca{background:var(--bg-1);border-color:var(--ink-faint);color:var(--ink-faint);box-shadow:none;}

/* etapa atual: o cartão inteiro se destaca (fundo e borda na cor quente
   do "ao vivo"), com um respiro contínuo e bem sutil no glow — puramente
   decorativo (não é controle interativo, só reforça "isso está rolando
   agora"), a mesma lógica do glow de fundo do site. */
.timeline li.is-agora{
  background:linear-gradient(135deg, rgba(255,106,61,.14) 0%, rgba(255,106,61,.04) 100%);
  border-color:rgba(255,106,61,.4);
  box-shadow:0 0 0 1px rgba(255,106,61,.12), 0 20px 44px -22px rgba(255,106,61,.4);
  animation:cronogramaAgoraRespiro 2.8s ease-in-out infinite;
}
@keyframes cronogramaAgoraRespiro{
  0%,100%{box-shadow:0 0 0 1px rgba(255,106,61,.12), 0 20px 44px -22px rgba(255,106,61,.4);}
  50%{box-shadow:0 0 0 1px rgba(255,106,61,.28), 0 24px 54px -18px rgba(255,106,61,.58);}
}
.timeline li.is-agora .timeline__marca{
  background:var(--accent-warm);border-color:var(--accent-warm);color:var(--bg-0);
  box-shadow:0 0 0 5px rgba(255,106,61,.25);
  animation:marcaAgoraRespiro 2.8s ease-in-out infinite;
}
@keyframes marcaAgoraRespiro{
  0%,100%{box-shadow:0 0 0 5px rgba(255,106,61,.25);}
  50%{box-shadow:0 0 0 9px rgba(255,106,61,.12);}
}
.timeline li.is-agora[data-key="true"] .timeline__title{
  background:linear-gradient(135deg, #fff 0%, var(--accent-warm) 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
}
.timeline li.is-agora .timeline__time{color:var(--accent-warm);font-weight:700;}
.timeline__now-tag{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;font-weight:700;
  background:var(--accent-warm);color:var(--bg-0);
  border-radius:999px;padding:3px 10px 3px 8px;margin-left:10px;
  vertical-align:middle;
  box-shadow:0 0 14px rgba(255,106,61,.5);
}
.timeline__now-tag::before{
  content:'';width:5px;height:5px;border-radius:50%;flex:none;
  background:var(--bg-0);
  animation:timelinePulso 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce){
  .timeline li{opacity:1;transform:none;filter:none;transition:background .15s ease, border-color .15s ease, box-shadow .15s ease;}
  .timeline li::after{transition:opacity .2s ease;}
  .timeline__marca{transform:translateY(-50%);transition:background .15s,border-color .15s,color .15s;box-shadow:none;}
  .timeline li.is-revelado .timeline__marca{transform:translateY(-50%);animation:none;}
  .timeline li.is-ativado .timeline__marca{animation:none;}
  .timeline__trilha{transition:none;}
  .timeline li.is-agora,
  .timeline li.is-agora .timeline__marca{animation:none;}
  .timeline.tem-agora .timeline__progresso::after{animation:none;}
  .timeline__now-tag::before{animation:none;opacity:1;}
}

/* ---------- cronograma: pop-up de detalhe do evento ---------- */
.evento-modal[hidden]{display:none;}
.evento-modal{
  position:fixed;inset:0;z-index:80;
  display:flex;align-items:center;justify-content:center;
  padding:20px;
  padding:max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
}
.evento-modal__backdrop{
  position:absolute;inset:0;
  background:rgba(5,11,36,.72);
  backdrop-filter:blur(2px);
  animation:eventoModalFundo .18s ease both;
}
@keyframes eventoModalFundo{from{opacity:0;}to{opacity:1;}}
.evento-modal__caixa{
  position:relative;z-index:1;
  width:100%;max-width:420px;
  background:var(--surface-gradient);
  border:1px solid var(--rule-strong);
  border-radius:var(--radius);
  padding:26px 26px 24px;
  display:flex;flex-direction:column;gap:10px;
  box-shadow:0 30px 70px rgba(5,11,36,.7);
  animation:eventoModalEntra .22s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes eventoModalEntra{from{opacity:0;transform:scale(.92) translateY(8px);}to{opacity:1;transform:scale(1) translateY(0);}}
.evento-modal__fechar{
  position:absolute;top:12px;right:12px;
  width:26px;height:26px;border:none;border-radius:50%;background:transparent;
  color:var(--ink-faint);font-size:18px;line-height:1;cursor:pointer;
}
.evento-modal__fechar:hover{color:var(--accent);background:rgba(43,224,255,.12);}
.evento-modal__cabeca{display:flex;align-items:center;gap:14px;}
.evento-modal__icone{
  flex:none;width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(43,224,255,.1);border:1px solid rgba(43,224,255,.35);color:var(--accent);
}
.evento-modal__icone svg{width:19px;height:19px;}
.evento-modal__eyebrow{
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--accent);margin:0 0 2px;
}
.evento-modal__caixa h3{font-size:22px;margin:0;padding-right:20px;}
.evento-modal__horario{font-family:var(--font-mono);color:var(--ink-faint);font-size:13px;margin:0;}
.evento-modal__desc,
.evento-modal__local{color:var(--ink-dim);font-size:14px;margin:0;}
.evento-modal__local{font-size:13px;color:var(--ink-faint);}
.evento-modal__status{
  align-self:flex-start;
  font-family:var(--font-mono);font-size:12px;
  padding:6px 12px;border-radius:999px;
  background:rgba(43,224,255,.15);color:var(--accent);
  border:1px solid rgba(43,224,255,.4);
}
.evento-modal__status.is-pico{background:rgba(255,106,61,.15);color:var(--accent-warm);border-color:rgba(255,106,61,.4);}
.evento-modal__status.is-passado{background:rgba(255,255,255,.06);color:var(--ink-faint);border-color:var(--rule-strong);}

.evento-modal__palestrante[hidden]{display:none;}
.evento-modal__palestrante{
  display:flex;align-items:center;gap:12px;
  margin-top:2px;padding:10px 12px;
  background:rgba(255,255,255,.03);border:1px solid var(--rule);border-radius:10px;
}
.evento-modal__palestrante img{width:40px;height:40px;border-radius:50%;object-fit:cover;flex:none;}
.evento-modal__palestrante span{font-size:13px;color:var(--ink-dim);line-height:1.4;}
.evento-modal__palestrante strong{color:var(--ink);}

.evento-modal__rodape{display:flex;flex-wrap:wrap;gap:10px;margin-top:8px;}
.evento-modal__favorito,
.evento-modal__compartilhar{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--font-body);font-size:13px;color:var(--ink-dim);
  background:transparent;border:1px solid var(--rule);border-radius:999px;
  padding:8px 14px;cursor:pointer;
  transition:border-color .15s,color .15s,background .15s;
}
.evento-modal__favorito:hover,
.evento-modal__compartilhar:hover{color:var(--ink);border-color:var(--rule-strong);}
.evento-modal__favorito.is-ativo{background:rgba(245,185,66,.14);border-color:#F5B942;color:#F5B942;}

/* ---------- palestrantes: carrossel giratório e arrastável ---------- */
.carrossel{
  overflow:hidden;
  margin:0 calc(var(--safe) * -1);
  padding:4px var(--safe);
  cursor:grab;
  touch-action:pan-y;
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);
}
.carrossel.is-arrastando{cursor:grabbing;}
.carrossel__trilho{
  display:flex;
  width:max-content;
  will-change:transform;
  user-select:none;
}
/* cada grupo carrega sua própria margem de fechamento: assim os dois grupos
   (original + duplicata) têm exatamente a mesma largura, e o JS pode andar
   -largura px (um grupo inteiro) sem deixar costura no loop. O giro e o
   arraste são controlados em js/app.js — sem @keyframes aqui, porque o
   arraste precisa poder interromper e retomar o movimento a qualquer ponto. */
.carrossel__grupo{display:flex;gap:22px;margin-right:22px;}
.carrossel__grupo img{-webkit-user-drag:none;}
@media (prefers-reduced-motion: reduce){
  .carrossel{overflow-x:auto;cursor:auto;}
  .carrossel__grupo[aria-hidden="true"]{display:none;}
}

.palestrante{
  position:relative;
  flex:0 0 340px;width:340px;
  background:var(--surface-gradient);border:1px solid var(--rule);border-radius:var(--radius);
  overflow:hidden;
  transition:border-color .25s ease, box-shadow .25s ease, transform .25s ease;
}
/* traço no topo do card, em degradê — o mesmo par accent/accent-2 e o
   mesmo gesto de "abrir da esquerda" do sublinhado do menu/assinatura do
   rodapé, só que na horizontal cheia. Assina o card como parte da mesma
   linguagem visual do resto do site em vez de só levantar+sombra. */
.palestrante::before{
  content:'';
  position:absolute;top:0;left:0;right:0;height:2px;z-index:1;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  transform:scaleX(0);transform-origin:left;
  transition:transform .3s cubic-bezier(.16,1,.3,1);
}
.palestrante:hover::before,
.palestrante:focus-within::before{transform:scaleX(1);}
.palestrante:hover{
  border-color:rgba(43,224,255,.4);
  box-shadow:var(--shadow-card-hover);
  transform:translateY(-4px);
}
.palestrante img{width:100%;aspect-ratio:4/5;object-fit:cover;transition:transform .5s cubic-bezier(.16,1,.3,1);}
.palestrante:hover img{transform:scale(1.05);}
.palestrante h3{font-size:21px;margin:20px 20px 3px;}
.palestrante__cargo{font-size:13.5px;color:var(--accent);margin:0 20px 12px;font-family:var(--font-mono);}
.palestrante__bio{font-size:14.5px;color:var(--ink-dim);margin:0 20px 22px;}

/* ---------- patrocinadores ---------- */
/* Sem caixa nenhuma por trás dos logos — eles vivem direto no fundo da
   página, como uma vitrine só, não uma grade de cartões isolados. O que
   costura tudo (Realização + apoios) num conjunto só, integrado, é: uma
   única régua dividindo as duas camadas e espaçamento generoso e
   consistente — a hierarquia (CDL grande vs. apoios menores, discretos
   até o hover) fala por tamanho/opacidade, não por caixas ou glow. */
.patrocinio{
  display:flex;flex-direction:column;align-items:center;
  margin-bottom:64px;
}

.patrocinio__realizacao{
  display:flex;flex-direction:column;align-items:center;gap:28px;
  padding:12px 24px 44px;
}
.patrocinio__label{
  font-family:var(--font-mono);font-size:12.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);
  display:inline-flex;align-items:center;gap:9px;
}
.patrocinio__label::before{
  content:'';width:18px;height:1px;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow:0 0 8px rgba(43,224,255,.6);
}
.patrocinio__logo-cdl{
  position:relative;
  height:68px;width:auto;max-width:min(80vw,400px);object-fit:contain;
  filter:drop-shadow(0 6px 30px rgba(43,224,255,.3));
}

/* régua única separando "quem realiza" de "quem apoia" — o único traço
   estrutural da seção inteira, mesma assinatura em degradê do resto do
   site (kicker, rodapé), então continua parecendo parte do mesmo layout.
   O ponto pulsando no meio (.patrocinio__linha-no) é o mesmo motivo do
   "Ao vivo" do mapa (timelinePulso) — aqui não é status, é literalmente
   o nó da "rede de apoio" que o texto da seção já menciona. */
.patrocinio__linha{
  position:relative;
  width:100%;max-width:520px;height:1px;
  background:linear-gradient(90deg, transparent, var(--rule-strong) 15%, var(--rule-strong) 85%, transparent);
  margin-bottom:44px;
}
.patrocinio__linha-no{
  position:absolute;top:50%;left:50%;
  width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 10px rgba(43,224,255,.7);
  animation:timelinePulso 2.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce){
  .patrocinio__linha-no{animation:none;}
}

.patrocinio__apoios{display:flex;flex-direction:column;align-items:center;gap:32px;}
.patrocinio__logos{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;
  gap:40px 64px;
}
.patrocinio__logo-item{display:flex;flex-direction:column;align-items:center;gap:14px;}
/* opacidade reduzida em repouso, cheia no hover/foco — o mesmo gesto de
   "logo bar" de sites de produto (marcas discretas até alguém prestar
   atenção nelas), em vez de tudo brigando pelo mesmo peso visual o tempo
   todo. Ainda assim sempre legíveis: nunca abaixo de ~0.75 de opacidade. */
.patrocinio__logo-item img{
  height:56px;width:auto;max-width:180px;object-fit:contain;display:block;
  opacity:.8;
  transition:opacity .25s ease, transform .25s ease;
}
.patrocinio__logo-item:hover img,
.patrocinio__logo-item:focus-within img{opacity:1;transform:translateY(-3px);}
.patrocinio__logo-caption{
  font-family:var(--font-mono);font-size:10.5px;letter-spacing:.06em;
  color:var(--ink-faint);opacity:.65;
  transition:opacity .25s ease, color .25s ease;
}
.patrocinio__logo-item:hover .patrocinio__logo-caption,
.patrocinio__logo-item:focus-within .patrocinio__logo-caption{opacity:1;color:var(--ink-dim);}

@media (max-width:560px){
  .patrocinio__logo-cdl{height:48px;}
  .patrocinio__logos{gap:32px 40px;}
  .patrocinio__logo-item img{height:44px;}
}

/* ---------- botão voltar ao topo ---------- */
.topo-btn[hidden]{display:none;}
.topo-btn{
  position:fixed;right:var(--safe);bottom:max(24px, env(safe-area-inset-bottom));z-index:30;
  width:44px;height:44px;border-radius:50%;
  border:1px solid var(--rule-strong);background:rgba(10,22,64,.85);color:var(--accent);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  box-shadow:0 12px 28px -10px rgba(2,4,16,.6);
  transition:border-color .15s,transform .15s;
}
.topo-btn:hover{border-color:var(--accent);transform:translateY(-2px);}

/* ---------- rodapé ---------- */
.rodape{
  position:relative;
  padding:64px var(--safe) 40px;
  border-top:1px solid var(--rule);
  color:var(--ink-faint);font-size:13px;
}
/* traço em degradê centrado sobre a borda — a mesma assinatura "circuito"
   do kicker/splash, fechando o site com a mesma marca com que ele abre. */
.rodape::before{
  content:'';position:absolute;top:-1px;left:50%;
  transform:translateX(-50%);
  width:120px;height:1px;
  background:linear-gradient(90deg, transparent, var(--accent), transparent);
}
/* três colunas (marca / local & contato / realização) em vez do antigo
   bloco único centralizado — organiza o que antes era só um parágrafo
   atrás do outro, sem informação nova. Empilha e centraliza de novo
   abaixo de 760px. */
.rodape__grid{
  display:grid;
  grid-template-columns:1.3fr 1fr 1fr;
  gap:40px;
  max-width:1100px;margin:0 auto;
  text-align:left;
}
.rodape__logo{height:26px;margin:0 0 16px;filter:brightness(0) invert(1);opacity:.85;}
.rodape__tagline{margin:0;max-width:280px;line-height:1.55;}
.rodape__label{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);margin:0 0 14px;
}
.rodape__linha{margin:0 0 6px;}
/* linha de contato com ícone: nada de texto sublinhado tipo link
   default de navegador (era isso que deixava o rodapé com cara de
   "sem estilo nenhum") — mesmo formato de ícone-em-caixa do
   .hero__meta-item, só que menor, e o link se anuncia pela cor no hover,
   não por sublinhado permanente. */
.rodape__item{
  display:flex;align-items:flex-start;gap:11px;
  margin:0 0 12px;
  color:var(--ink-faint);
  text-decoration:none;
  line-height:1.5;
  transition:color .15s;
}
.rodape__item:last-child{margin-bottom:0;}
.rodape__item:hover{color:var(--ink-dim);}
.rodape__item-icone{
  flex:none;
  display:flex;align-items:center;justify-content:center;
  width:26px;height:26px;margin-top:-1px;
  border-radius:8px;
  background:rgba(43,224,255,.08);
  color:var(--accent);
  transition:background .15s;
}
.rodape__item-icone svg{width:13px;height:13px;}
.rodape__item:hover .rodape__item-icone{background:rgba(43,224,255,.16);}
@media (max-width:760px){
  .rodape__grid{grid-template-columns:1fr;text-align:center;gap:32px;}
  .rodape__logo{margin:0 auto 16px;}
  .rodape__tagline{margin:0 auto;}
  .rodape__item{justify-content:center;text-align:left;}
}
/* assinatura de quem fez o site: sem placa nem fundo, só o próprio
   conjunto (eyebrow + logo + nome) com bastante espaço acima pra ganhar
   peso de "assinatura" mesmo sem caixa — o clique fica claro pelo
   sublinhado em degradê que abre no nome (mesmo gesto do menu) e pela
   seta que desliza ao lado, não por um cartão. Vira uma barra própria,
   separada da grade acima por uma linha, em vez de só "mais um item"
   empilhado no fim do bloco central antigo. */
.rodape__dev{
  display:flex;flex-direction:column;align-items:center;gap:14px;
  max-width:1100px;margin:52px auto 0;
  padding-top:32px;
  border-top:1px solid var(--rule);
  text-decoration:none;
  text-align:center;
}
.rodape__dev-eyebrow{
  font-family:var(--font-mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-faint);
  transition:color .25s ease;
}
.rodape__dev:hover .rodape__dev-eyebrow,
.rodape__dev:focus-visible .rodape__dev-eyebrow{color:var(--ink-dim);}
.rodape__dev-marca{display:inline-flex;align-items:center;gap:12px;}
.rodape__dev-logo{height:30px;width:auto;transition:opacity .25s ease;}
.rodape__dev:hover .rodape__dev-logo,
.rodape__dev:focus-visible .rodape__dev-logo{opacity:.85;}
.rodape__dev-nome{
  position:relative;
  font-family:var(--font-display);font-size:19px;font-weight:600;
  color:var(--ink);letter-spacing:-.01em;
}
.rodape__dev-nome::after{
  content:'';position:absolute;left:0;right:100%;bottom:-4px;height:1px;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  transition:right .25s cubic-bezier(.16,1,.3,1);
}
.rodape__dev:hover .rodape__dev-nome::after,
.rodape__dev:focus-visible .rodape__dev-nome::after{right:0;}
.rodape__dev-seta{
  display:inline-block;
  color:var(--accent);font-size:14px;
  opacity:0;transform:translate(-4px,2px);
  transition:opacity .2s ease, transform .2s ease;
}
.rodape__dev:hover .rodape__dev-seta,
.rodape__dev:focus-visible .rodape__dev-seta{opacity:1;transform:translate(0,0);}
@media (max-width:480px){
  .rodape__dev-nome{font-size:16px;}
}
