/* ==========================================================================
   E F Cunha Soft House — site styles V2 (development)
   --------------------------------------------------------------------------
   This file is a development-only copy of assets/css/site.css. It lives at
   dev/new-home/assets/css/site-v2.6d786f55.css and is served by tools-dev/serve-dev.mjs
   on port 8092. Do not promote to assets/css/site.css until the V2 release is
   approved and committed in the same atomic operation as the rest of V2.
   Last sync from assets/css/site.css: 2026-10-15 (baseline kept verbatim here).
   Brand palette extracted from Logo_E_F_Cunha_Startup.png /
   banner_EF_Cunha_Startup_v2.png
   ========================================================================== */

/* --- Fonts ---
   A tipografia do site e a sans-serif nativa da plataforma (system-ui):
   no Windows resolve Segoe UI, no macOS San Francisco, no Android Roboto.
   E a opcao mais moderna -- nenhuma webfont para baixar, nenhuma requisicao
   externa, nenhum cookie -- e o site inteiro (todas as paginas, PT e EN)
   herda a mesma pilha pelo token --font. */

/* --- Tokens --- */
:root {
  --navy: #052a66;
  --navy-deep: #03204f;
  --blue: #0b6bcb;
  --blue-strong: #0a5cb0;
  --cyan: #00aeef;
  --cyan-strong: #0693cd;

  --ink: #10233f;
  --muted: #4a5d7a;
  --line: #d8e4f5;
  --line-soft: #e8f0fb;
  --bg: #ffffff;
  --bg-alt: #f4f9ff;
  --bg-alt-2: #eaf3ff;

  --ok: #0b6b3a;
  --ok-bg: #e4f6ec;
  --beta: #8a4b00;
  --beta-bg: #fdf0dd;
  --dev: #4a5d7a;
  --dev-bg: #eef2f8;

  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;

  --shadow-sm: 0 1px 2px rgba(4, 32, 79, .06), 0 2px 8px rgba(4, 32, 79, .05);
  --shadow: 0 10px 30px rgba(4, 32, 79, .08), 0 2px 8px rgba(4, 32, 79, .05);

  --wrap: 1440px;
  --gutter: clamp(1rem, 4vw, 2.5rem);

  /* Tipografia padronizada (Figma)
     Entrelinhas por papel, alinhadas ao briefing de revisão tipográfica:
       13 / 14 / 16 px  -> 1.40 / 1.40 / 1.60
       22 px (h3)       -> 1.30
       32 px (h2)       -> 1.25
       48 px (h1 hero)  -> 1.18
     O corpo do texto herda 1.65 do `body` quando a 18px; o `p` a 16px usa
     --lh-16 (1.60) e antes valia 1.50 -- era essa diferença que apertava
     as linhas de texto corrido em todo o site. */
  --fs-12: .75rem;   --lh-12: 1.4;     /* 12 / 16,8 — legendas e badges */
  --fs-13: .8125rem; --lh-13: 1.4;     /* 13 / 18,2 — etiquetas */
  --fs-14: .875rem;  --lh-14: 1.4;     /* 14 / 19,6 — nav e legendas */
  --fs-16: 1rem;     --lh-16: 1.6;     /* 16 / 25,6 — parágrafos */
  --fs-22: 1.375rem; --lh-22: 1.3;     /* 22 / 28,6 — h3 */
  --fs-32: 2rem;     --lh-32: 1.25;    /* 32 / 40 — h2 seções */
  --fs-48: 3rem;     --lh-48: 1.18;    /* 48 / 56,6 — h1 hero */

  /* A medida do texto corrido. `em` e o proprio corpo do paragrafo, entao a
     linha sai com ~70 caracteres em qualquer corpo (16px -> 544px, 18px ->
     612px). O teto em `ch` nao dava conta disso: `ch` e a largura do "0", que
     e mais largo que a media da letra, e o mesmo 66ch rendia 70 caracteres a
     16px e 76 a 18px. Medido no navegador (tools-dev/medir_medida.py, com os
     retangulos de renderizacao): a faixa do briefing e 55-75. */
  --measure-corpo: 34em;

  --step--1: clamp(.82rem, .79rem + .16vw, .9rem);
  --step-0: clamp(1rem, .97rem + .16vw, 1.08rem);
  --step-1: clamp(1.12rem, 1.05rem + .35vw, 1.3rem);
  --step-2: clamp(1.3rem, 1.18rem + .6vw, 1.65rem);
  --step-3: clamp(1.55rem, 1.3rem + 1.1vw, 2.25rem);
  --step-4: clamp(1.9rem, 1.4rem + 2.1vw, 3.05rem);
  --step-5: clamp(2.2rem, 1.5rem + 3vw, 4rem);

  /* A medida do texto. O `ch` e a largura do caractere "0" da fonte: com a
     Inter o "0" mede 10,09px a 16px, contra 8,63px da Segoe UI. O mesmo
     valor em `ch` entregaria, portanto, linhas 17% mais largas do que as
     aprovadas. O fator 0.855 devolve a medida original em pixels --
     o corpo continua com ~70 caracteres por linha. */
  --fator-ch: .855;

  /* A Inter fica na frente; a pilha do sistema continua como reserva para
     quem não tem a fonte (e para o instante antes do download). */
  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

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

html {
  scroll-behavior: smooth;
  /* Matches the real sticky header: 88px on the desktop bar and about 117px where the
     Menu button stacks the actions onto a second line. */
  scroll-padding-top: 8rem;
  -webkit-text-size-adjust: 100%;
}
@media (min-width: 1310px) {
  html { scroll-padding-top: 6.5rem; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: 1.65;
  font-weight: 400;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; height: auto; }
img { display: block; }

h1, h2, h3, h4 {
  color: var(--navy);
  line-height: 1.15;
  margin: 0 0 .6em;
  font-weight: 600;
  letter-spacing: -.015em;
  text-wrap: balance;
}

h1 { font-size: var(--fs-48); line-height: var(--lh-48); font-weight: 700; letter-spacing: -.03em; }
h2 { font-size: var(--fs-32); line-height: var(--lh-32); font-weight: 700; letter-spacing: -.02em; }
h3 { font-size: var(--fs-22); line-height: var(--lh-22); font-weight: 600; }
h4 { font-size: var(--fs-16); line-height: var(--lh-16); font-weight: 600; }

/* A medida do texto: 66ch. O `ch` e a largura do caractere "0" da fonte e o
   fator 0.855 devolve a medida em pixels. Medido no navegador (tools-dev/
   medir_medida.py, retangulos de renderizacao, nao estimativa): com 72ch a
   linha mais cheia saia com 78-81 caracteres em EN, acima da faixa de 55-75 do
   briefing; com 66ch ela fica entre 67 e 72. O `p` e a regra do paragrafo
   ficam em um bloco so: antes `margin`/`max-width` estavam declarados duas
   vezes, e qualquer ajuste futuro precisava ser feito nas duas. */
p { font-size: var(--fs-16); line-height: var(--lh-16); margin: 0 0 1.1em; max-width: var(--measure-corpo); }
ul, ol { margin: 0 0 1.1em; padding-left: 1.25em; }
/* 12-16px entre itens de lista (briefing): .45em dava 7,2px a 16px e colava
   os itens uns nos outros. */
li { margin-bottom: .75em; }
li:last-child { margin-bottom: 0; }

a { color: var(--blue-strong); text-decoration-thickness: .08em; text-underline-offset: .18em; }
a:hover { color: var(--navy); }

strong { font-weight: 600; color: var(--navy); }

:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: #cfe6ff; color: var(--navy-deep); }

/* --- Layout helpers --- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(0.75rem, 1.5vw, 1rem);
}

.section { padding-block: clamp(3rem, 7vw, 6rem); }
.section--alt { background: var(--bg-alt); }
.section--tint { background: linear-gradient(180deg, var(--bg-alt-2), var(--bg-alt)); }
.section--tight { padding-block: clamp(2.25rem, 5vw, 3.5rem); }

.section-head { max-width: calc(72ch * var(--fator-ch, .855)); margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-head h2,
.section-head h3 { margin-bottom: .85em; }
/* `:not(.eyebrow)` é obrigatório aqui: esta regra vale (0,1,1) e `.eyebrow`
   vale (0,1,0), então o parágrafo de etiqueta era atingido pela regra do
   section-head. Efeito: a etiqueta saia a 16px em vez de 13px e perdia a
   margem de 12px, deixando o gap etiqueta->titulo em 0px (etiqueta colada no
   titulo). O `:not()` devolve a etiqueta ao token e mantem a folga de 12px. */
.section-head p:not(.eyebrow) { font-size: var(--fs-16); line-height: var(--lh-16); color: var(--muted); max-width: var(--measure-corpo); margin-bottom: 0; }

.eyebrow {
  display: block;
  font-size: var(--fs-13);
  line-height: var(--lh-13);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: .75rem;
}

.lede { font-size: var(--fs-16); line-height: var(--lh-16); color: var(--muted); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--navy);
  color: #fff;
  padding: .75rem 1.25rem;
  border-radius: 0 0 var(--radius-sm) 0;
  font-weight: 600;
}
.skip-link:focus { left: 0; color: #fff; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- Header --- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--line-soft);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 4.25rem;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: clamp(1rem, 2vw, 1.5rem);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  text-decoration: none;
  color: var(--navy);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -.01em;
  flex: 0 0 auto;
}
.brand:hover { color: var(--navy); }
/* The mark ships at 192x205 (ratio 0.9366). Declaring a width and letting the height
   follow keeps that ratio exact, where the previous 40x43 pair sat at 0.9302. */
.brand img { width: 60px; height: auto; }
.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-text small {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .22em;
  color: var(--blue);
  text-transform: uppercase;
}

.site-nav { margin-left: auto; margin-right: auto; }
.site-nav ul {
  display: flex;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
}
/* The global `li { margin-bottom: .45em }` also matched the navigation items and was
   adding 7.8px of dead space under the last one. */
.site-nav li { margin: 0; }
.site-nav a {
  display: inline-block;
  padding: .5rem .5rem;
  color: var(--ink);
  font-size: 15px;
  line-height: 1.4;
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  position: relative;
  transition: color .24s ease;
}
/* Underline animado via pseudo-element. Esconde por padrão (scaleX 0),
   aparece no hover, foco visível e estado atual. Cor = currentColor para
   acompanhar a cor do texto. */
.site-nav a::after {
  content: "";
  position: absolute;
  left: .5rem;
  right: .5rem;
  bottom: .25rem;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform .24s ease;
}
.site-nav a:hover,
.site-nav a:focus-visible { color: var(--navy); outline: none; }
.site-nav a:hover::after,
.site-nav a:focus-visible::after,
.site-nav a[aria-current]::after { transform: scaleX(1); }
.site-nav a[aria-current] { color: var(--blue-strong); }

/* --- Home link (visible "Início" — independent of the logo) ---
   O link é um pill igual aos outros itens de navegação, marcado com
   aria-current="page" quando o usuário está em /. Mantém o requisito de
   "retorno à Home" sem depender do clique no logotipo. No mobile, o link
   some do topo (vira primeiro item do drawer). */
.home-link {
  display: none; /* visível só no desktop (≥1100px) — ver @media abaixo */
  align-items: center;
  gap: .35rem;
  padding: .375rem .75rem;
  border-radius: 999px;
  color: var(--ink);
  font-size: var(--fs-14);
  line-height: var(--lh-14);
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  border: 1px solid transparent;
}
.home-link:hover { background: var(--bg-alt-2); color: var(--navy); }
.home-link[aria-current="page"] { color: var(--blue-strong); background: var(--bg-alt-2); }
.home-link svg { width: 1em; height: 1em; }

.header-actions { display: flex; align-items: center; gap: .5rem; flex: 0 0 auto; }

/* The language pill and the call to action sat at 29px and 48px next to each other,
   which is what made the action side of the header look unaligned. Both are locked to
   the same 44px box so the row reads as one group. */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  height: 2.75rem;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
}
.lang-switch::before {
  content: '';
  width: 1.05em;
  height: 1.05em;
  flex: 0 0 auto;
  background-color: var(--blue);
  -webkit-mask: no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3c2.5 2.7 3.8 5.7 3.8 9S14.5 18.3 12 21c-2.5-2.7-3.8-5.7-3.8-9S9.5 5.7 12 3Z'/%3E%3C/svg%3E");
  mask: no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3c2.5 2.7 3.8 5.7 3.8 9S14.5 18.3 12 21c-2.5-2.7-3.8-5.7-3.8-9S9.5 5.7 12 3Z'/%3E%3C/svg%3E");
}
.lang-switch a {
  display: inline-flex;
  align-items: center;
  height: 2.25rem;
  padding: 0 .75rem;
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-decoration: none;
  color: var(--muted);
}
.lang-switch a[aria-current='true'] { background: var(--navy); color: #fff; }

.header-cta { display: none; }
@media (min-width: 900px) { .header-cta { display: inline-flex; } }

/* Nav toggle (progressive: hidden until JS confirms it can open) */
.nav-toggle { display: none; }
.js .nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  /* Same 44px box as the language pill and the call to action, so the controls on the
     header row share one baseline and one height. */
  min-height: 2.75rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0 1rem;
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  color: var(--navy);
  cursor: pointer;
}

