/* balões de "Ecossistema Transoft" reaproveitam .ic--logo (mesma classe
   já usada nos itens de logo da lista .showcase__list, ver seção
   "Seção 'Uma empresa de tecnologia...'" no CLAUDE.md) — essa regra
   específica (mesma especificidade de .float-card .h .ic acima, 3
   classes, mas declarada depois) sobrescreve o quadrado fixo 32x32
   genérico pra manter a largura automática que os logos precisam. */
.float-card .h .ic--logo{width:auto;height:36px;padding:0 10px}
.float-card .h .ic--logo img{max-height:18px;max-width:100px}
/* descrição de produto (balões do "Ecossistema Transoft") — texto mais
   longo que o .s original (que era só uma métrica curta tipo "+12% vs
   ontem"), por isso cor mais neutra e sem negrito, pra não brigar com o
   nome do produto (.v) logo acima. */
.float-card__desc{font-size:12px;color:var(--text-dim);margin-top:6px;line-height:1.5}
/* posições próprias pro contexto do "Ecossistema Transoft" — o container
   (.showcase__visual--floatcards) é bem menor que o .hero__right
   original, então os 3 balões precisam de um arranjo mais compacto. */
.showcase__visual--floatcards .fc-1{top:8%;right:8%;width:220px}
.showcase__visual--floatcards .fc-2{top:40%;left:6%;width:210px}
.showcase__visual--floatcards .fc-3{bottom:6%;right:12%;width:215px}
.section--tight{padding:90px 0}
/* pequeno rótulo azul acima do título de seção — genérico, reaproveitável
   em qualquer .section__head (estreado na seção de valores do sobre.html,
   "Nossos valores" acima de "No que a Transoft acredita"). .section__title
   já tem margin-top:18px, que cuida sozinho do espaçamento abaixo deste
   rótulo sem precisar de margin extra aqui. */
.section__eyebrow{
  display:block;
  font-size:13px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-dim);font-weight:700;
}
/* ========================================================
   MARQUEE — segmentos
   ======================================================== */
.marquee{
  position:relative;
  padding:38px 0;
  overflow:hidden;
}
.marquee::before,.marquee::after{
  content:"";position:absolute;top:0;bottom:0;width:140px;z-index:2;pointer-events:none;
}
.marquee::before{left:0;background:linear-gradient(90deg,var(--bg-0),transparent)}
.marquee::after{right:0;background:linear-gradient(-90deg,var(--bg-0),transparent)}
.marquee__track{
  display:flex;gap:60px;width:max-content;
  animation:marqueeScroll var(--marquee-duration,32s) linear infinite;
}
.marquee__set{display:flex;gap:60px}
/* variante do marquee pra logos de clientes (sobre.html, "Empresas que
   confiam em nós") — reaproveita o mesmo .marquee/[data-marquee-track]
   genérico (initMarquee() já clona qualquer .marquee__set que encontrar,
   sem precisar de mudança nenhuma no JS), só troca o conteúdo do
   .marquee__set de texto+ícone por <img> direto. Mesmo tratamento
   "dim → branco no hover" do .clients-strip da home. */
.marquee__logo{height:72px;width:auto;object-fit:contain;opacity:.5;transition:opacity .3s;flex-shrink:0}
.marquee__logo:hover{opacity:1}
/* gap maior só nesta instância — os logos ficaram bem maiores (72px, ver
   .marquee__logo acima) e o gap:60px genérico (compartilhado com a faixa de
   texto "Urbano · Fretamento..." da home) ficava apertado demais nesta
   escala. Escopado do mesmo jeito que o resto dos overrides desta seção. */
.clients-marquee-section .marquee__track,
.clients-marquee-section .marquee__set{gap:88px}
.clients-marquee__btn{margin-top:32px}
@keyframes marqueeScroll{to{transform:translateX(var(--marquee-shift,-50%))}}
/* ========================================================
   CONHEÇA NOSSO FUNDADOR (sobre.html) — resumo + modal "BioWiki"
   ======================================================== */