/* Below this width the whole row cannot hold the five priority links, the brand and the
   actions, so the existing Menu button takes over. The threshold is measured, not guessed:
   the row needs 1168px of content, which is 1248px of wrapper, and a desktop scrollbar
   costs another 15px of viewport. 1280px therefore leaves about 17px in hand. */

/* The .nav-lang-item only appears inside the drawer at very small widths — everywhere
   else the language pill in .header-actions is what the user sees. Hidden by default
   to keep the desktop nav tidy, and re-shown only at ≤359px (see inside the media
   query below). */
.site-nav .nav-lang-item { display: none; }

@media (max-width: 1309px) {
  /* Marca mais compacta: só o mark hexagonal + label curto (ou só o mark em
     320). O texto "E F CUNHA / Soft House" só aparece a partir do tablet. */
  .brand img { width: 30px; }
  .brand-text { display: none; }
  .site-nav {
    order: 4;
    flex: 1 0 100%;
    margin-left: 0;
    display: none;
    padding-bottom: 1rem;
  }
  .js .nav-open .site-nav { display: block; }
  .site-nav ul { flex-direction: column; gap: 0; }
  .site-nav a { display: block; padding: .7rem .5rem; border-radius: var(--radius-sm); }
  /* Em ≤359 px não há espaço para a marca + menu + lang na mesma linha.
     O lang switch vira item do drawer e o CTA some (já estava).
     A regra base .site-nav .nav-lang-item { display: none; } está fora do
     media query (acima). Aqui só reativamos e estilizamos o item em ≤359. */
  @media (max-width: 359px) {
    .header-actions .lang-switch { display: none !important; }
    .site-nav .nav-lang-item {
      display: flex;
      justify-content: center;
      padding: .35rem .5rem 0;
    }
    .site-nav .nav-lang-item .lang-switch {
      display: inline-flex;
      gap: .25rem;
    }
    .site-nav .nav-lang-item .lang-switch a {
      padding: 0 1rem;
      min-width: 2.75rem;
      justify-content: center;
    }
    .site-nav .nav-lang-item .lang-switch::before { display: none; }
  }
  /* No drawer mobile, cada disclosure vira um accordion do meio do menu. O
     botão continua visível (com chevron) e o painel aparece como bloco
     indentado quando aberto — sem card flutuante. Funciona para teclado,
     toque e leitor de tela. */
  .nav-dropdown,
  .nav-products,
  .nav-more { position: static; }
  /* O painel começa fechado no drawer mobile; só aparece quando o <li> pai
     recebe .is-open via JS. */
  .site-nav .nav-dropdown__panel,
  .site-nav .products-menu,
  .site-nav .nav-more__menu {
    display: none;
    position: static;
    flex-direction: column;
    gap: 0;
    border: 0;
    box-shadow: none;
    padding: 0 .25rem .25rem 1.6rem;
    background: none;
    min-width: 0;
    max-width: none;
    margin: 0;
    transform: none;
    opacity: 1;
  }
  .js .nav-dropdown.is-open .nav-dropdown__panel,
  .js .nav-products.is-open .products-menu,
  .js .nav-more.is-open .nav-more__menu { display: block; }
  /* No accordion mobile, o label "Demonstração" fica mais discreto ainda. */
  .site-nav .nav-dropdown__demo-label {
    padding: 0 .5rem .15rem;
    margin: 0 0 .25rem;
  }
  /* No mobile, sub-botões: removem a pílula, ficam como linhas de link
     simples, indentadas igual ao resto do drawer. */
  .site-nav .nav-dropdown__items a {
    background: none;
    color: var(--ink);
    box-shadow: none;
    border-radius: 8px;
    justify-content: flex-start;
    padding: .55rem .5rem;
    min-height: 0;
    transform: none;
  }
  .site-nav .nav-dropdown__items a:hover,
  .site-nav .nav-dropdown__items a:focus-visible {
    background: var(--bg-alt-2);
    color: var(--navy);
    transform: none;
    box-shadow: none;
  }
  /* Marca + texto dentro do subitem, no drawer, sem card flutuante */
  .site-nav .nav-dropdown__panel .pm-mark,
  .site-nav .products-menu .pm-mark,
  .site-nav .nav-more__menu .pm-mark { display: none; }
  .site-nav .nav-dropdown__panel a,
  .site-nav .products-menu a,
  .site-nav .nav-more__menu a {
    padding: .55rem .5rem;
    border-radius: 8px;
  }
  /* Botão do dropdown no drawer: largura total, justifica à esquerda, chevron à direita.
     Mantém a aparência de pílula e adiciona a rotação quando expandido. */
  .nav-dropdown__btn,
  .nav-products__btn,
  .nav-more__btn {
    width: 100%;
    justify-content: space-between;
    padding: .7rem .5rem;
    border-radius: var(--radius-sm);
    /* Sem o chrome padrão do <button> do navegador (borda outset cinza + fundo
       cinza). O desktop já zera isso; no drawer os botões ficavam com a cara
       de controle nativo. Agora o item do menu é só a linha + chevron. */
    background: transparent;
    border: 0;
  }
  /* No drawer, o dropdown "Serviços" vira uma linha com rótulo-link (navega)
     + setinha (expande o accordion). A linha precisa ser flex para a setinha
     ficar à direita do rótulo, e o painel desce para a linha de baixo. */
  .site-nav .nav-dropdown--split {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }
  .site-nav .nav-dropdown--split > .nav-dropdown__link { flex: 1 1 auto; }
  .site-nav .nav-dropdown--split > .nav-dropdown__btn--split {
    width: auto;
    flex: 0 0 auto;
    padding: .7rem .5rem;
  }
  .site-nav .nav-dropdown--split > .nav-dropdown__panel { flex: 1 0 100%; }
  /* Label no topo do submenu do drawer — para legados que usam data-label. Para
     os .nav-dropdown novos o label já está no próprio botão, então não precisa. */
  .site-nav .nav-products > .products-menu::before {
    content: attr(data-label);
    display: block;
    padding: .25rem .5rem .35rem 0;
    color: var(--muted);
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
  }
  /* At this width the brand, the Menu button and the actions cannot share one row
     (133 + 69 + 255 against 358px of space), so they are stacked on purpose:
     the Menu button stays on the brand's row, where it belongs, and the language
     and contact controls align to the right edge underneath it. 8px between rows. */
  .header-inner { flex-wrap: wrap; row-gap: .5rem; padding-block: .5rem; }
  /* Only one auto margin, so the Menu never floats in the middle when all three
     groups still fit on one row. */
  .nav-toggle { order: 2; }
  .header-actions { order: 3; margin-left: auto; }
  .no-js .site-nav { display: block; }
  /* Em mobile/tablet o "Início" some do topo e vira item do drawer, para
     liberar a primeira linha do header. */
  .home-link { display: none !important; }
  /* O link "Início" vira o primeiro item do drawer mobile, listado dentro de
     .site-nav > ul. */
  .nav-home { order: -1; }
  .nav-home a { font-weight: 600; }
  /* CTA "Fale conosco" some do header no mobile/tablet e vira o último item
     do drawer, com aparência de botão. */
  .header-cta { display: none !important; }
  .site-nav .nav-cta-item { margin-top: .65rem; padding-top: .65rem;
    border-top: 1px solid var(--line-soft); }
  .site-nav .nav-cta-item a {
    display: flex; align-items: center; justify-content: center;
    background: var(--blue); color: #fff; font-weight: 600;
    padding: .8rem 1rem; border-radius: 999px;
  }
  .site-nav .nav-cta-item a:hover { background: var(--navy); color: #fff; }
}

/* Above the breakpoint the full navigation is visible, so the Menu button is redundant. */
@media (min-width: 1310px) {
  .nav-toggle { display: none !important; }

  /* Brand, five priority links and the actions on one row. The wrapper widens past the
     1160px content column so the row closes, and it is sized for the worst case rather
     than the happy one: `font-display: optional` means a cold cache can settle on the
     metric-matched fallback, where the brand measures 159px instead of 139px. Against the
     1220px of content this leaves about 41px in hand in that case and 61px with the web
     font, which is what keeps the row on one line either way. */
  .header-inner {
    flex-wrap: nowrap;
    min-height: 0;
    max-width: 1440px;
    column-gap: 1rem;
    /* 44px of control + 40px of padding + the 1px rule is the 88px bar. */
    padding-block: 1.25rem;
    padding-inline: 0 7.2rem;
  }
  .brand { order: 1; }
  .home-link { order: 2; display: inline-flex; margin-left: .35rem; }
  .site-nav { order: 3; margin-left: auto; margin-right: auto; }
  .header-actions { order: 4; margin-left: auto; }
  .site-nav ul {
    justify-content: center;
    flex-wrap: nowrap;
    gap: 1.25rem;
  }
  .site-nav a { padding: .5rem .5rem; }
  /* Itens do drawer só aparecem no mobile/tablet (definidos em @media acima).
     .nav-home é visível no desktop como primeiro item do nav central — o
     briefing pede "Início | Sobre ▾ | Soluções ▾ | ..." e o link aproveita
     as regras globais .site-nav a (pílula + hover + aria-current). */
  .nav-cta-item { display: none; }

  /* The overflow disclosure: a button styled as a navigation link (matching
     the .site-nav a global rule) with an animated underline pseudo-element and
     a chevron that rotates when the panel is open. The button itself is NOT
     a filled pill — the only filled button in the header is the "Fale conosco"
     CTA on the right. Works for click, keyboard, touch. Hover is convenience. */
  .nav-dropdown,
  .nav-products,
  .nav-more { position: relative; }
  .nav-dropdown__btn,
  .nav-products__btn,
  .nav-more__btn {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .5rem .5rem;
    background: transparent;
    border: 0;
    border-radius: 0;
    font: inherit;
    font-size: 15px;
    line-height: 1.4;
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
    position: relative;
    transition: color .24s ease;
  }
  /* Underline animado (mesmo padrão do .site-nav a) — aparece no hover e
     quando o painel está aberto. */
  .nav-dropdown__btn::after,
  .nav-products__btn::after,
  .nav-more__btn::after {
    content: "";
    position: absolute;
    left: .5rem;
    right: .5rem;
    bottom: .25rem;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: center;
    transition: transform .24s ease;
  }
  .nav-dropdown__btn:hover,
  .nav-dropdown__btn:focus-visible,
  .nav-products__btn:hover,
  .nav-products__btn:focus-visible,
  .nav-more__btn:hover,
  .nav-more__btn:focus-visible { color: var(--navy); outline: none; }
  .nav-dropdown__btn:hover::after,
  .nav-dropdown__btn:focus-visible::after,
  .nav-products__btn:hover::after,
  .nav-products__btn:focus-visible::after,
  .nav-more__btn:hover::after,
  .nav-more__btn:focus-visible::after { transform: scaleX(1); }
  /* Estado aberto: cor azul forte + underline persistente (sem fundo). */
  .nav-dropdown__btn.is-current,
  .nav-dropdown__btn[aria-expanded='true'],
  .nav-products__btn.is-current,
  .nav-products__btn[aria-expanded='true'],
  .nav-more__btn.is-current,
  .nav-more__btn[aria-expanded='true'] { color: var(--blue-strong); }
  .nav-dropdown__btn.is-current::after,
  .nav-dropdown__btn[aria-expanded='true']::after,
  .nav-products__btn.is-current::after,
  .nav-products__btn[aria-expanded='true']::after,
  .nav-more__btn.is-current::after,
  .nav-more__btn[aria-expanded='true']::after { transform: scaleX(1); }
  /* A seta gira 180° quando o painel abre. Mesmo SVG nos botões legados. */
  .nav-dropdown__chev,
  .nav-dropdown__btn svg,
  .nav-products__btn svg,
  .nav-more__btn svg {
    width: 1em;
    height: 1em;
    color: var(--blue);
    /* Setas giram em 250ms ease-out, alinhadas com a abertura do painel.
       No fechamento (estado padrão) o transition herdado é 200ms ease-in
       — então a seta gira "devagar" ao abrir e "rápido" ao fechar, matching
       com a velocidade do painel. */
    transition: transform .25s ease-out;
  }
  .js .nav-dropdown.is-open .nav-dropdown__btn svg,
  .js .nav-products.is-open .nav-products__btn svg,
  .js .nav-more.is-open .nav-more__btn svg { transition: transform .2s ease-in; }
  .nav-dropdown__btn[aria-expanded='true'] .nav-dropdown__chev,
  .nav-dropdown__btn[aria-expanded='true'] svg,
  .nav-products__btn[aria-expanded='true'] svg,
  .nav-more__btn[aria-expanded='true'] svg { transform: rotate(180deg); }
  /* Dropdown "Serviços" com rótulo-link + setinha-disclosure -------------
     O rótulo é um link que vai direto para a página de Serviços (1 clique);
     a setinha abre o submenu com as frentes. Padrão "link + disclosure",
     usado para não obrigar dois cliques para chegar a uma página que é o
     destino principal do item. O rótulo herda as regras de .site-nav a
     (pílula, hover, aria-current). */
  .nav-dropdown--split { display: inline-flex; align-items: center; }
  .nav-dropdown--split > .nav-dropdown__link { margin-right: -.2rem; }
  .nav-dropdown--split > .nav-dropdown__btn--split {
    gap: 0;
    padding: .5rem .4rem .5rem .2rem;
  }
  /* A setinha não é um link: não recebe o underline animado do rótulo. */
  .nav-dropdown--split > .nav-dropdown__btn--split::after { display: none; }
  .nav-dropdown--split > .nav-dropdown__btn--split .nav-dropdown__chev { width: 13px; height: 13px; }
  /* Alvo de toque da setinha — WCAG 2.2 SC 2.5.8 (mínimo 24x24 CSS px).
     A caixa base mede 22,58x29 px: falta 1,42 px de largura. O padding
     extra entra pela DIREITA, onde não há nada desenhado — a seta fica no
     lado esquerdo da caixa e não se move. A margem negativa de -0.1rem no
     item compensa exatamente a largura extra, para que nenhum outro item do
     cabeçalho mude de posição (medido: dx = 0,00 px; render idêntico em
     1.296.000 pixels, salvo 58 px de antialiasing na borda de uma letra).
     O seletor precisa do prefixo .site-nav: `.site-nav li { margin: 0 }`
     tem especificidade maior e anularia a margem. Escopado no breakpoint do
     menu de uma linha, porque abaixo dele o menu vira drawer (coluna) e a
     margem negativa vazaria para fora do contêiner. */
  @media (min-width: 1310px) {
    .nav-dropdown--split > .nav-dropdown__btn--split { padding: .5rem .5rem .5rem .2rem; }
    .site-nav .nav-dropdown--split { margin-right: -0.1rem; }
  }
  /* Painel: extensão visual do cabeçalho. Sem border-top e sem border-radius
     no topo, fica "grudado" na borda inferior do header. A altura é animada
     com max-height (0 → 600px) e o padding interno também anima, dando o
     efeito de "crescer para baixo" sem flash. visibility/pointer-events
     controlam a interação durante a transição. */
  .site-nav .nav-dropdown__panel,
  .site-nav .products-menu,
  .site-nav .nav-more__menu {
    display: block;
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 60;
    min-width: 18rem;
    margin: 0;
    padding: 0 .75rem;
    list-style: none;
    background: #fff;
    border: 1px solid var(--line-soft);
    border-top: 0;
    border-radius: 0 0 16px 16px;
    box-shadow: 0 18px 48px rgba(4, 32, 79, .16);
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    visibility: hidden;
    transform: translateY(-4px);
    pointer-events: none;
    /* Estado padrão (fechado). Controla a animação de SAÍDA — quando o
       painel é removido de .is-open, ele volta a opacity 0, transform
       -4px, max-height 0 com 200ms ease-in. */
    transition: opacity .2s ease-in, transform .2s ease-in, max-height .2s ease-in, padding .2s ease-in, visibility 0s linear .2s;
  }
  /* Label "Demonstração" — texto pequeno em small caps, sem fundo, alinhado
     à esquerda. Identifica visualmente que o conteúdo é temporário para
     esta entrega (não vai pro dist). */
  .nav-dropdown__demo-label {
    display: block;
    margin: 0 0 .5rem;
    padding: 0 .25rem;
    color: var(--muted);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
  }
  /* Lista de sub-itens: estilizada. Quando preenchida com <li><a>…</a></li>,
     os itens aparecem como pills azul claro com hover preenchido. */
  .nav-dropdown__items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .35rem;
  }
  /* A lista ja tem `gap`: a margem global do `li` somaria uma segunda vez e
     abriria o painel do dropdown. O espaco visual vem do `gap` + do padding do
     link (0,5rem). */
  .nav-dropdown__items li { margin: 0; }
  /* Sub-item: link simples, alinhado à esquerda, mesma tipografia e cor
     do cabeçalho. Sem pill, sem bordas arredondadas. Hover discreto em
     azul-claro. */
  .nav-dropdown__items a {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: .5rem;
    padding: .5rem .5rem;
    background: transparent;
    color: var(--ink);
    border-radius: 0;
    font-size: 15px;
    line-height: 1.4;
    font-weight: 500;
    text-decoration: none;
    transition: background-color .24s ease, color .24s ease;
  }
  .nav-dropdown__items a:hover,
  .nav-dropdown__items a:focus-visible {
    background: var(--bg-alt-2);
    color: var(--navy);
    outline: none;
  }
  /* Quando aberto (JS adiciona .is-open no <li> pai): painel cresce,
     ganha opacity, volta para translateY(0) e fica visível. */
  .js .nav-dropdown.is-open .nav-dropdown__panel,
  .js .nav-products.is-open .products-menu,
  .js .nav-more.is-open .nav-more__menu {
    opacity: 1;
    max-height: 600px;
    padding: .75rem;
    visibility: visible;
    transform: translateY(0);
    pointer-events: auto;
    /* Estado .is-open. Controla a animação de ENTRADA — quando o painel
       ganha .is-open, ele anima para opacity 1, transform 0, max-height
       600px com 250ms ease-out. */
    transition: opacity .25s ease-out, transform .25s ease-out, max-height .25s ease-out, padding .25s ease-out, visibility 0s;
  }
  /* As regras legadas abaixo (.nav-dropdown__panel a, .products-menu a, etc)
     cobriam o markup antigo (sem <ul class="nav-dropdown__items">). O markup
     atual é .nav-dropdown__items a (pílula azul claro), então essas regras
     são dead-code — mantidas apenas .pm-mark e .pm-text caso o markup
     legado seja reintroduzido no futuro. */
  .nav-dropdown__panel .pm-mark,
  .products-menu .pm-mark,
  .nav-more__menu .pm-mark {
    width: 38px; height: 38px; flex: 0 0 auto;
    background: var(--bg-alt-2); color: var(--blue);
    border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: .82rem;
  }
  .nav-dropdown__panel .pm-text,
  .products-menu .pm-text,
  .nav-more__menu .pm-text {
    display: flex; flex-direction: column; line-height: 1.25; min-width: 0;
  }
  .nav-dropdown__panel .pm-text strong,
  .products-menu .pm-text strong { color: var(--navy); font-size: .92rem; font-weight: 600; }
  .nav-dropdown__panel .pm-text small,
  .products-menu .pm-text small { color: var(--muted); font-size: var(--fs-12); line-height: var(--lh-12); }
  /* prefers-reduced-motion: corta todas as transições/transforms dos componentes
     do dropdown, deixando apenas o toggle instantâneo de visibilidade. */
  @media (prefers-reduced-motion: reduce) {
    .nav-dropdown__panel,
    .products-menu,
    .nav-more__menu,
    .nav-dropdown__chev,
    .nav-dropdown__btn,
    .nav-dropdown__btn svg,
    .nav-products__btn svg,
    .nav-more__btn svg,
    .nav-dropdown__items a,
    .site-nav a,
    .site-nav a::after,
    .nav-dropdown__btn::after,
    .nav-products__btn::after,
    .nav-more__btn::after { transition: none !important; transform: none !important; }
    .js .nav-dropdown.is-open .nav-dropdown__panel,
    .js .nav-products.is-open .products-menu,
    .js .nav-more.is-open .nav-more__menu { transform: none !important; }
  }
}

/* --- Controls: a fonte do site em todo botão e campo --- */
/* O browser não dá ao <button>, <input>, <select> e <textarea> a fonte do
   documento: eles caem na fonte de UI do sistema (Arial no Windows). Esta
   regra centraliza a família em todo o site — o tamanho e o peso continuam
   sendo definidos por cada componente (.btn, .cp-form input, .copy-btn). */
button,
input,
select,
textarea {
  font-family: var(--font);
}

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 2.75rem;
  padding: .8rem 1.4rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: var(--fs-16);
  line-height: 1.25;
  text-decoration: none;
  border: 2px solid transparent;
  transition: transform .16s ease, box-shadow .16s ease, background-color .16s ease, color .16s ease;
  cursor: pointer;
}
.btn--primary { background: var(--blue); color: #fff; box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--navy); color: #fff; transform: translateY(-1px); }
.btn--ghost { background: #fff; color: var(--navy); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--blue); color: var(--blue-strong); background: #fff; }
.btn--sm { padding: .55rem 1rem; font-size: var(--fs-14); }

.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.75rem; }

/* --- Hero --- */
.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(1100px 520px at 88% -12%, #dceeff 0%, rgba(220, 238, 255, 0) 68%),
    linear-gradient(180deg, #ffffff 0%, #f5faff 100%);
  border-bottom: 1px solid var(--line-soft);
}
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(11, 107, 203, .16) 1.2px, transparent 1.2px);
  background-size: 26px 26px;
  mask-image: linear-gradient(115deg, transparent 42%, #000 100%);
  pointer-events: none;
}
.hero .wrap { position: relative; z-index: 1; padding-inline: clamp(0.75rem, 1.5vw, 1rem); }
@media (min-width: 980px) {
  /* No desktop a hero usa o wrap cheio (padding 0) para a brand e o texto encostarem
     na borda esquerda; no mobile/tablet mantemos o gutter para evitar texto colado. */
  .hero .wrap { padding-inline: 0; }
}

.hero-grid {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center;
  padding-block: clamp(2.5rem, 6vw, 5.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 980px) {
  .hero-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); }
}

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .35rem .85rem;
  font-size: var(--fs-12);
  line-height: var(--lh-12);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--blue-strong);
  margin-bottom: 1.25rem;
}
.hero-badge::before {
  content: '';
  width: .5rem; height: .5rem;
  border-radius: 50%;
  background: var(--cyan);
}