.founder{max-width:800px}
.founder__lead{margin-top:18px;color:var(--text-dim);font-size:16px;line-height:1.75}
.founder__lead strong{color:#fff;font-weight:700}
.founder__lead strong.founder__hl{color:var(--primary-2)}
/* Layout conferido direto na página de referência real
   (tecnomobile.com.br/sobre-nos — o usuário apontou que as tentativas
   anteriores, "adivinhando" pelas capturas, não batiam com o site de
   verdade). Duas correções que só ficaram claras vendo o HTML fonte:
   1) a foto NÃO é cortada por uma caixa de altura fixa — lá é só
      max-width:130px com altura automática (a imagem aparece inteira, do
      jeito que o arquivo é, sem object-fit nenhum). Removido o cálculo de
      altura fixa/object-fit:cover que eu tinha colocado antes.
   2) o botão "Visualizar BioWiki" fica DENTRO da coluna de nome/cargo
      (abaixo do "CEO"), não numa linha separada por baixo de tudo — a
      foto fica à esquerda, alinhada ao centro vertical dessa coluna
      inteira (foto + nome/cargo/botão), não só do nome. */
.founder__profile{display:flex;align-items:center;gap:24px;flex-wrap:wrap;margin-top:36px}
.founder__photo{width:100%;max-width:130px;height:auto;display:block;border-radius:15px;flex-shrink:0;box-shadow:3px 2px 16px -4px rgba(0,0,0,.5)}
.founder__info{display:flex;flex-direction:column;align-items:flex-start}
.founder__name{font-weight:700;color:#fff;font-size:18px;line-height:1.3}
.founder__role{color:var(--text-dim);font-size:14px;margin-top:4px;margin-bottom:18px}
/* modal "BioWiki" — estrutura copiada da referência enviada pelo usuário
   (foto grande à esquerda + card de conteúdo à direita, tag/nome/cargo,
   texto rolável, ícone do LinkedIn no canto inferior direito, botão de
   fechar circular flutuando no canto superior direito, fundo desfocado),
   com as cores adaptadas pra identidade escura do site em vez do card
   branco da referência. Mesma técnica de overlay fixed+backdrop-filter já
   usada no .nav__backdrop do menu mobile. */
.founder-modal{
  position:fixed;inset:0;z-index:200;
  display:flex;align-items:center;justify-content:center;
  padding:24px;
  opacity:0;visibility:hidden;
  transition:opacity .35s var(--ease-out), visibility .35s;
}
.founder-modal.is-open{opacity:1;visibility:visible}
.founder-modal__backdrop{
  position:absolute;inset:0;
  background:rgba(3,5,10,.72);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
/* altura fixa (não max-height) — conferido no CSS de origem
   (#biowikModal .modal-dialog{height:407px} no desktop), é a altura do
   modal que é fixa, não a largura da coluna da foto (ver .founder-modal__photo
   abaixo). Usei 420px (bem perto do 407px original) com min() só de
   segurança pra não estourar em telas curtas, o que a referência não
   tinha — telas muito baixas ali provavelmente já vazavam também. */
.founder-modal__box{
  position:relative;display:flex;
  width:100%;max-width:820px;height:min(420px,82vh);
  border-radius:24px;overflow:hidden;
  background:linear-gradient(180deg, rgba(15,20,35,.98) 0%, rgba(8,12,22,.98) 100%);
  border:1px solid rgba(255,255,255,.08);
  box-shadow:0 40px 100px -30px rgba(0,0,0,.7);
  transform:translateY(24px) scale(.97);opacity:0;
  transition:transform .4s var(--ease-out), opacity .4s var(--ease-out);
}
.founder-modal.is-open .founder-modal__box{transform:translateY(0) scale(1);opacity:1}
.founder-modal__close{
  position:absolute;top:16px;right:16px;z-index:2;
  width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;
  background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);
  color:#fff;transition:background .25s;
}
.founder-modal__close:hover{background:rgba(255,255,255,.18)}
.founder-modal__close svg{width:16px;height:16px}
/* foto: ALTURA 100% do modal, LARGURA automática (acompanha a proporção
   real da imagem) — não o contrário. No CSS de origem é literalmente
   `#biowikModal .modal-img-biowiki{height:100% !important;width:auto}`;
   minha primeira tentativa tinha invertido essa relação (coluna de
   largura fixa, foto encaixada dentro via object-fit), o que podia sobrar
   espaço vazio do lado da foto em vez dela preencher naturalmente. */
.founder-modal__photo-col{flex:0 0 auto;height:100%}
.founder-modal__photo{height:100%;width:auto;object-fit:cover;display:block}
.founder-modal__content{flex:1;min-width:0;display:flex;flex-direction:column;padding:32px 36px}
.founder-modal__head{padding-bottom:20px;border-bottom:1px solid rgba(255,255,255,.08)}
.founder-modal__tag{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-dim)}
.founder-modal__name{font-family:var(--font-display);font-weight:700;font-size:20px;color:#fff;margin-top:6px}
.founder-modal__role{color:var(--text-dim);font-size:14px;margin-top:2px}
/* min-height:0 é necessário aqui: sem isso, um filho flex com flex:1
   dentro de um pai flex-column (.founder-modal__content) nunca encolhe
   abaixo da altura do próprio conteúdo, e o overflow-y:auto nunca chega a
   rolar de verdade — pegadinha clássica de flexbox. */
/* barra de rolagem discreta e personalizada, mesmo padrão já usado no
   .nav__menu mobile — track transparente (deixa o fundo escuro do próprio
   modal aparecer, em vez da barra branca padrão do navegador) com só a
   barrinha arrastável (thumb) visível. */
.founder-modal__body{flex:1;min-height:0;overflow-y:auto;margin-top:20px;padding-right:8px;scrollbar-width:thin;scrollbar-color:rgba(13,110,233,.55) transparent}
.founder-modal__body::-webkit-scrollbar{width:5px}
.founder-modal__body::-webkit-scrollbar-track{background:transparent}
.founder-modal__body::-webkit-scrollbar-thumb{background:rgba(13,110,233,.5);border-radius:999px}
.founder-modal__body::-webkit-scrollbar-thumb:hover{background:rgba(58,141,255,.7)}
.founder-modal__body p{font-size:14.5px;color:var(--text-dim);line-height:1.7;margin-bottom:14px}
.founder-modal__body p:last-child{margin-bottom:0}
.founder-modal__linkedin{
  align-self:flex-end;flex-shrink:0;margin-top:16px;
  width:34px;height:34px;border-radius:8px;
  display:grid;place-items:center;
  background:#0a66c2;color:#fff;
}
.founder-modal__linkedin svg{width:18px;height:18px}
/* abaixo de 576px o site de origem troca a foto retangular inteira por um
   avatar circular pequeno e recortado (150×150, object-fit:cover,
   object-position:top pra manter o rosto enquadrado) — mesmo breakpoint e
   valores exatos do CSS real (#biowikModal .modal-img-biowiki{height:150px;
   width:150px} + >img{border-radius:100%;object-fit:cover;object-position:top}).
   Diferente do resto (altura 100%/largura auto), aqui a referência crop a
   foto de propósito, então reproduzi o crop também em vez de manter
   "sempre inteira" a qualquer custo. */
@media (max-width:575px){
  /* max-height duplicado (vh depois dvh) é de propósito: em navegadores
     mobile, "vh" é calculado pela altura do viewport "cheio" (com a barra
     de endereço escondida) — em mobile Safari/Chrome com a barra visível,
     90vh pode ficar mais alto que a área realmente visível na tela,
     cortando o fim do modal sem deixar nada pra rolar até lá. "dvh"
     (dynamic viewport height, suportado nos navegadores mobile atuais)
     acompanha a altura visível de verdade; a declaração de vh antes serve
     só de fallback pra navegadores mais antigos que não entendem dvh. */
  .founder-modal__box{flex-direction:column;height:auto;max-height:90vh;max-height:90dvh}
  .founder-modal__photo-col{height:auto;flex:0 0 auto;padding-top:28px;display:flex;justify-content:center}
  .founder-modal__photo{width:110px;height:110px;border-radius:50%;object-fit:cover;object-position:top}
  .founder-modal__content{padding:24px}
  /* .founder-modal__body já nasce flex:1;min-height:0;overflow-y:auto (regra
     base, compartilhada com o desktop) — mas aqui .founder-modal__box tem
     height:auto (só limitado por max-height, não uma altura fixa como no
     desktop), então o texto podia crescer sem limite e empurrar o botão do
     LinkedIn pra fora da área visível da tela, sem nenhuma forma de rolar
     até ele. Um teto próprio, só no mobile, garante que apenas o texto role
     dentro de uma caixa de tamanho definido — foto, cabeçalho e o botão do
     LinkedIn ficam sempre visíveis fora dessa área de rolagem, replicando o
     mesmo comportamento que o desktop já tinha (rolagem isolada no corpo do
     texto, resto do modal sempre à vista). */
  .founder-modal__body{max-height:34vh;max-height:34dvh}
}
/* ========================================================
   REDES SOCIAIS (sobre.html) — seção abaixo de "Conheça nosso fundador"
   ======================================================== */
.social-grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:22px;
  margin-top:10px;
}
/* mesma técnica de anel-de-gradiente-só-no-hover já usada em .integ-card
   (mask-composite:exclude) — reaproveitada aqui pra manter os cards
   visualmente na mesma linguagem do resto do site, sem inventar um
   componente novo do zero. */
.social-card{
  position:relative;isolation:isolate;
  padding:28px;
  border-radius:var(--radius-lg);
  background:rgba(15,20,35,.4);
  border:1px solid rgba(255,255,255,.07);
  transition:transform .35s var(--ease-out), border-color .35s, box-shadow .35s;
}
.social-card::before{
  content:"";position:absolute;inset:-1px;border-radius:inherit;padding:1.5px;
  background:linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  opacity:0;transition:opacity .35s;
  pointer-events:none;
}
.social-card:hover{
  transform:translateY(-6px);
  border-color:transparent;
  box-shadow:0 24px 48px -20px rgba(5,7,13,.6);
}
.social-card:hover::before{opacity:1}
/* .social-grid usa .reveal-stagger (não .reveal por card) — a regra
   genérica `.reveal-stagger.in > *{transform:none}` (ver seção "Reveal ao
   rolar") empata em especificidade com `.social-card:hover` (duas classes
   contando o pseudo-classe cada) e vem depois no arquivo, então vencia e
   cancelava o "subir" no hover depois do card já ter entrado em vista —
   mesmo conflito já documentado nos cards do ERP (`.erp-card.reveal.in:
   hover`). Correção: especificidade extra de propósito, três classes. */
.social-grid.reveal-stagger .social-card:hover{transform:translateY(-6px)}
.social-card__top{display:flex;align-items:center;gap:16px}
/* selo do ícone neutro (sem cor de marca nem hover próprio) — pedido
   explícito do usuário depois de ver a versão com selo colorido por rede
   e leve escala/rotação no hover; mesmo tratamento visual de outros
   selos de ícone do site (ex.: .tl-mark__icon). */
.social-card__icon{
  width:52px;height:52px;flex-shrink:0;border-radius:14px;
  display:grid;place-items:center;
  background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.1);
  color:var(--primary-2);
  transition:background .15s, border-color .15s, color .15s;
}
.social-card__icon svg{width:24px;height:24px}
.social-card__info{display:flex;flex-direction:column;min-width:0}
.social-card__name{font-weight:700;color:#fff;font-size:16px;transition:color .15s}
.social-card__handle{color:var(--text-dim);font-size:13.5px;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color .15s}
.social-card__btn{width:100%;justify-content:center;margin-top:22px;transition:transform .25s var(--ease-out), box-shadow .25s, background .15s, color .15s, border-color .15s}
/* Fundo claro sólido da seção, pedido explícito do usuário.
   `position:relative;z-index:1` pelo motivo de sempre: sem isso a grade
   ambiente global (`body::after`, fixed/z-index:0) pintaria por cima do
   fundo sólido em vez de ficar atrás dele. */
.social-section{position:relative;z-index:1;background:#e2e7f0}
.social-section .section__title{color:#0b0f1a}
.social-section .social-card{background:#e9edf5;border-color:rgba(11,15,26,.08);transition:background-color .15s, transform .35s var(--ease-out), border-color .15s, box-shadow .35s}
.social-section .social-card__icon{background:rgba(11,15,26,.05);border-color:rgba(11,15,26,.09);color:var(--primary)}
.social-section .social-card__name{color:#0b0f1a}
.social-section .social-card__handle{color:var(--text-mute)}
.social-section .social-card__btn{color:#0b0f1a;border-color:rgba(11,15,26,.16);background:rgba(11,15,26,.03)}
/* Hover: em vez do anel de gradiente (::before, ver receita genérica do
   .social-card acima), o card claro "vira" escuro — pedido explícito do
   usuário ("a cor do card se altere para um azul mais escuro"). Precisa
   desligar o ::before herdado (`opacity:0` vence o `opacity:1` da regra
   genérica por ter mais especificidade) e reescrever a cor de cada
   elemento filho pro par claro-sobre-escuro, já que o texto/ícone/botão
   dessa seção foram pensados pra ficar sobre um card claro. */
.social-section .social-card:hover{
  background:#0d1f3d;
  border-color:transparent;
  box-shadow:0 24px 48px -20px rgba(5,7,13,.45);
}
.social-section .social-card:hover::before{opacity:0}
.social-section .social-card:hover .social-card__icon{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.14);color:var(--primary-2)}
.social-section .social-card:hover .social-card__name{color:#fff}
.social-section .social-card:hover .social-card__handle{color:var(--text-dim)}
.social-section .social-card:hover .social-card__btn{color:#fff;border-color:rgba(255,255,255,.18);background:rgba(255,255,255,.06)}
.social-section .social-card:hover .social-card__btn:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.34)}
/* Fundo da seção "Uma empresa de tecnologia..." (não do card à direita,
   que continua com sua própria foto — ver .showcase__visual--floatcards
   logo abaixo) — pedido explícito do usuário. Véu escuro (::before,
   z-index:0) garante contraste do texto por cima; .container já é
   z-index:1 globalmente (ver topo do arquivo), então nada mais precisa
   de ajuste. */
.empresa-section{
  position:relative;z-index:1;overflow:hidden;
  background-image:url('../img/background_bulcao_igrejinha.webp');
  background-size:cover;background-position:center;
}
.empresa-section::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:rgba(5,7,13,.87);
}
/* Contraste reforçado em 2 camadas — véu mais opaco (acima) já resolve a
   maior parte, mas texto branco/cinza direto sobre foto ainda corre risco
   em trechos mais claros dela; text-shadow garante legibilidade mesmo
   ali, mesma técnica já usada no rótulo dos .ramo-panel. */
.empresa-section .section__title{text-shadow:0 4px 18px rgba(0,0,0,.55)}
.empresa-section .section__lead{
  color:rgba(255,255,255,.85);
  text-shadow:0 2px 10px rgba(0,0,0,.5);
}
/* "Ecossistema Transoft" reaproveitando os balões flutuantes/arrastáveis
   (.float-card, ver "Estatísticas flutuantes" no CLAUDE.md) no lugar do
   .dash quadrado — pedido explícito do usuário ("esse quadrado feio e
   nada moderno"). Precisa de altura própria pra ancorar os .float-card
   (position:absolute), mesmo raciocínio já usado no
   .showcase__visual--scrollreel logo abaixo. */
.showcase__visual--floatcards{
  height:760px;
  background-image:url('../img/sala_reuniao.webp');
  background-size:cover;
  background-position:center;
}
/* véu escuro por cima da foto — mesma técnica de camadas por z-index já
   documentada em outras seções do site (.tl-slide, .erp-card): foto
   (background-image do próprio elemento, sempre atrás de tudo) → véu
   (::after, z-index:0) → rótulo/balões (z-index:1/2). Sem o véu, o
   rótulo "Ecossistema Transoft" e o texto dos balões perderiam contraste
   dependendo do trecho da foto atrás deles. */
.showcase__visual--floatcards::after{
  content:'';position:absolute;inset:0;z-index:0;
  background:linear-gradient(180deg, rgba(5,7,13,.8) 0%, rgba(5,7,13,.6) 45%, rgba(5,7,13,.88) 100%);
}
/* rótulo "Ecossistema Transoft · 3 produtos" — fica atrás dos balões mas
   na frente do véu, ancorado no canto superior esquerdo do card, dando
   contexto pro que os 3 balões representam sem precisar de outro card. */
.showcase__eco{
  position:absolute;top:30px;left:30px;z-index:1;
  display:flex;align-items:center;gap:10px;
}
.showcase__visual--floatcards .float-card{z-index:2}
.showcase__eco-label{font-size:13px;color:var(--text-dim);font-weight:600}
/* variante pra logo de verdade no lugar do ícone genérico — os 3 logos
   (Transnet, Tecnomobile, Mercado na Rede) são wordmarks horizontais com
   proporções bem diferentes entre si (a do Transnet é bem mais larga que
   as outras duas), então a caixa vira largura automática (em vez do
   quadrado fixo 42x42 do ícone) que se ajusta ao conteúdo; a imagem em si
   usa max-height+max-width (não object-fit, não tem "caixa" fixa pra
   encaixar) pra cada logo ficar do maior tamanho legível possível sem
   estourar o espaço disponível na linha. */
.showcase__item .ic--logo{width:auto;height:44px;flex:0 0 auto;padding:0 14px}
.showcase__item .ic--logo img{max-height:22px;max-width:120px;width:auto;height:auto;display:block}
/* ========================================================
   CABEÇALHO DE PÁGINA (páginas internas)
   ======================================================== */
.page-header{
  padding:200px 0 100px;
  text-align:center;
  position:relative;
  background:
    radial-gradient(600px 300px at 50% 0%, rgba(13,110,233,.25), transparent 60%);
}
.page-header h1{
  font-size:clamp(40px,5vw,70px);
  color:#fff;letter-spacing:-.028em;
}
.page-header h1 span{
  color:var(--primary-2);
}
.page-header p{margin-top:22px;color:var(--text-dim);font-size:18px;max-width:680px;margin-left:auto;margin-right:auto}
/* variante com vídeo de fundo — só em sobre.html (.page-header--video),
   modificador em vez de mudar o .page-header genérico (as outras 6
   páginas internas continuam com o fundo estático de sempre). Camadas por
   z-index, mesma técnica já usada em .erp-card/.tl-slide: vídeo (0) →
   véu de gradiente pro contraste do texto (1) → conteúdo (2). */
/* hero de verdade — ocupa a tela inteira (min-height:100vh, não mais só
   padding grande), mesma receita do .hero da home: min-height:vh +
   display:flex;align-items:center pra centralizar o conteúdo dentro dessa
   altura, em vez de depender só de padding fixo pra "empurrar" a seção
   pra baixo. video/scrim são position:absolute, então saem do fluxo flex
   e continuam cobrindo inset:0 normalmente — só o .container participa do
   center. */
.page-header--video{
  overflow:hidden;
  min-height:100vh;
  display:flex;align-items:center;
  padding:140px 0 80px;
}
.page-header__video{
  position:absolute;inset:0;z-index:0;
  width:100%;height:100%;object-fit:cover;object-position:top;
  filter:saturate(1.05) brightness(.85);
}
/* véu escuro leve — pedido explícito do usuário depois de ter pedido a
   remoção completa do véu forte anterior ("coloque uma sombra leve no
   background"). Tom uniforme bem mais sutil (.36, era .78-.9 na versão
   forte; começou em .28, escurecido "só mais um pouco" a pedido do
   usuário) na maior parte da seção; só nos últimos 38% sobe até
   opacidade 1 (mesma cor de --bg-0) pra continuar "derretendo" no fundo
   da seção seguinte sem deixar uma linha visível na costura — mesma
   técnica de sempre, só que partindo de um tom bem mais claro. */
.page-header__scrim{
  position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg, rgba(5,7,13,.36) 0%, rgba(5,7,13,.36) 62%, rgba(5,7,13,1) 100%);
}
.page-header--video .container{position:relative;z-index:2}
/* texto alinhado à esquerda em vez do centralizado padrão do
   .page-header — pedido do usuário pra fugir do hero-centralizado-
   genérico (o layout mais batido/"cara de IA" pra uma seção assim);
   .page-header__content limita a largura do bloco de texto (senão, sem
   centralização, o parágrafo esticaria até a borda direita do container
   inteiro em telas largas). */
.page-header--video{text-align:left}
/* largura maior que a genérica de outras seções — "Construindo tecnologia"
   (a primeira linha digitada) precisa caber inteira numa linha só nas
   larguras de desktop mais comuns; com 640px ela quebrava numa terceira
   linha extra, além do <br> proposital antes de "desde 1986.". */
.page-header__content{max-width:820px}
.page-header--video p{margin-left:0;margin-right:0}
/* .page-header h1 span{color:var(--primary-2)} (regra genérica, pensada
   pras outras 6 páginas — lá só o trecho em destaque vem dentro de um
   <span>) deixava os dois .page-header__type azuis aqui, já que agora o
   <h1> inteiro é dividido em dois <span> (um por linha digitada, ver
   initHeroTypewriter()), não só o destaque. Mesma especificidade da regra
   genérica (.page-header--video h1 span = 1 classe + 2 tags, igual a
   .page-header h1 span) — como esta vem depois no arquivo, vence e volta
   o texto pro branco padrão do <h1>. :not(.page-header__shine) exclui o
   span que tem o degradê animado (ver abaixo) — senão esta regra venceria
   por especificidade e sobrescreveria o color:transparent que o
   background-clip:text precisa pra funcionar. */
.page-header--video h1 span:not(.page-header__shine){color:#fff}
/* título virou o elemento secundário da seção (ver .hero-quote logo
   abaixo) — pedido explícito do usuário pra inverter tamanho/evidência
   entre título e citação, com a citação virando o texto "de destaque" e
   o título encolhendo. Mesma especificidade de ".page-header h1" (1
   classe + 1 elemento) — como esta vem depois no arquivo, vence. */
.page-header--video h1{
  font-size:clamp(18px,2vw,22px);
  font-weight:500;letter-spacing:-.01em;
  color:var(--text-dim);
  margin-top:20px;
}
.page-header__actions{margin-top:36px}
/* Citação de JK rolando devagar na vertical (discurso inteiro, sem
   segmentar em trechos que alternam — versão anterior, revertida a
   pedido do usuário), agora ACIMA do título e como elemento em maior
   evidência da seção — pedido explícito do usuário pra inverter tanto a
   posição quanto o tamanho/destaque entre o título e a citação (era o
   inverso: título grande em cima, citação pequena embaixo). Tamanho/peso
   trocados com o que o <h1> tinha antes (clamp(40px,5vw,70px),
   font-display, branco); o <h1> (ver acima, ".page-header--video h1")
   herdou o tamanho pequeno que a citação tinha. Itálico mantido — ainda
   lê como citação, só que agora grande. Seletores prefixados com
   .hero-quote (2 classes) de propósito — a regra genérica ".page-header
   p{margin-top:22px;color:var(--text-dim);font-size:18px;max-width:680px;
   margin-left:auto;margin-right:auto}" (1 classe + 1 elemento) tem a
   mesma especificidade que ".hero-quote__scroll" sozinho (1 classe), e
   por vir depois no arquivo venceria; ".hero-quote .hero-quote__scroll"
   (2 classes) garante que esta regra sempre vença, independente da
   ordem. */
.hero-quote{position:relative;margin-top:0;max-width:820px}
/* texto inteiro rolando devagar dentro de uma janela fixa. Altura do
   viewport em `em` (não px fixo), pra acompanhar o clamp() de font-size
   do texto em qualquer largura de tela: ~3 linhas visíveis de cada vez
   (3 × line-height 1.15 + uma folga pequena pra não cortar a linha de
   cima/baixo no meio da rolagem). Máscara em degradê nas bordas de
   cima/baixo — pedido explícito do usuário depois de ver o corte seco no
   meio de uma linha (o `overflow:hidden` sempre cortou ali, só que sem
   nenhuma transição visual suavizando); a linha que está entrando/saindo
   agora esmaece até transparente antes de tocar a borda, em vez de ser
   cortada de repente. */
.hero-quote__viewport{
  position:relative;overflow:hidden;
  font-size:clamp(40px,5vw,70px);
  height:3.85em;
  mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%);
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%);
}
/* --hq-start/--hq-end setados via JS (initHeroQuoteScroll(), main.js) com
   a altura real medida do viewport e do parágrafo — garante que o texto
   comece exatamente na borda de baixo da janela (sem atraso vazio no
   início do ciclo) e só termine de fato depois de sair inteiro pela borda
   de cima (sem cortar a última linha). Fallback (sem JS, ou antes do JS
   rodar) usa %, relativo à própria altura do parágrafo — ainda funciona,
   só não encaixa perfeitamente nas bordas da janela. */
.hero-quote .hero-quote__scroll{
  position:absolute;top:0;left:0;width:100%;margin:0;
  color:#fff;font-style:italic;font-family:var(--font-display);
  font-weight:600;letter-spacing:-.025em;
  font-size:1em;line-height:1.15;
  animation:heroQuoteScroll 26s linear infinite;
}
@keyframes heroQuoteScroll{
  from{transform:translateY(var(--hq-start,100%))}
  to{transform:translateY(var(--hq-end,-100%))}
}
@media (prefers-reduced-motion:reduce){
  .hero-quote__viewport{height:auto;overflow:visible;mask-image:none;-webkit-mask-image:none}
  .hero-quote .hero-quote__scroll{position:static;animation:none;transform:none}
}
/* referência da citação — pedido explícito do usuário, fonte pequena
   embaixo do texto rolando. Não é .hero-quote__scroll (fica fora da
   janela/animação, sempre visível, parada). */
.hero-quote .hero-quote__cite{
  margin:14px 0 0;color:var(--text-dim);
  font-size:14px;font-style:normal;letter-spacing:0;
}
/* linha do tempo — carrossel por década com abas, estilo "Adobe Firefly"
   (referência visual enviada pelo usuário). Abas trocam a década (.tl-slide);
   dentro do slide ativo, os marcos funcionam em acordeão — só o marco
   clicado expande ícone+título+descrição, os outros ficam só com
   ícone+título (ver initTimelineCarousel() no main.js). */
/* trilho único arredondado envolvendo as abas (referência: barra de tabs
   do Adobe Firefly) — só a aba ativa vira uma pill preenchida, as outras
   ficam só como texto dentro do mesmo trilho, sem borda/fundo próprios.
   Cores seguem a identidade do site (gradiente --primary→--primary-2 na
   aba ativa), só o layout foi copiado da referência. A pill ativa é um
   elemento à parte (.tl-tabs__indicator, position:absolute), não o
   background do próprio botão — é isso que permite ela "deslizar" de uma
   aba pra outra (transform/width animados via transition) em vez de só
   aparecer/desaparecer de repente. Posição/tamanho calculados em JS
   (moveIndicator() dentro de initTimelineCarousel(), main.js), já que
   dependem da largura real de cada botão (texto variável). */
.tl-tabs{position:relative;display:flex;flex-wrap:wrap;gap:4px;width:fit-content;max-width:100%;margin:0 auto 28px;padding:6px;border-radius:999px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08)}
.tl-tabs__indicator{position:absolute;top:0;left:0;border-radius:999px;background:linear-gradient(135deg,var(--primary),var(--primary-2));box-shadow:0 10px 26px -10px var(--primary-glow);transition:transform .35s var(--ease-out), width .35s var(--ease-out), height .35s var(--ease-out);z-index:0;pointer-events:none}
.tl-tab{position:relative;z-index:1;padding:10px 22px;border-radius:999px;border:none;background:transparent;color:var(--text-dim);font-weight:600;font-size:14px;transition:color .25s}
.tl-tab:hover{color:#fff}
.tl-tab.active{color:#fff}
.tl-carousel{position:relative}
.tl-slide{display:none;position:relative;overflow:hidden;border-radius:28px;min-height:600px;border:1px solid rgba(255,255,255,.08)}
.tl-slide.active{display:block}
/* imagem (ou vídeo) de fundo full-bleed, uma por década — não mais por
   marco (ver .tl-mark, que perdeu data-tl-bg: os marcos só abrem/fecham o
   próprio texto no acordeão, sem trocar o fundo do slide). background-image
   inline no próprio .tl-slide__bg (mesma técnica/motivo do .erp-card__img:
   custom property com url() relativo quebraria, pois resolveria relativo à
   folha de estilo em vez do HTML) cobre o caso de foto; se um dia for
   vídeo, basta colocar um <video> dentro do .tl-slide__bg (ver regra
   abaixo) no lugar do background-image. background-color é o fallback
   enquanto a imagem/vídeo real não existe. */
.tl-slide__bg{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:#0b0f1a;background-size:cover;background-position:center}
.tl-slide__bg img,.tl-slide__bg video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
/* gradiente escuro-esquerda → transparente-direita, mesma receita do
   .erp-card::before, garantindo contraste pro texto sobreposto à esquerda */
/* mais paradas que o degradê original, com queda gradual (nunca mais que
   ~.2 de opacidade entre uma parada e a seguinte) — pedido explícito do
   usuário depois de ver uma "linha" nítida separando a área escura da
   clara, mais visível ainda agora que o fundo é vídeo (movimento chama
   atenção pra qualquer costura). */
.tl-slide::before{content:'';position:absolute;inset:0;z-index:1;background:linear-gradient(90deg, rgba(5,7,13,.96) 0%, rgba(5,7,13,.9) 20%, rgba(5,7,13,.76) 38%, rgba(5,7,13,.56) 54%, rgba(5,7,13,.34) 68%, rgba(5,7,13,.14) 82%, rgba(5,7,13,0) 100%)}
/* área de texto alargada (era 540px) — pedido explícito do usuário pra
   caber mais texto no acordeão sem depender só do max-height do
   .tl-mark__text (ver logo abaixo). */
.tl-slide__body{position:relative;z-index:2;max-width:660px;padding:56px}
.tl-slide__title{font-family:var(--font-display);font-size:26px;color:#fff;margin-bottom:12px}
.tl-slide__lead{font-size:15px;color:var(--text-dim);line-height:1.7;margin-bottom:32px}
/* marcos em acordeão — mesma técnica de max-height do .nav__sub mobile */
.tl-marks{display:flex;flex-direction:column;gap:4px}
/* linha divisória só aparece encostada no marco ativo (acima e abaixo
   dele) — entre dois marcos inativos fica sem linha nenhuma. Por isso a
   borda começa transparente em todos e só o .active (mais o irmão logo
   depois dele, que é quem desenha a linha de baixo) recebe a cor real. */
.tl-mark{text-align:left;padding:12px 0;border-top:1px solid transparent;transition:border-color .3s}
.tl-mark:first-child{border-top:none}
.tl-mark.active,
.tl-mark.active + .tl-mark{border-top-color:rgba(255,255,255,.08)}
.tl-mark__head{display:flex;align-items:center;gap:12px}
.tl-mark__icon{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.06);color:var(--primary-2);flex-shrink:0;transition:background .3s,color .3s}
.tl-mark__icon svg{width:16px;height:16px}
.tl-mark__title{font-size:15px;font-weight:600;color:#fff}
.tl-mark__text{
  display:block;max-height:0;opacity:0;overflow:hidden;font-size:13px;color:var(--text-dim);line-height:1.6;padding-left:44px;
  transition:max-height .4s var(--ease-out), opacity .3s var(--ease-out), margin-top .4s var(--ease-out);
  /* barra de rolagem discreta, com cor tanto no polegar quanto na trilha
     (não só no polegar sobre trilha transparente) — pedido explícito do
     usuário. scrollbar-color cobre Firefox; os três ::-webkit-scrollbar-*
     cobrem Chrome/Safari/Edge. */
  scrollbar-width:thin;
  scrollbar-color:rgba(255,255,255,.2) rgba(255,255,255,.06);
}
.tl-mark__text::-webkit-scrollbar{width:6px}
.tl-mark__text::-webkit-scrollbar-track{background:rgba(255,255,255,.06);border-radius:999px}
.tl-mark__text::-webkit-scrollbar-thumb{background:rgba(255,255,255,.2);border-radius:999px}
.tl-mark__text::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.32)}
/* tamanho máximo da caixa de texto do marco ativo — textos que ultrapassem
   isso rolam dentro da própria caixa (overflow-y:auto) em vez de estourar
   o card ou serem cortados sem aviso (o overflow:hidden da regra base
   acima só existe pra esconder o texto todo quando max-height:0). */
.tl-mark.active .tl-mark__text{max-height:230px;opacity:1;margin-top:8px;overflow-y:auto;padding-right:14px}
.tl-mark.active .tl-mark__icon{background:linear-gradient(135deg,var(--primary),var(--primary-2));color:#fff}
/* botão "Conhecer soluções" por marco/slide, pedido explícito do usuário,
   posicionado no canto inferior direito do card — é irmão do
   .tl-slide__body (não filho dele), pra poder se posicionar relativo ao
   card inteiro (.tl-slide, que já tem position:relative) em vez de ficar
   preso à coluna de texto de 540px. Sobra bastante espaço vazio à direita
   (onde a imagem de fundo aparece livre, sem texto por cima), então o
   botão absoluto não esbarra em nada no desktop. */
.tl-slide__cta{position:absolute;right:40px;bottom:40px;z-index:2}
@media (max-width:900px){
  /* trilho de abas vira barra horizontal arrastável/deslizável (scroll
     nativo por toque) em vez de quebrar em várias linhas empilhadas —
     pedido explícito do usuário depois de ver as 5 abas quebrando em 3
     linhas no mobile (`flex-wrap:wrap` da regra genérica). `flex-wrap:
     nowrap` impede a quebra; `overflow-x:auto` deixa o conteúdo (mais
     largo que o trilho) rolar horizontalmente — a largura do `.tl-tabs`
     continua limitada por `max-width:100%` (regra genérica), então é o
     conteúdo interno que estoura e rola, não o elemento em si. Scrollbar
     escondida (`scrollbar-width:none`/`::-webkit-scrollbar{display:none}`)
     pra parecer um gesto de arrastar, não uma barra de rolagem comum.
     `.tl-tabs__indicator` (posicionado via `offsetLeft/offsetTop`, ver
     `moveIndicator()` no main.js) continua funcionando sem nenhuma
     mudança: esses valores são relativos ao `.tl-tabs` (seu
     `offsetParent`), não à viewport, então a pill acompanha a aba certa
     mesmo com o trilho rolado.
     Toque já rola nativo por causa do `overflow-x:auto`; o `cursor:grab`/
     `.is-dragging{cursor:grabbing}` abaixo são pro arrasto por
     mouse/trackpad, que não tem gesto de rolagem nativo — ver o bloco de
     `pointerdown/move/up` em `initTimelineCarousel()` (main.js) que move
     `root.scrollLeft` conforme o ponteiro anda. */
  .tl-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;justify-content:flex-start;cursor:grab}
  .tl-tabs::-webkit-scrollbar{display:none}
  .tl-tabs.is-dragging{cursor:grabbing}
  .tl-tab{flex-shrink:0}
  /* escurecimento leve nas duas pontas, sinalizando que dá pra arrastar
     pra ver mais abas — pedido explícito do usuário. Camadas extras de
     `background-image` (não um ::before/::after à parte) de propósito:
     um pseudo-elemento posicionado dentro do próprio `.tl-tabs` rolaria
     junto com o conteúdo (ele também é filho do elemento com
     overflow-x:auto), saindo de vista assim que o usuário rolasse —
     `background-image` num elemento não acompanha o *conteúdo* dele ao
     rolar (`background-attachment` padrão é `scroll`, que trava o fundo
     na caixa do próprio elemento, não no conteúdo interno), então essas
     duas manchas ficam sempre grudadas nas pontas visíveis do trilho,
     não importa o quanto ele tenha rolado. `border-radius:999px` do
     `.tl-tabs` já corta essas manchas na forma de pílula de graça
     (background sempre respeita o border-radius por padrão). */
  .tl-tabs{
    background-image:
      linear-gradient(90deg, rgba(5,7,13,.55) 0%, transparent 100%),
      linear-gradient(-90deg, rgba(5,7,13,.55) 0%, transparent 100%);
    background-repeat:no-repeat;
    background-position:left center, right center;
    background-size:32px 100%, 32px 100%;
  }
  .tl-slide{min-height:auto}
  .tl-slide__body{max-width:none;padding:32px 24px}
  .tl-slide::before{background:linear-gradient(180deg, rgba(5,7,13,.45) 0%, rgba(5,7,13,.62) 30%, rgba(5,7,13,.82) 55%, rgba(5,7,13,.94) 78%, rgba(5,7,13,.97) 100%)}
  /* no mobile o .tl-slide__body passa a ocupar a largura toda e cresce
     conforme os marcos abrem/fecham no acordeão — um botão absoluto fixo
     no canto inferior do card correria o risco de sobrepor o último
     marco. Em vez disso, o botão sai do position:absolute e volta ao
     fluxo normal (depois do .tl-slide__body, mesmo nível dentro do
     .tl-slide), com a margem esquerda automática fazendo o alinhamento à
     direita sem precisar de wrapper novo — display:flex (não
     inline-flex) é o que permite essa margem automática funcionar aqui,
     já que só caixas de bloco participam desse truque. */
  .tl-slide__cta{position:relative;z-index:2;display:flex;width:fit-content;margin:28px 24px 32px auto}
}
/* "Seção branca" — pedido explícito do usuário ("transforme a seção da
   linha do tempo... em uma seção branca"), mesma receita padrão de
   sempre (ver "Convenções gerais" no CLAUDE.md), aplicada via modificador
   próprio (`.tl-section--light`, mesmo padrão de `.ai-section--light`/
   `.erp-section--light`/`.pillars-section--light`) em vez de editar as
   regras base do componente. Os `.tl-slide` (cada década) **não**
   precisaram de nenhum ajuste — já são cards auto-contidos (imagem +
   degradê escuro + texto branco, mesma técnica de `.erp-card`/
   `.ramo-panel`), funcionam sobre qualquer fundo de seção. Só a "casca"
   fora dos slides (fundo da seção, título, trilho de abas) precisou de
   tema claro. */
.tl-section--light{position:relative;z-index:1;background:#e2e7f0}
.tl-section--light .section__title{color:#0b0f1a}
/* .tl-tabs usava um tom translúcido branco (pensado pro fundo escuro
   original) — quase invisível sobre #e2e7f0. `background-color`/
   `border-color` (não o shorthand `background`) de propósito: o
   shorthand resetaria `background-image` pra `none`, apagando o
   escurecimento leve nas pontas do trilho no mobile (`.tl-tabs{
   background-image:...}` dentro do media query logo acima) — aqui só
   trocamos a cor de base, sem mexer nesses dois gradientes extras. */
.tl-section--light .tl-tabs{background-color:rgba(11,15,26,.05);border-color:rgba(11,15,26,.1)}
/* `:not(.active)` evita empate de especificidade com `.tl-tab.active
   {color:#fff}` (mesma pegadinha já documentada em `.ai-section--light
   .ai-tab:not(.active)`) — a aba ativa já fica branca por cima do
   gradiente sólido do indicador, funciona igual em qualquer fundo de
   seção, não precisa de override. */
.tl-section--light .tl-tab:not(.active){color:var(--text-mute)}
.tl-section--light .tl-tab:not(.active):hover{color:#0b0f1a}
/* valores (página sobre) — lista editorial full-width, não grid de cards.
   Segunda versão: a primeira (grid 2x2 de caixas escuras arredondadas com
   numerozinho colorido) foi trocada a pedido do usuário por "parecer
   design genérico de IA". Motivo do redesenho: fugir da caixa-com-borda-
   arredondada-e-número-colorido (o padrão mais batido de landing page) e ir
   pra algo que não existe em nenhuma outra seção do site — numerais
   grandes "vazados" (só contorno, via -webkit-text-stroke, sem preenchimento)
   que só ganham cor (o gradiente --primary→--primary-2, mesma receita de
   outros destaques do site) no hover, junto com um leve deslocamento da
   linha inteira. Divisória horizontal simples entre itens, mesma
   linguagem das linhas entre marcos da linha do tempo (`.tl-mark`, ver
   seção própria) — reaproveita um padrão que já existe nesta mesma
   página em vez de inventar um terceiro estilo de borda. */
.values{display:flex;flex-direction:column}
.value{
  position:relative;
  display:grid;grid-template-columns:140px 1fr;align-items:center;gap:32px;
  padding:36px 4px;
  border-top:1px solid rgba(255,255,255,.08);
  transition:padding-left .4s var(--ease-out);
}
.value:first-child{border-top:none}
.value:hover{padding-left:16px}
.value__num{
  font-family:var(--font-display);font-weight:800;font-size:68px;line-height:1;letter-spacing:-.02em;
  color:transparent;-webkit-text-stroke:1.5px rgba(255,255,255,.16);
  transition:color .4s var(--ease-out);
}
.value:hover .value__num{
  -webkit-text-stroke:1.5px transparent;
  background:linear-gradient(135deg,var(--primary),var(--primary-2));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.value h4{font-size:21px;font-weight:700;color:#fff;margin-bottom:10px}
.value p{font-size:14.5px;color:var(--text-dim);line-height:1.7;max-width:620px}
@media (max-width:640px){
  .value{grid-template-columns:1fr;gap:12px}
  .value__num{font-size:44px}
}