.hero h1 { margin-bottom: .75rem; }
.hero h1 .accent { color: var(--blue-strong); display: block; margin-top: .45rem; }
.hero h1 .accent-2 { color: var(--cyan-strong); }

.hero .lede { max-width: calc(56ch * var(--fator-ch, .855)); }
.hero .lede strong { color: var(--navy); }

/* The hero is the only block above the fold, so its height is pinned for the two
   narrowest-and-therefore-tallest cases: two lines of headline and three lines of
   lead text, matching what Poppins produces. Reserving the height up front means a
   font substitution can never move the image below it. */
@media (max-width: 979px) {
  .hero h1 { min-height: 2.3em; }
  .hero .lede { min-height: 6.6em; }
}

/* Em mobile/tablet a H1 padronizada em 48px estoura a viewport (<400px). Reduzimos
   progressivamente até 32px no menor breakpoint, mantendo a mesma família/peso. */
@media (max-width: 600px) {
  .hero h1 { font-size: 2.25rem; line-height: 1.18; }
}
@media (max-width: 400px) {
  .hero h1 { font-size: var(--fs-32); line-height: var(--lh-32); }
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.5rem;
  margin-top: 1.5rem;
  padding: 0;
  list-style: none;
  font-size: .9rem;
  color: var(--muted);
  /* Measured height including the extra line the longest item takes while the
     metric-matched fallback is the active font. Reserving it means the image below
     never moves, whichever font the browser ends up using. */
  min-height: 9.7rem;
}
.hero-meta li {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: 0;
  /* One line per item so the hero height does not depend on the font. Only from the
     width where the longest item provably fits: below that the text would be clipped
     when the metric-matched fallback is the active font. */
  max-width: 100%;
}
@media (min-width: 1060px) {
  /* Wide enough that every item fits on one line with either font, so the list is
     shorter and the height is fixed at the measured value. */
  .hero-meta { min-height: 5.6rem; }
  .hero-meta li { white-space: nowrap; }
}
.hero-meta svg { width: 1.05em; height: 1.05em; flex: 0 0 auto; color: var(--blue); }

/* --- Hero, composition B (approved) -------------------------------------
   The text column gives up width so the product capture can be shown closer to
   its real size: 486px before, 584px here, against the 662px the file actually
   is. The whole section drops from about 906px to 705px, which is what lets the
   headline, the paragraph, the buttons and the capture share one screen under
   the 88px sticky header.

   Revisão 2026-10-15: o wrap subiu para 1280px e a composição foi rebalanceada
   para 1.05fr/.95fr (texto um pouco maior que a imagem). O título subiu de 15ch
   para 18ch (cabe em 2 linhas em vez de 3) e o lede de 44ch para 52ch. A
   proporção ainda dá à captura 562px a 1440px, suficiente para mostrar o painel
   sem distorcer; o texto ganha 96px a mais (de 480 para 576) para acomodar
   títulos longos sem quebra desnecessária.

   Everything here is desktop-only and sits after the rules above, so at 980px
   and below the hero keeps the single-column layout and metrics it already had.
   Text, colours, image and button labels are untouched: this block only moves
   boxes and adjusts size and spacing. */
@media (min-width: 980px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    gap: clamp(2rem, 4vw, 3.5rem);
    padding-block: clamp(2.5rem, 5vw, 4.5rem);
    align-items: center;
  }
  .hero h1 {
    font-size: var(--fs-48);
    line-height: var(--lh-48);
    max-width: none;
    margin-bottom: 1rem;
  }
  .hero .lede { max-width: var(--measure-corpo); font-size: var(--fs-16); line-height: var(--lh-16); }
  .hero .btn-row { margin-top: 1.75rem; }
  /* The eyebrow needs about 397px and the text column is now ~576px. Easing the
     tracking keeps the same words and the same colour on one line instead of
     breaking mid-phrase. */
  .hero-badge {
    letter-spacing: .04em;
    padding: .35rem .7rem;
    margin-bottom: 1.25rem;
  }
  @media (min-width: 1080px) {
    .hero-badge { white-space: nowrap; }
  }
  /* The one-line-per-item rule above exists so the hero height does not depend on
     which font loads. In the wider text column (576px vs 440px) the items fit on
     one line again from about 1180px, so we restore the no-wrap rule there. */
  .hero-meta { gap: .5rem 1.25rem; min-height: 5rem; }
  .hero-meta li { white-space: normal; }
  @media (min-width: 1180px) {
    .hero-meta li { white-space: nowrap; }
  }
  .hero-visual img { width: 100%; }
}

.hero-visual { position: relative; }
.hero-visual img {
  width: 100%;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid var(--line);
}

/* --- Moldura de laptop no hero (aproxima a imagem de referência) ---
   A moldura é feita com padding + background no container e a base do
   notebook é desenhada com ::before (um trapézio cinza claro). A imagem
   recebe border-radius e overflow:hidden para preencher a tela do laptop.
   Tudo é puramente CSS para que a imagem responsiva e o WebP continuem
   funcionando sem pipeline de SVG.

   O padding-bottom reserva espaço para a base e para a sombra da base
   DENTRO do container: o hero tem overflow:hidden para o gradient
   decorativo de pontos, então qualquer ::before posicionado com bottom
   negativo seria cortado pela máscara. */
.hero-visual--shot {
  position: relative;
  padding: 14px 14px 24px;
  background: #1f2937;
  border-radius: 18px 18px 4px 4px;
  border: 4px solid var(--navy);
  box-shadow: 0 30px 60px rgba(4, 32, 79, .14), 0 6px 18px rgba(4, 32, 79, .08);
  overflow: visible;
  justify-self: end;
  max-width: 100%;
  width: 100%;
  transform: translateX(120px) scale(1.18);
  transform-origin: right center;
}
/* Em telas ≥1700px a moldura cresce tanto com scale(1.18)+translateX(120) que vaza
   além da borda direita do .hero (overflow:hidden corta). Reduzimos os dois valores
   proporcionalmente para que ela continue grande mas respeite a grid. */
@media (min-width: 1700px) {
  .hero-visual--shot {
    transform: translateX(80px) scale(1.12);
  }
}
/* No mobile o transform translateX(120) scale(1.18) faz a moldura vazar para fora do
   viewport (375px). Resetamos o transform para ela respeitar a grid natural. Esta
   regra fica DEPOIS da regra base e do media query de 1700px para vencer por ordem
   de declaração em mobile/tablet. */
@media (max-width: 979px) {
  .hero-visual--shot {
    transform: none;
  }
}
.hero-visual--shot img {
  display: block;
  border-radius: 6px;
  border: none;
  box-shadow: none;
  width: 100%;
  max-width: 100%;
}
.hero-visual--shot::before {
  /* Base do notebook — trapézio cinza claro abaixo da tela. */
  content: '';
  position: absolute;
  left: -4%;
  right: -4%;
  bottom: 4px;
  height: 14px;
  background: linear-gradient(180deg, #e5e7eb 0%, #cbd5e1 100%);
  border-radius: 0 0 12px 12px;
  box-shadow: 0 6px 20px rgba(4, 32, 79, .12);
  clip-path: polygon(2% 0, 98% 0, 100% 100%, 0 100%);
}
.hero-visual--shot::after {
  /* Pequeno entalhe central na base — touchpad do notebook. */
  content: '';
  position: absolute;
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  width: 60px;
  height: 4px;
  background: rgba(15, 23, 42, .18);
  border-radius: 4px;
}
.caption {
  margin: .75rem 0 0;
  font-size: var(--fs-13);
  line-height: var(--lh-13);
  color: var(--muted);
  /* Block, with the icon as a wrapping inline box: the text wraps as one flow, so a
     font swap cannot change whether the icon sits beside the text or above it.
     The caption also uses the metric-matched stack, so its own line count is stable. */
  font-family: var(--font);
  display: block;
}
.caption svg {
  width: 1em;
  height: 1em;
  color: var(--blue);
  vertical-align: -.15em;
  margin-right: .3em;
  display: inline;
}
/* Keeps the caption at the same height before and after the web font loads, which
   removes the last layout shift. Browsers without :has() simply ignore the rule. */
.caption:has(.caption-break) { min-height: 2.4em; }

/* --- Cards / grids --- */
.grid { display: grid; gap: clamp(1.25rem, 2.4vw, 2rem); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }

/* --- CloudPilot: capabilities stay in three columns (revised 2026-10-15) ---
   Sem esta regra, o auto-fit de .grid--3 (minmax 17rem) cai para 4 colunas
   em wrap=1280px, ficando com cards de ~276px e quebras de título. A regra
   escopada mantém 3 colunas explícitas no desktop, deixando os cards em
   ~395px (largura confortável para h3 + p) e 2 fileiras para os 6 cards. */
@media (min-width: 980px) {
  #capacidades .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* --- Maturity block: explanation above, table at full width (approved) ---
   The block used to be two columns, 432px beside 622px. The table has three columns
   and only ever used 58% of the container, so its longest description column was
   243px wide and every row grew to about 131px; the callout beside it left roughly
   1986px of empty column. Stacked, the table takes the full 1080px and rows settle
   around 82px, with the explanation reading as a band above it instead.

   Scoped to the classes, not to #produto or #product, so the English page gets the
   same result. The callout is addressed as a child of this grid because a second
   .callout--light exists in the trust section and must not be touched.

   Desktop only: at 980px and below the block already stacks, and the table keeps
   the horizontal scroll it has always had inside .table-wrap. */
@media (min-width: 980px) {
  .grid.grid--2.grid--wide-right {
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
  }
  /* The band spans the row; the prose keeps a comfortable measure instead of
     stretching across the whole container. */
  .grid--wide-right > .callout--light p { max-width: var(--measure-corpo); }
  /* The legend already belongs to the block above the table, so it carries no
     trailing margin here. */
  .grid--wide-right .badge-legend { margin-bottom: 0; }
}

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 2.4vw, 2rem);
  box-shadow: var(--shadow-sm);
  height: 100%;
  display: flex;
  flex-direction: column;
}
.card h3 { font-size: var(--step-1); margin-bottom: .5rem; }
.card p { margin-bottom: 0; color: var(--muted); font-size: var(--fs-16); line-height: var(--lh-16); }
.card > :last-child { margin-bottom: 0; }

.card--plain { box-shadow: none; background: transparent; border-color: var(--line-soft); }

.card-head {
  /* The badge used to sit beside the title in a row, which left the title about
     half the card's inner width (161px inside a 343px card) and broke it over
     three lines while the paragraph below used the full 290px. Stacking them gives
     the title the whole column and keeps the maturity label next to the text it
     qualifies. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .5rem;
  margin-bottom: .6rem;
}
.card-head h3 { margin: 0; }

.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 12px;
  background: var(--bg-alt-2);
  color: var(--blue);
  flex: 0 0 auto;
  margin-bottom: .85rem;
}
.icon-badge svg { width: 1.35rem; height: 1.35rem; }

/* --- CloudPilot: four challenge cards in four columns (revised 2026-10-15) ---
   A antiga grade de 2 colunas deixava 106px de ar à direita do segundo card em
   1160px e as colunas ficavam em 527px: título curto + parágrafo curto
   deixavam metade do card vazia. Com 1280px de wrap e 4 colunas, cada card
   passa a ~292px e os quatro fecham a linha sem buracos. O seletor é escopado
   em #desafio para não tocar Controle e Cobertura (que também usam .grid--2
   mas têm layouts diferentes: Controle é mockup + pills, Cobertura é 2 cards
   mais altos com parágrafos longos). O ajuste é desktop-only; abaixo de
   900px o auto-fit já empilha corretamente. */
@media (min-width: 900px) {
  #desafio .grid--2 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.25rem; }
}
@media (min-width: 1180px) {
  #desafio .grid--2 { gap: 1.5rem; }
}

/* --- Trust and security: six measures in two columns (approved) ---
   The section kept a 343px text column, which measured 20.3 characters per line
   in the two cards that carry a <code> and 17.4 at 1024px. The <code> was part
   of the cause: FORCE ROW LEVEL SECURITY took 285px of a 293px column and broke
   onto two lines, pushing that paragraph to twelve lines while its neighbours
   sat at four. Equalised card heights then left 311px of empty space across the
   six. Two columns take the text to 478px and the average to 38.9 characters per
   line; 105px of internal slack remain, which is about 17px per card and buys
   the aligned grid the section relies on.

   Scoped on :has(> .card--plain) because .grid--3 and .callout--light are both
   shared with the product section, and .section-head repeats in every section.
   The product grid uses plain .card, and its callout sits inside a .grid--2, so
   neither the grid nor the sibling callout selector can reach it. No section id
   appears here, so the same rules drive the PT and EN builds. */
@media (min-width: 900px) {
  .grid--3:has(> .card--plain) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
}
/* The chips keep the design system's .88em; only the break is prevented, so no
   text is cut and nothing has to be shrunk to fit. */
.grid--3:has(> .card--plain) > .card--plain code { white-space: nowrap; }

/* The h2 only reaches two lines across the full container: measured, 673px and
   896px both wrap to three, and only the unconstrained 1080px fits two. The
   introduction keeps its own 72ch measure instead of stretching with the title
   (revised 2026-10-15: was 62ch, widened with --wrap so the lede no longer
   reads as a thin column on the right of a 1080px title).

   The anchor is written as a single :has() on purpose. Chrome rejects a :has()
   nested inside another :has() outright — the whole rule is discarded without a
   warning — so :has(~ .grid--3 > .card--plain) is the deepest form that works.
   It still matches exactly one element: the product grid uses plain .card, and
   its grid--3 therefore fails the child test. The h2 needs no rule of its own,
   it has no max-width; it is the section head that was capping it. */
.section-head:has(~ .grid--3 > .card--plain) { max-width: none; }
.section-head:has(~ .grid--3 > .card--plain) p { max-width: var(--measure-corpo); }

/* The callout heading was running 990px on one line above a 673px paragraph.
   Capping it at 46ch keeps the block balanced without moving any content, and
   the paragraph keeps the 62ch it already had. */
.grid--3:has(> .card--plain) ~ .callout--light h3 { max-width: calc(46ch * var(--fator-ch, .855)); }

/* --- Company section: full-width facts, asymmetric content (approved) ---
   The facts list shared a 527px column with the founder card and the stack, and
   the stack's auto-fit put six items in two 256px columns: 23.3 characters per
   line at 1440px but 46.5 at 1024px, where the same component collapses to one
   column. The section read better on the smaller screen.

   The list now spans the container above a two-column row holding the founder
   card and the stack, the stack runs in one column, and the heading takes the
   full measure so it fits on two lines.

   Scoped through :has(.facts) / :has(.stack-grid). .facts, .stack-grid and
   .banner-band each appear once in the document, and .grid--2 and .card are
   shared with the product and AWS sections, so the bare class names are not safe
   on their own. No section id appears here, so PT and EN share these rules. */
.section:has(> .wrap > .facts) .section-head { max-width: none; }
.section:has(> .wrap > .facts) .section-head h2 { max-width: none; }
.section:has(> .wrap > .facts) .section-head p { max-width: var(--measure-corpo); }

/* the eleven registry rows read as a two-column spec sheet on the desktop and
   as one column below 1000px, where two columns would squeeze each label */
/* same 420px floor the published list uses before stacking dt over dd */
@media (min-width: 420px) {
  .section:has(> .wrap > .facts) .facts > div { grid-template-columns: minmax(8rem, 38%) 1fr; }
}

@media (min-width: 1000px) {
  .section:has(> .wrap > .facts) .facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 3.5rem;
  }
  /* one column: the labels sit above their text instead of competing with them
     for 256px. Without this the paragraphs stay at 23.3 characters per line. */
  .section:has(.stack-grid) .stack-grid { grid-template-columns: minmax(0, 1fr); }
  /* height:100% comes from the design system and would stretch the 335px card to
     the height of the stack, which is the 220px of empty space we do not want */
  .section:has(.stack-grid) > .wrap > .grid--2 > .card { height: auto; }
}

/* The item headings were meant to be 1rem: the rule below pointed at .stack-grid
   h3 while the markup uses h4, so it never matched and the six items inherited
   the section h3 at 20.8px. Same value, now on the element that is really there. */
.stack-grid h4 { font-size: 1rem; margin-bottom: .35rem; }

/* --- Maturity badges --- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .2rem .55rem;
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  flex: 0 0 auto;
  border: 1px solid transparent;
}
.badge::before {
  content: '';
  width: .42rem;
  height: .42rem;
  border-radius: 50%;
  background: currentColor;
}
.badge--available { color: var(--ok); background: var(--ok-bg); border-color: #bfe6cf; }
.badge--beta { color: var(--beta); background: var(--beta-bg); border-color: #f0d5a8; }
.badge--dev { color: var(--dev); background: var(--dev-bg); border-color: #d5dded; }

.badge-legend {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1.5rem;
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
  padding: 1rem 1.25rem;
  list-style: none;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: #fff;
  font-size: .88rem;
  color: var(--muted);
}
.badge-legend li { display: flex; align-items: flex-start; gap: .55rem; margin: 0; }
.badge-legend .badge { margin-top: .12rem; }

/* --- Problem section --- */
.problem-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem; }
.problem-list li {
  display: flex;
  gap: .85rem;
  align-items: flex-start;
  background: #fff;
  border: 1px solid var(--line);
  border-left: 4px solid var(--cyan);
  border-radius: var(--radius-sm);
  padding: 1rem 1.15rem;
  margin: 0;
}
.problem-list svg { color: var(--blue); flex: 0 0 auto; width: 1.3rem; height: 1.3rem; margin-top: .15rem; }
.problem-list p { margin: 0; font-size: var(--fs-16); line-height: var(--lh-16); }
.problem-list h3 { font-size: var(--step-0); margin-bottom: .3rem; }

/* --- "Why it matters" blocks (approved) ---
   Each item is a full-width 1080px box, but the paragraph inside it is capped by the
   62ch measure on p, so about 598px of text sat in a 1080px row: 425px empty on the
   right of every one of the four blocks. Two columns make the box and the text the same
   width, and the empty space falls from 425px to under 30px.

   Everything is selected by classes that already exist in the markup, so the English
   page behaves identically and the section keeps no dependency on any other one. The
   heading is reached through :has(~ .problem-list) because .section-head repeats in
   every section, and the callout through the ~ sibling because .callout also appears
   in the product and trust sections. */
@media (min-width: 980px) {
  .problem-list { gap: 1.25rem; }
  .problem-list li { padding: 1.5rem 1.75rem; gap: 1rem; }
  .section-head:has(~ .problem-list) { margin-bottom: 2.5rem; }
  .problem-list ~ .callout { margin-top: 2.5rem; padding: 3rem; }
  .problem-list ~ .callout p:not(.eyebrow) { max-width: var(--measure-corpo); }
}
@media (min-width: 1200px) {
  /* Two columns only from 1200px. Below that the cards fall to about 450px and the
     text drops to 34-41 characters per line, which is too narrow to read; a single
     column there keeps the original 52-68. */
  .section-head:has(~ .problem-list) { max-width: calc(72ch * var(--fator-ch, .855)); margin-bottom: 2.75rem; }
  .problem-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
  /* The measure is the card width now, so the 62ch cap has to come off. */
  .problem-list li p { max-width: none; }
}

.callout {
  background: linear-gradient(135deg, var(--navy) 0%, #0a4a9e 55%, var(--blue) 100%);
  color: #eaf3ff;
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}
.callout h3, .callout h2 { color: #fff; }
/* Light enough to clear AA against the lightest stop of the callout gradient. */
.callout p { color: #e3eeff; }
.callout p:last-child { margin-bottom: 0; }
.callout strong { color: #fff; }
/* The dark callout gradient ends near the brand blue, so its accent text has to be
   light enough to clear 4.5:1 against #0B6BCB as well as against the navy. */
.callout .eyebrow { color: #e8f1ff; }
.callout--light {
  background: #fff;
  border: 1px solid var(--line);
  color: var(--ink);
}
.callout--light h3 { color: var(--navy); }
.callout--light p { color: var(--muted); }
.callout--light .eyebrow { color: var(--blue-strong); }
.callout--light strong { color: var(--navy); }
.callout--light code { color: var(--navy); }
/* Badges and flags inside the dark AWS band need inverted text, not the light-theme colours. */
.aws-band .eyebrow, .aws-band .confirm-flag { color: #cfe6ff; border-color: rgba(207, 230, 255, .55); }

/* --- How it works flow ---
   The five steps used to share the whole container in five columns, which left
   169px of text per card: 15.9 to 20.1 characters per line, the narrowest
   measure anywhere in the site, and worse at 1024px (139px / 14.3 characters)
   because the five-column rule held all the way down to 900px. equalised heights
   added 203px of dead space under the shorter cards. The steps are now a single
   vertical rail, which restores a readable measure and lets the other half of
   the container carry the product captures instead of empty space.

   The step markup has three direct children (number, h3, p), so the number is
   taken out of flow with absolute positioning rather than a two-column grid —
   auto-placement would drop the paragraph into the 44px number column. */
.flow {
  list-style: none;
  padding: 0;
  margin: 0;
  display: block;
  position: relative;
  counter-reset: step;
}
.flow::before {
  content: '';
  position: absolute;
  left: 1.375rem;
  top: 1.4rem;
  bottom: 1.4rem;
  width: 2px;
  background: var(--line);
}
.flow li {
  position: relative;
  padding: 0 0 1.75rem 4rem;
  margin: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.flow li:last-child { padding-bottom: 0; }
.flow .step-n {
  position: absolute;
  left: 0;
  top: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  font-size: .95rem;
  font-weight: 600;
  margin-bottom: 0;
}
.flow h3 { font-size: var(--step-0); margin-bottom: .3rem; }
.flow p { font-size: .88rem; color: var(--muted); margin: 0; }
/* The connector used to join the cards horizontally; the rail replaces it. */
.flow li::after { display: none; }
.flow-note {
  margin-top: 2rem;
  font-size: .88rem;
  color: var(--muted);
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}

/* --- How it works: steps beside the product captures (approved) ---
   Scoped on purpose. The section id differs between builds (#como in PT, #how in
   EN) and .grid--2 is shared with three other sections, so the split is anchored
   on its own wrapper rather than on either. Below 1000px it stays a single
   column, which also preserves the reading order: title, steps, note, captures.

   Revisão 2026-10-15: o wrap subiu para 1280px. A antiga proporção 380-600
   deixava 80px de ar à direita das capturas e a coluna de steps apertada (432px
   no wrap de 1160). A nova proporção 1.1fr/1fr (steps > shots) dá à coluna de
   texto ~616px e aos mockups ~552px, fechando a linha sem vazios e mantendo
   os dois screenshots dentro do srcset 760w. */
.split { display: block; }
.shots {
  display: grid;
  gap: 2rem;
  margin-top: 2.5rem;
}
@media (min-width: 1000px) {
  .split {
    display: grid;
    /* The 380px floor keeps the step text at roughly 36 characters per line or
       better even at 1024px. The capture column takes the remainder. The 1.1fr/1fr
       split gives the steps the wider column and the captures up to ~580px (cap
       interno), which stays inside the 760w asset the srcset serves at this width. */
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    column-gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
  }
  .shots { margin-top: 0; max-width: 580px; justify-self: end; width: 100%; }
}
/* Sticky is opt-in, gated on the measured arithmetic rather than on taste.
   The step column grows with the wider wrap: at 1280px it is ~616px wide and
   ~830px tall with the four steps and the note. A sticky box taller than the
   viewport pins its own top edge and strands its bottom below the fold, so
   sticky only turns on when the available height clears the 88px sticky header
   plus the column. 5.5rem matches the header's tallest single-row height. */
@media (min-width: 1280px) and (min-height: 900px) {
  .split__steps { position: sticky; top: 5.5rem; }
}

/* The captures were raw rectangles sitting 200px below cards that all carry a
   border, a 14px radius and a soft shadow. They now share that surface. */
.shots figure {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: .5rem;
  /* The figure has to claim the full .shots width; without width:100% it sizes
     to the image inside it and leaves an ~80px gutter on the right. */
  width: 100%;
}
.shots figure img { width: 100%; height: auto; }
.shots .caption { padding: 0 .35rem; }

/* --- Data / table --- */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: #fff; max-width: 100%; }
table { border-collapse: collapse; width: 100%; min-width: 32rem; font-size: var(--fs-14); line-height: var(--lh-14); }
caption { text-align: left; padding: .9rem 1rem 0; font-size: .85rem; color: var(--muted); }
/* 16px cell padding on the 8px scale: the maturity table carries 17 rows, and at
   12.8px the lines read as a dense block. */
th, td { text-align: left; padding: 1rem; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
thead th { background: var(--bg-alt); color: var(--navy); font-weight: 600; font-size: .85rem; letter-spacing: .03em; text-transform: uppercase; }
tbody tr:last-child td { border-bottom: 0; }
td code, th code, p code, li code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .88em;
  background: var(--bg-alt-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: .08em .38em;
  color: var(--navy);
  word-break: break-word;
}

/* --- CloudPilot: five security measures, asymmetric columns (revised 2026-10-15) ---
   Revisão do bloco #controle após --wrap=1280px. A grade anterior (auto-fit
   22rem) deixava o mockup em 447px e a pill-list em 527px dentro do wrap de
   1160px, com 80px de ar à direita da lista. A nova proporção 0.92fr/1.08fr
   dá ao mockup ~530px e à lista ~620px, fechando a linha e dando à lista
   espaço para as 6 pills em até 3 linhas equilibradas.

   Só desktop: abaixo de 980px o layout já empilha normalmente. O seletor
   escopa por #controle para não tocar .grid--2 de outras seções. */
@media (min-width: 980px) {
  #controle .grid--2 {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    gap: clamp(1.5rem, 3vw, 2.5rem);
    align-items: center;
  }
  /* A pill-list passa a ocupar a coluna maior; o mockup mantém a proporção do
     asset 1000x720 (ratio 1.39) e fica centralizado na sua coluna. */
  #controle .grid--2 > figure.shots__inline { max-width: 100%; }
  #controle .grid--2 > div:last-child { padding-left: clamp(0.5rem, 1.5vw, 1.25rem); }
}

/* --- Trust / security --- */
.pill-list {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  padding: 0;
  margin: 0;
  list-style: none;
}
.pill-list li {
  margin: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .35rem .8rem;
  font-size: .85rem;
  font-weight: 500;
  color: var(--navy);
}

.stack-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.stack-grid h3 { font-size: 1rem; margin-bottom: .35rem; }
.stack-grid p { font-size: .9rem; color: var(--muted); margin: 0; }

/* --- CloudPilot: coverage cards equal columns (revised 2026-10-15) ---
   Revisão do bloco #cobertura após --wrap=1280px. A grade anterior (auto-fit
   22rem) deixava cada card em 527px dentro do wrap de 1160px, com 106px de ar
   à direita do segundo card. Os cards têm h3 curto + p longo, então a
   proporção 1fr/1fr fecha a linha e dá paridade visual entre as duas caixas.
   O gap aumenta um pouco para deixar cada card respirar mais dentro do wrap
   maior. Só desktop: abaixo de 980px o layout já empilha. */
@media (min-width: 980px) {
  #cobertura .grid--2 {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 3vw, 2.5rem);
  }
}

/* --- AWS band --- */
.aws-band {
  background: linear-gradient(180deg, var(--navy-deep) 0%, #06306f 100%);
  color: #e6efff;
}
.aws-band h2, .aws-band h3 { color: #fff; }
.aws-band p { color: #cfe1ff; }
.aws-band a { color: #9fd0ff; }
.aws-band a:hover { color: #fff; }
.aws-band .eyebrow { color: #8fc4ff; }
.aws-band .card {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .18);
  box-shadow: none;
  color: #e6efff;
}
.aws-band .card h3 { color: #fff; }
.aws-band .card p { color: #dbe8fc; }
.aws-band .card strong { color: #fff; }
.aws-band .card li { color: #dbe8fc; }
.aws-band .pill-list li {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .2);
  color: #eaf3ff;
}
.aws-band .table-wrap { background: rgba(255, 255, 255, .04); border-color: rgba(255, 255, 255, .2); }
.aws-band caption { color: #b9cff2; }
.aws-band .caption { color: #b9cff2; }
.aws-band .caption svg { color: #8fc4ff; }
.aws-band table { color: #e6efff; }
.aws-band thead th { background: rgba(255, 255, 255, .08); color: #fff; }
.aws-band th, .aws-band td { border-color: rgba(255, 255, 255, .16); }
.aws-band code {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .25);
  color: #fff;
}
.aws-band .badge--available { color: #b9f2cf; background: rgba(11, 107, 58, .35); border-color: rgba(185, 242, 207, .35); }
.aws-band .badge--beta { color: #ffd9a3; background: rgba(138, 75, 0, .35); border-color: rgba(255, 217, 163, .35); }
.aws-band .badge--dev { color: #d7e3f7; background: rgba(255, 255, 255, .12); border-color: rgba(215, 227, 247, .3); }

/* --- AWS band: full-width table, asymmetric cards (approved) ---
   The table used to share a 527px column with the two cards, which left its
   service column with 106px of usable text: 8.7 characters per line, the
   narrowest measure on the site. The table now takes the whole container and
   the cards move to a row beneath it, keeping the reading order. CSS only: the
   outer grid collapses to one column and the right-hand div becomes the card
   grid.

   The cards are asymmetric (0.82fr / 1.18fr) and the short one is centred
   against the long one, so the leftover height splits into equal margins above
   and below instead of pooling into a hole under the short card. height:auto is
   required because .card carries height:100% from the design system, which
   would otherwise stretch the 234px card to 879px.

   Column widths are fixed px only above 1000px: at 768px a fixed 380px service
   column left 170px for the description and the measure collapsed to 15.7. */
@media (min-width: 900px) {
  .aws-band .grid--2 { grid-template-columns: minmax(0, 1fr); }
  .aws-band .grid--2 > div:last-child {
    display: grid;
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
    gap: 1.5rem;
    align-items: start;
    margin-top: 2rem;
  }
  .aws-band .grid--2 > div:last-child > .card { height: auto; }
  .aws-band .grid--2 > div:last-child > .card:first-child { align-self: center; }
}
@media (min-width: 1000px) {
  .aws-band table th, .aws-band table td { padding: 1rem 1.1rem; }
  .aws-band table tbody th { width: 380px; }
  .aws-band table tbody td:last-child { width: 140px; }
}

/* --- AWS table on phones (approved) ---
   Below 768px the table stops scrolling sideways and each AWS service becomes a
   self-contained block: name, description, maturity badge. The description goes
   from 208px to the full column, lifting it from 26.2 to 39.3 characters per
   line, and the three column names stay on screen as the legend above the
   blocks. The section grows about 129px at 390px in exchange.

   No data-label attributes and no ::before content, so nothing is duplicated for
   a screen reader. The accessibility tree was compared against the same table in
   its normal layout: table, rowgroup, 8 rows, 3 columnheaders, 7 rowheaders and
   14 cells, same nesting and same order. */
@media (max-width: 767px) {
  .aws-band .table-wrap { overflow-x: visible; }
  .aws-band table { min-width: 0; }
  /* the caption must join the rule: left as display:table-caption it still sized
     the table by the header min-content and overflowed by 84px at 320px */
  .aws-band table, .aws-band caption, .aws-band thead, .aws-band tbody,
  .aws-band tr, .aws-band th, .aws-band td { display: block; width: auto; }
  .aws-band thead tr { display: flex; gap: 1rem; border-bottom: 1px solid rgba(255, 255, 255, .18); }
  /* min-width:0 is required or the header labels size the flex row to
     min-content and push it past the container */
  .aws-band thead th { flex: 1 1 0; min-width: 0; font-size: .75rem; }
  .aws-band tbody tr { padding: 1rem 0; border-bottom: 1px solid rgba(255, 255, 255, .12); }
  .aws-band tbody tr:last-child { border-bottom: 0; }
  .aws-band tbody th, .aws-band tbody td { padding: 0; border: 0; }
  .aws-band tbody th { font-size: 1rem; margin-bottom: .4rem; }
  .aws-band tbody td:first-of-type { margin-bottom: .6rem; }
  .aws-band tbody td:last-child { text-align: left; }
}

.confirm-flag {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #ffd9a3;
  border: 1px dashed rgba(255, 217, 163, .6);
  border-radius: 999px;
  padding: .1rem .5rem;
  vertical-align: middle;
}

/* --- Company --- */
.facts { display: grid; gap: 0; margin: 0; border-top: 1px solid var(--line); }
.facts > div {
  display: grid;
  grid-template-columns: 1fr;
  gap: .15rem 1rem;
  padding: .75rem 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: .94rem;
}
@media (min-width: 420px) {
  .facts > div { grid-template-columns: minmax(7rem, 34%) 1fr; gap: .5rem 1rem; }
}
.facts dt { font-weight: 600; color: var(--navy); margin: 0; }
.facts dd { margin: 0; color: var(--muted); overflow-wrap: anywhere; }

.banner-band img { width: 100%; border-radius: var(--radius); border: 1px solid var(--line); }

/* --- Contact --- */
.contact-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  box-shadow: var(--shadow);
}
.mailto {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding-block: .25rem;
  font-size: clamp(1.05rem, 2.4vw, 1.5rem);
  font-weight: 600;
  color: var(--blue-strong);
  text-decoration: none;
  word-break: break-word;
}
.mailto:hover { text-decoration: underline; color: var(--navy); }
.copy-btn {
  margin-top: 1.1rem;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .45rem 1rem;
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  color: var(--navy);
  cursor: pointer;
}
.copy-btn:hover { border-color: var(--blue); }
[hidden] { display: none !important; }

/* --- Contato · Etapa 9 · Proposta C ---
   Composicao institucional premium: cartao centrado e estreito, contexto,
   linha de acao com e-mail e botao lado a lado (>=720px) ou empilhados, e
   legenda como nota de rodape separada por um fio. Tudo escopado em
   #contato / #contact para nao vazar para outras secoes. */
#contato .contact-card,
#contact .contact-card { max-width: 52rem; margin-inline: auto; text-align: left; }
#contato .contact-card h2,
#contact .contact-card h2 { max-width: calc(20ch * var(--fator-ch, .855)); }
#contato .contact-card > p,
#contact .contact-card > p { max-width: var(--measure-corpo); }
#contato .c-acao,
#contact .c-acao { margin-top: 1.75rem; padding-top: 1.75rem; border-top: 1px solid var(--line); }
@media (min-width: 720px) {
  #contato .c-acao,
  #contact .c-acao { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem 2rem; flex-wrap: wrap; }
  #contato .c-acao p:has(> .mailto),
  #contact .c-acao p:has(> .mailto) { margin: 0; }
  /* 15rem (240px) > 234px natural da string PT mais longa ("Copiar endereco de e-mail"):
     impede que o botao encolha de 234px para 13.5rem (216px) quando o rotulo muda
     para "Endereco copiado" apos o copy. A mesma folga existe na versao EN, mas e
     pequena e mantem a largura estavel nos dois idiomas. */
  #contato .copy-btn,
  #contact .copy-btn { margin-top: 0; padding: .8rem 1.4rem; min-width: 15rem; text-align: center; }
}
#contato .mailto,
#contact .mailto { padding-block: .25rem; }
@media (max-width: 719px) {
  #contato .c-acao,
  #contact .c-acao { margin-top: 1.5rem; }
  #contato .copy-btn,
  #contact .copy-btn { margin-top: .9rem; width: 100%; padding: .85rem 1.2rem; text-align: center; }
  /* WCAG 2.5.5: alvo de toque minimo de 44x44 CSS px. Com font-size ~16.8px e
     line-height ~1.2, padding-block .65rem (10.4px) + texto ~20px = ~41px; o
     min-height: 2.75rem garante os 44px mesmo se o line-height variar. */
  #contato .mailto,
  #contact .mailto { min-height: 2.75rem; padding-block: .65rem; display: inline-flex; align-items: center; }
}
#contato .caption,
#contact .caption { margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }

/* --- Contato · Etapa 9 · feedback de copia ---
   O <p id="copy-status> fica sempre no flow (sem o atributo hidden) com min-height
   reservado para que a legenda (.caption) nao se desloque quando o JS preenche
   o textContent. Acessibilidade preservada: role="status" + aria-live="polite"
   anunciam a mudanca para leitores de tela; o conteudo inicial e um unico espaco
   (nao vazio puro) para que screen readers nao ignorem o live region. */
#contato #copy-status,
#contact #copy-status {
  margin: .5rem 0 0;
  font-size: .85rem;
  color: var(--muted);
  line-height: 1.4;
  min-height: 1.4rem;
  /* flex-basis: 100% mantem o status sempre em uma linha propria do .c-acao
     (display:flex; flex-wrap:wrap). Quando o JS preenche o textContent, a linha
     nao reflowa verticalmente: a altura reservada (1.4rem) ja cobre 1 linha em
     desktop e o @media abaixo cobre 2 linhas no celular. */
  flex-basis: 100%;
}
@media (max-width: 719px) {
  /* No celular o texto quebra em ate 2 linhas (47 chars em ~360px). */
  #contato #copy-status,
  #contact #copy-status { min-height: 2.6rem; }
}

/* --- Legal page --- */
.legal { max-width: 46rem; }
.legal h2 { font-size: var(--step-3); margin-top: 2.25rem; }
.legal h3 { font-size: var(--step-1); margin-top: 1.5rem; }
/* Os `:not()` devolvem o token as classes especiais: sem eles, esta
   regra vence o `.eyebrow` global e a etiqueta de topo da pagina sairia
   a 16px em vez de 13px; e cada `:not()` acrescenta uma classe a
   especificidade, o que faria a meta `.updated` e a legenda `.caption`
   perderem o proprio tamanho.
   Mesmo padrao de `.section-head p:not(.eyebrow)`. */
.legal p:not(.eyebrow):not(.updated):not(.caption), .legal li { font-size: var(--fs-16); line-height: var(--lh-16); }
.legal .updated { color: var(--muted); font-size: .875rem; }

/* --- About page (/pt/sobre/, /sobre/) --- */
/* Página institucional com H1 + lede + lista "Nossa atuação". Aproveita as
   classes de section já existentes (section, wrap, section-head, eyebrow,
   lede) e adiciona apenas o ajuste de hierarchy para H1 em vez de H2. */
.section--sobre { padding-top: clamp(3rem, 6vw, 5rem); }
.section-head--page h1 {
  font-size: clamp(2rem, 4.5vw, var(--step-4));
  line-height: 1.1;
  letter-spacing: -.02em;
  margin: 0 0 1rem;
  color: var(--navy);
  max-width: calc(28ch * var(--fator-ch, .855));
}
.section-head--page .lede {
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  line-height: 1.55;
  color: var(--ink);
  max-width: calc(56ch * var(--fator-ch, .855));
  margin: 0 0 1rem;
}
.section-head--page p { max-width: calc(56ch * var(--fator-ch, .855)); }

/* O bloco legado .sobre-atuacao (limite de largura, borda no topo e a lista
   antiga de frentes) foi removido: a pagina Sobre tem layout proprio em
   assets/css/sobre.css e nenhuma outra pagina usa essas classes. */

/* --- Motion preferences --- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .btn:hover { transform: none; }
}

/* ==========================================================================
   E F Cunha Soft House — V2 refinement (development scope)
   --------------------------------------------------------------------------
   Added after Etapa 1 visual review (2026-10-15).
   Do not promote to assets/css/site.css until the V2 release is approved.
   ========================================================================== */

/* --- Hero institucional: logo menor, copy com mais largura no desktop --- */
.hero--institutional .hero-visual--logo {
  max-width: 360px;
  margin-inline: auto;
}
.hero--institutional .hero-visual--logo img {
  width: 100%;
  height: auto;
}
.hero--institutional .hero-visual--logo .caption {
  margin-top: .75rem;
}
@media (min-width: 980px) {
  .hero--institutional .hero-grid {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    gap: clamp(1.5rem, 3vw, 2.5rem);
    align-items: center;
  }
  .hero--institutional .hero-visual--logo img {
    max-width: 320px;
  }
}

/* --- Bloco 3 (CloudPilot): compacto, sem fundo alternativo --- */
#cloudpilot.section {
  padding-block: clamp(2rem, 4.5vw, 3.25rem);
}
#cloudpilot .section-head {
  max-width: calc(60ch * var(--fator-ch, .855));
  margin-inline: auto;
  text-align: left;
}

/* --- Bloco 4 (Engenharia): 3 colunas no desktop sobrepondo o global --- */
[id="engineering"] .grid--3,
[id="engenharia"] .grid--3 {
  grid-template-columns: 1fr;
}
@media (min-width: 720px) {
  [id="engineering"] .grid--3,
  [id="engenharia"] .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 980px) {
  /* id do bloco + classes vencem o seletor global .grid--3:has(> .card--plain) */
  [id="engineering"] .grid.grid--3:has(> .card--plain),
  [id="engenharia"] .grid.grid--3:has(> .card--plain) {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 1.25rem;
  }
}
[id="engineering"] .grid--3 > .card--plain,
[id="engenharia"] .grid--3 > .card--plain {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* --- Bloco 5 (Empresa e Contato): composição institucional, dados reduzidos --- */
#contato .section-head {
  max-width: calc(60ch * var(--fator-ch, .855));
}
#contato .contact-card {
  max-width: calc(60ch * var(--fator-ch, .855));
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
#contato .contact-card .lede {
  margin: 0;
}
#contato .contact-cta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
#contato .mailto-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
}
#contato .mailto-link:hover {
  border-color: var(--blue);
  color: var(--navy);
}
#contato .copy-btn {
  border: 1px solid var(--line);
  background: #fff;
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.9rem;
  cursor: pointer;
  color: var(--ink);
  font: inherit;
  font-size: var(--step--1);
}
#contato .copy-btn:hover {
  border-color: var(--blue);
  color: var(--navy);
}
#contato #copy-status {
  font-size: var(--step--1);
  color: var(--muted);
  margin: 0;
  min-height: 1.4em;
}

/* --- Rodapé: ajustes finos de espaçamento em mobile --- */
@media (max-width: 600px) {
}

/* --- CloudPilot: nav interno discreto (abaixo do hero) ---
   Índice local só presente na página do CloudPilot, com pílulas de borda
   fina para não competir visualmente com o menu institucional. Acessível
   por teclado (Tab/Shift+Tab), toque (44px de altura mínima no mobile) e
   leitor de tela (aria-label="Seções desta página"). */
.cloudpilot-nav {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  align-items: center;
  padding: .85rem 0;
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  list-style: none;
}
.cloudpilot-nav-hint {
  width: 100%;
  color: var(--muted);
  font-size: .76rem;
  font-weight: 600;
  letter-spacing: .04em;
  margin: 0 0 .25rem;
}
.cloudpilot-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 1.85rem;
  padding: .25rem .7rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  font-size: .82rem;
  font-weight: 500;
  text-decoration: none;
  line-height: 1.3;
}
.cloudpilot-nav a:hover { background: var(--bg-alt-2); border-color: var(--blue); color: var(--navy); }
.cloudpilot-nav a[aria-current="true"] {
  background: var(--bg-alt-2);
  color: var(--blue-strong);
  border-color: transparent;
}
@media (max-width: 600px) {
  .cloudpilot-nav a { min-height: 2.25rem; padding: .35rem .8rem; font-size: var(--fs-14); line-height: var(--lh-14); }
}

/* =============================================================
   PROPOSTA V3 — sobreposições e novos componentes
   ============================================================= */

/* --- Áreas de atuação (Sobre) — 4 cards iguais com ícone colorido --- */
.act-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}
@media (min-width: 980px) {
  .act-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.act-card {
  background: #fff;
  border-radius: var(--radius);
  padding: clamp(1.25rem, 2vw, 1.85rem);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  /* 16px: o gap entre icone, titulo e descricao (briefing: icone->titulo 16px
     e titulo->descricao 12-16px). */
  gap: 1rem;
  min-width: 0;
}
.act-card__icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.act-card__icon--blue {
  background: #eaf2fd;
  color: var(--blue);
}
.act-card__icon--pink {
  background: #fde7f1;
  color: #d6336c;
}
.act-card h3 { margin: 0; color: var(--navy); font-size: var(--fs-22); line-height: var(--lh-22); }
.act-card p { margin: 0; color: var(--muted); line-height: 1.6; }

/* Hover Fill nos act-cards (Etapa Ajuste Soluções).
   Estado normal: card branco, ícone colorido com fundo pastel, texto navy/muted.
   Hover: card vira azul da identidade, ícone transparente com traço branco,
   título branco, parágrafo branco com leve transparência. Transição 250ms. */
.act-card {
  transition: background-color .25s ease, color .25s ease, box-shadow .25s ease;
}
.act-card:hover,
.act-card:focus-within {
  background: var(--blue);
  box-shadow: 0 18px 40px -16px rgba(10, 92, 176, .45);
}
.act-card:hover h3,
.act-card:focus-within h3,
.act-card:hover p,
.act-card:focus-within p {
  color: #fff;
  transition: color .25s ease;
}
.act-card:hover .act-card__icon,
.act-card:focus-within .act-card__icon {
  background: transparent;
  color: #fff;
  transition: background-color .25s ease, color .25s ease;
}

/* --- CloudPilot como faixa horizontal (substitui section--alt) --- */
.cp-strip {
  background: linear-gradient(135deg, var(--navy) 0%, var(--blue-strong) 100%);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: clamp(2rem, 3rem + 1vw, 3rem);
  display: grid;
  gap: 2rem;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  align-items: center;
  position: relative;
  overflow: hidden;
}
.cp-strip::before {
  content: "";
  position: absolute;
  inset: auto -10% -40% auto;
  width: 380px; height: 380px;
  background: radial-gradient(closest-side, rgba(0,174,239,.35), transparent 70%);
  pointer-events: none;
}
.cp-strip__copy h2 { color: #fff; }
.cp-strip__copy p { color: rgba(255,255,255,.85); max-width: calc(50ch * var(--fator-ch, .855)); }
.cp-strip__copy .eyebrow { color: var(--cyan); }
.cp-strip__copy .btn--primary { background: #fff; color: var(--navy); }
.cp-strip__copy .btn--primary:hover { background: var(--bg-alt); }
.cp-strip__shot {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 25px 60px rgba(0,0,0,.32);
  border: 1px solid rgba(255,255,255,.12);
}
.cp-strip__shot img { display: block; }

/* --- Variante clara do cp-strip (imagem mostra fundo claro) --- */
.cp-strip--light {
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.cp-strip--light::before { display: none; }
.cp-strip--light .cp-strip__copy h2 { color: var(--navy); }
.cp-strip--light .cp-strip__copy p { color: var(--muted); }
.cp-strip--light .cp-strip__copy .eyebrow { color: var(--blue); }
.cp-strip--light .cp-strip__copy .btn--primary { background: var(--blue); color: #fff; }
.cp-strip--light .cp-strip__copy .btn--primary:hover { background: var(--navy); }
.cp-strip--light .cp-strip__shot {
  box-shadow: var(--shadow);
  border: 1px solid var(--line);
}
.cp-strip--light .cp-strip__shot img { display: block; }

/* --- Engenharia como grid de cards --- */
.eng-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
@media (min-width: 980px) {
  .eng-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.eng-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 2vw, 1.85rem);
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 1rem 1.25rem;
  align-items: start;
}
.eng-card__icon {
  width: 44px; height: 44px;
  border-radius: 10px;
  background: #eaf2fd;
  color: var(--blue);
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.eng-card h3 { margin: 0 0 .35rem; font-size: var(--fs-22); line-height: var(--lh-22); }
.eng-card p { margin: 0; color: var(--muted); line-height: 1.6; }

/* --- Contato centralizado --- */
.contact-card {
  max-width: 640px;
  margin-inline: auto;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 2vw + 1rem, 2.5rem);
  text-align: center;
  box-shadow: var(--shadow-sm);
}
.contact-card .eyebrow { justify-content: center; display: inline-flex; }
.contact-card h2 { margin-top: .5rem; }
.contact-card .lede { margin-inline: auto; }
.contact-actions {
  margin-top: 1.75rem;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  justify-content: center;
  align-items: center;
}

/* --- CloudPilot capabilities: cards com badge Disponível/Beta --- */
.cp-cap {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: .55rem;
}
.cp-cap__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
}
.cp-cap h3 { margin: 0; font-size: var(--fs-22); line-height: var(--lh-22); }
.cp-cap p { margin: 0; color: var(--muted); font-size: var(--step-0); line-height: 1.55; }
.status-badge {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .25rem .55rem;
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.status-badge::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.status-ok { color: var(--ok); background: var(--ok-bg); }
.status-beta { color: var(--beta); background: var(--beta-bg); }

/* --- CloudPilot pillars (Desafio) — sem numeração decorativa --- */
.cp-pillar {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
}
.cp-pillar h3 { margin: 0 0 .35rem; font-size: var(--fs-22); line-height: var(--lh-22); }
.cp-pillar p { margin: 0; color: var(--muted); font-size: var(--step-0); line-height: 1.55; }
.cp-grid-4 { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.cp-grid-3 { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* --- Como funciona (passos + screenshot lateral) --- */
.cp-flow {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
}
.cp-steps { display: grid; gap: 1rem; }
.cp-step {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
}
.cp-step__n {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: .95rem;
}
.cp-step h4 { margin: 0 0 .2rem; font-size: var(--fs-22); line-height: var(--lh-22); }
.cp-step p { margin: 0; color: var(--muted); font-size: var(--step-0); }
.cp-flow__shot {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}
.cp-flow__shot img { display: block; }

/* --- Controle como pílulas --- */
.cp-controls {
  display: flex;
  flex-wrap: wrap;
  gap: .55rem;
  margin-top: 1rem;
}
.cp-controls span {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .55rem .95rem;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--line);
  font-size: var(--step-0);
  color: var(--navy);
  font-weight: 500;
}
.cp-controls svg { color: var(--blue); }

/* --- Cobertura (provedores + hospedagem) --- */
.cp-providers {
  display: grid;
  gap: 1rem;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}
.cp-providers__list,
.cp-providers__host {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
}
.cp-providers h3 { margin: 0 0 .75rem; font-size: var(--fs-22); line-height: var(--lh-22); }
.cp-providers p { margin: 0; color: var(--muted); }
.cp-providers__list ul {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.cp-providers__list li {
  margin: 0;
  padding: .4rem .75rem;
  background: var(--bg-alt);
  border-radius: 8px;
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--navy);
}

/* --- Header V3 — CTA some do header em mobile --- */
@media (max-width: 720px) {
  .header-actions .header-cta,
  .header-actions .btn--primary.header-cta { display: none; }
  .header-actions .lang-switch { margin-left: auto; }
}

/* --- Mobile real (≤480px) ajustes finos --- */
@media (max-width: 480px) {
  .act-grid { grid-template-columns: 1fr; grid-template-rows: auto; }
  .act-card--feature { grid-row: auto; }
  .cp-strip { grid-template-columns: 1fr; padding: 1.5rem; }
  .cp-strip::before { display: none; }
  .cp-flow { grid-template-columns: 1fr; }
  .cp-providers { grid-template-columns: 1fr; }
  .cp-grid-4 { grid-template-columns: 1fr; }
  .cp-grid-3 { grid-template-columns: 1fr; }
  .eng-item { padding: 1.1rem 0; }
  .contact-card { padding: 1.5rem 1.25rem; }
}
@media (max-width: 360px) {
  .cp-grid-4 { grid-template-columns: 1fr; }
  .eng-item__icon { width: 40px; height: 40px; }
}

/* --- Print --- */
@media print {
  .site-header, .hero::after, .btn-row, .lang-switch { display: none; }
  body { color: #000; }
  .section { padding-block: 1rem; }
}
