/* ==========================================================================
   IMASS Theme — Tokens e Reset
   ========================================================================== */

:root {
    /* Cores — referencias/tokens.md §1 */
    --imass-primary: #88619e;
    --imass-dark: #202020;
    --imass-text: #181818;
    --imass-text-light: #555555;
    --imass-white: #ffffff;
    --imass-bg: #ffffff;
    --imass-edge: rgba(24, 24, 24, .15);   /* sombra inset dos botões filled */

    /* Tipografia — tokens.md §2 (Sarabun do tema-pai é sobrescrito por Roboto) */
    --imass-font-body: 'Roboto', Arial, Helvetica, sans-serif;
    --imass-font-heading: 'Playfair Display', Arial, Helvetica, sans-serif;
    --imass-font-eyebrow: 'Roboto Condensed', Arial, Helvetica, sans-serif;

    /* Corpo do builder por banda — NÃO é 14px fixo. O original só declara
       `html{font-size:16px}` (`09-style.css:662`) e nenhum `font-size` em `body` no nível
       base; o 14px é override de `@media (max-width:1199px)` (`:30991`) e o 13px é override
       de `@media (max-width:360px)` (`:31033`). Medido em 0.2a de 18/10 banda a banda
       (`qa/base-font-live.json` × `qa/base-font-replica.json`): 16/24 a 1600, 1440, 1260 e
       1200 · 14/21 de 1199 a 414 · 13/19,5 a 320 — as rodadas antigas calibraram tudo na
       banda do meio, que é a única que o 14px acerta.
       O `line-height` é `1.5em` (`:669`), não `1.5`: `em` resolve no corpo e desce como
       VALOR ABSOLUTO (24px ≥1200) para os filhos, e é isso que mantém um `<p>` de 25px com
       24px de entrelinha no vivo — com `1.5` unitless a réplica inflava a entrelinha de
       cada filho proporcionalmente ao seu próprio tamanho. */
    --imass-font-size-base: var(--imass-builder-em);
    --imass-line-height-base: 1.5em;

    /* Layout */
    --imass-container-max: 1200px;          /* conteúdo da faixa larga (`.bt_bb_cell{width:1200px!important}`) */
    --imass-gutter: 30px;                   /* valeta do port — ver `.container` */
    --imass-header-height: 68px;            /* tokens.md §3a: linha do menu e logo */
    --imass-header-height-sticky: 34px;     /* calc(68px*.5) */
    /* Caixa pintada pelo cabeçalho = linha + forro vertical da faixa larga
       (`40 + 68 + 30`), e a barra da banda móvel (`84`). É ESTA o número que as faixas
       usam para descer o conteúdo, não a linha de 68: o header é sobreposição
       (`btContentWrap` começa em y=0 medido em 0.2a, banda a banda), então quem paga o
       vão é a própria faixa. Usar `--imass-header-height` aqui deixava o topo do herói a
       7px da borda inferior do cabeçalho em 1440. */
    --imass-header-box: 138px;
    --imass-logo-height: 68px;
    --imass-logo-height-sticky: 45.5px;     /* calc(70px*.65) — regra posterior do custom */
    /* Faixa larga (≥1200): o `.port` do cabeçalho NÃO é o `.port` de conteúdo. Ele sangra
       a janela toda (censo do corpus: `class="port"` 1×, `gutter` **0×** em `home.html`) com
       valeta própria de 60px e forro vertical — medido no vivo em 0.2a (`qa/port-oracle.json`):
       caixa `[0,0,vw,138]` = 40 + linha 68 + 30; em sticky `[0,0,vw,84]` = 30 + 34 + 20. */
    --imass-header-pad: 40px 60px 30px;
    --imass-header-pad-sticky: 30px 60px 20px;
    --imass-header-side: 60px;
    --imass-menu-gap: 50px;                 /* `padding-right` do `li` (`09-style.css:2164`) e
                                               `margin-left` do widget (`:2760`) — o mesmo vão
                                               que o `<nav>` paga à esquerda (`:2407`). */
    --imass-logo-shift: -15px;              /* a tinta do logo sobe acima da linha (`inline-custom.css:51`) */

    /* Espaçamento */
    --imass-spacing-xs: 8px;
    --imass-spacing-sm: 16px;
    --imass-spacing-md: 24px;
    --imass-spacing-lg: 40px;
    --imass-spacing-xl: 60px;
    /* Base do `em` DENTRO das colunas de conteúdo do builder, por banda — não é a fonte do
       `body`, é a caixa que as escadas de espaçamento (`16em`, `12em`, `3,75em`, `2em`,
       `.25em`) resolvem. Medida no vivo (0.2a de 18/10, `qa/hero-slides.json`): a coluna de
       texto do herói tem `getComputedStyle().fontSize` = **16px de 1200 para cima** e
       **14px abaixo**, nos 44 pares banda × slide lidos. É por isso que o mesmo
       `extra_large` vale 256, 224 e 168 em bandas diferentes. */
    --imass-builder-em: 14px;
    /* `bt_bb_top/bottom_spacing_large` = **`8,75em` sobre o `.bt_bb_port`** (`09-style.css:10207`)
       e o trap ≤768 do tema corta para `4,375em` (`09-style.css:10291`). O valor é lido no
       próprio invólucro, então ele SEGUE a escada do corpo: medido no vivo em 18/10 o forro da
       primeira faixa de /sobre, /clientes e /servicos é **140px ≥1200** (8,75 × 16), **122,5px**
       em 993–1199 (8,75 × 14), **61,3px ≤768** (4,375 × 14) — `qa/band-top.mjs` +
       `qa/sobre-top.mjs`. Congelar 122,5px aqui errava a banda larga em −17,5 por lado e o topo
       em −38; o token agora é `em` exatamente como a folha do builder, por isso também acerta os
       113,75px do corte ≤360 sem media query nova. */
    --imass-band-spacing: 8.75em;
    /* Os OUTROS degraus da mesma escada de FAIXA (não confundir com a escada de SEPARADOR,
       que em `medium` vale 3,75em — `09-style.css:22084` — e só coincide em `large`:
       `.bt_bb_section.bt_bb_top_spacing_medium > .bt_bb_port{padding-top:5em}` e
       `..._normal{2em}` (`09-style.css:10204`/`:10201`, com os pés de baixo em `:10222`/`:10219`;
       `crush.css:943` dava 4em e perde por ordem de documento). Medido no vivo da home, lado a
       lado (`qa/bands-sections.mjs`): `medium` = **80px ≥1200 / 70px em 992 / 42px ≤768** e
       `normal` = **32px / 28px / 28px** — as três leituras do mesmo `5em`/`2em` sobre a escada
       do corpo. O trap ≤768 corta `medium` para `3em` (`09-style.css:10288`/`:10297`) e não
       toca `normal`. */
    --imass-band-spacing-normal: 2em;
    --imass-band-spacing-medium: 5em;
    /* O degrau de CIMA da escada de FAIXA: `extra_large` = 16em, com o próprio pé no trap
       ≤768 cortando para 12em (`09-style.css:10210`/`:10228` e `:10294`/`:10303`). O censo das
       11 folhas congeladas dá **3 usos, todos na mesma posição**: o topo das três páginas de
       área (`seguranca-do-trabalho`, `medicina-ocupacional`, `meio-ambiente`). Medido no vivo
       a 1440 / 1199 / 768 (`qa/band-ladder.mjs`): **256 / 224 / 168** — 16em, 16em de corpo 14
       e o trap de 12em, na ordem. A D-01 colapsou as três áreas em `/servicos`, então a réplica
       só tem uma faixa que o paga: a primeira. */
    --imass-band-spacing-extra-large: 16em;
    /* Valeta entre colunas de uma linha SEM classe `bt_bb_column_gap_*`: cada coluna leva
       20px de padding por lado (01-content_elements.crush.css:1195) ⇒ 40px entre vizinhas.
       Medido no vivo nos pares 6/6 da home e de /sobre; linhas com valeta explícita
       (`gap_45` = 90px, `gap_10` = 20px) não usam este token. */
    --imass-column-gap: 40px;

    /* Botões — tokens.md §4. O raio vem de body.btHardRoundedButtons, não do elemento. */
    --imass-btn-padding: 1.125em 1.875em;
    --imass-btn-radius: 50px;

    /* Transições */
    --imass-transition: 300ms ease;
}

@media (min-width: 1200px) {
    /* A escada de `em` do builder troca de base exatamente onde troca o modo do menu
       (`btMenuHorizontal` ≥1200). Medido: coluna do herói 16px a 1200/1260/1320/1440 e
       14px a 1199 e abaixo — 44 pares banda × slide (`qa/hero-slides.json`). */
    :root {
        --imass-builder-em: 16px;
    }
}

/* Terceiro degrau da escada do corpo: `@media (max-width:360px){ body{font-size:13px} }`
   (`09-style.css:31033`), medido a 320 (`qa/base-font-live.json`). Abaixo de 361 também
   encolhe as escalas de `em` do builder (`--imass-builder-em`), porque elas resolvem no
   mesmo corpo. */
@media (max-width: 360px) {
    :root {
        --imass-builder-em: 13px;
    }
}

/* ==========================================================================
   Reset
   ========================================================================== */

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

/* O corpus não tem `line-height` em `html` nem `-webkit-text-size-adjust` — o `1.15` aqui
   era normalize.css importado. Vivo resolve `normal` (medido 18/10, `qa/base-font`), e a
   única folha com `line-height: 1.15` no corpus é `ul.bt_bb_tabs_header li span`
   (`01-content_elements.crush.css:5162-5164`). Inerte para o conteúdo porque o `body`
   declara o próprio, mas era lixo de origem. O `text-size-adjust` fica: é o único que
   protege a banda mobile do inflation do iOS e nenhum dos dois lados tem medição dele. */
html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    font-family: var(--imass-font-body);
    font-size: var(--imass-font-size-base);
    line-height: var(--imass-line-height-base);
    color: var(--imass-text);
    background-color: var(--imass-bg);
    /* O header é transparente e sobrepõe a primeira faixa (tokens.md §3a).
       Quem desce o conteúdo abaixo dele é a própria faixa, com padding-top. */
}

/* ==========================================================================
   Contrato global de headings (rodada 19, task #54)
   --------------------------------------------------------------------------
   São DUAS folhas, mesma especificidade (0,0,1), e a que vem depois no `<head>`
   vence: `09-style.css:686-699` põe o clearfix `h1..h6::after{content:" ";display:table;
   width:100%;clear:both}` e `:702-707` põe `{clear:both; padding:0 0 .4em; line-height:1;
   margin:0; font-weight:800; letter-spacing:-.03em}`; `inline-custom.css:40` repõe a
   família (Playfair, sobre o Sarabun de `09-style.css:678-684`) e `:76-78` corrige o
   `line-height` para `1.1`. A escada por nível (`:709-726`) está em **`em`** — segue a
   base do builder (16/14/13), ao contrário dos `rem` das classes `bt_bb_size_*` (§3c.1).

   O que o vivo resolve com ela (`qa/h-styles-live-1440`, 6 rotas · 18/10): `clear=both`
   e `::after{display:table}` em **100%** dos headings, pseudo com altura **0px** (clearfix
   inerte em altura, mas é o valor que o motor imprime), `letter-spacing` = −,03em em todos
   (−0,624px no `h4` de 20,8px · −1,8px nos 60px), `line-height` = 1,1 (22,88 · 27,5) e
   `padding-bottom` = `.4em` exatamente onde nenhuma folha de escopo o zera — o `h4` do
   autor mede 8,32px de `pb`, porque `.btAboutAuthor .aaTxt h*` (`09-style.css:5113-5121`)
   só declara `font-size:1.3em`; nos headings dentro de `.bt_bb_headline` o `padding:0`
   de `09-style.css:9657-9665` vence e o `pb` medido é 0px.

   A regra anterior (`margin-top:0; margin-bottom:.5em; font-weight:700; line-height:1.2`,
   sem `clear`, sem `letter-spacing`, sem `padding`, com um `h2{2.5rem}` avulso) estava
   errada em seis propriedades ao mesmo tempo; só não aparecia nos gates porque quase todo
   título da réplica tem classe própria. A sonda que decide o alcance real dela é
   `qa/h-blast.mjs`: escreve uma sentinela na regra global e relê o computado de cada
   heading — o que muda é governado, o que não muda já tem classe. */
h1, h2, h3, h4, h5, h6 {
    clear: both;
    margin: 0;
    padding: 0 0 .4em;
    font-family: var(--imass-font-heading);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -.03em;
}

/* Escada por nível do corpus (`09-style.css:709-726`), em `em` do corpo da banda. */
h1 { font-size: 3em; }
h2 { font-size: 2.5em; }
h3 { font-size: 2.10225em; }
h4 { font-size: 1.76775em; }
h5 { font-size: 1.4865em; }
h6 { font-size: 1.25em; }

h1::after, h2::after, h3::after,
h4::after, h5::after, h6::after {
    content: " ";
    display: table;
    width: 100%;
    clear: both;
}

p {
    margin-top: 0;
    /* `p, dl, address, cite { margin: 0 0 1em }` (09-style.css:600-605): o vão é 1em do
       próprio parágrafo, não 14px fixo. Nas bandas ≤1199 o corpo é 14 ⇒ mesmo valor de
       antes; ≥1200 vale 16px — medido no vivo (`qa/textblock-live`, p do lede de /sobre
       com `m=[0 0 16 0]` a 1440). */
    margin-bottom: 1em;
}

a {
    color: var(--imass-text);
    text-decoration: none;
    /* Rodada 16 (movimento): o framework dá `a{transition: color 200ms ease}` nu e
       `.mainHeader a{…linear}` só no cabeçalho. O `linear` estava vazando para o site
       inteiro; o cabeçalho continua linear porque `.main-nav a` (especificidade maior)
       o define em linha própria. */
    transition: color 200ms ease;
}

a:hover {
    color: var(--imass-primary);
}

/* Seleção de texto — rodada 15, décimo eixo. O corpus tem exatamente 2 regras
   `::selection` nas 11 páginas congeladas: `#88619e` no `<style id="avantage-style-inline-css">`
   e `#e94d65` + `color:#fff` na folha do framework, que no HTML cru vem DEPOIS (offset
   87.538 vs 16.983) com a mesma especificidade — a cascata lida do congelado resolve em
   vermelho. Não se porta o vermelho: o pixel do congelado já refutou essa leitura nas
   setas do carrossel, que têm o mesmo par inline-antes/framework-depois (inclusive com
   `!important` dos dois lados, `tokens.md` §6.17) e imprimem roxo. O `color:#fff` do
   framework sim, porque sem ele o texto selecionado fica ilegível sobre a marca. */
::selection {
    background: var(--imass-primary);
    color: #fff;
}

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

ul, ol {
    margin-top: 0;
    padding-left: 1.5em;
}

/* `small` é **absoluto** no original: `09-style.css:673-675` dá `font-size: 14px` e não
   `em`/`rem`. Medido em `/artigos` nó a nó (rodada 20, `qa/deep-tree.mjs`): o `SMALL` da data
   vale 14px/19,6 **com corpo a 16** (1440) e 14px/19,6 **com corpo a 14** (768) — se fosse
   relativo, a segunda banda daria 12,25. Sem a regra a réplica caía no default de agente de
   usuário (0,8333em ⇒ 13,33 a 1440 e 11,67 a 768) e a linha de data encolhia 1px/5,33px.
   É regra global e a réplica tem UM emissor de `<small>` (`frontend/articles/_item.php:49`),
   então o raio é exatamente o nó medido. */
small {
    font-size: 14px;
}

/* Citação do `bt_bb_text` — folha inteira em `09-style.css:730-784`, uma regra só para
   os três blockquotes do corpus (home linha 1, sobre faixa 3, clientes faixa 3). É
   `em` puro, então acompanha a escada do corpo: a 14px vira 21,875/28,4375 com valeta
   35/0/35/17,5 (valores que a réplica já tinha medido em /clientes e /sobre); a 16px
   vira 25/32,5 com 40/0/40/20 — medidos 18/10 em `qa/textblock-live` ([740 × 600 × 242,5]
   com `p=[40 0 40 20]`). O recuo `.8em` é da coluna alinhada à esquerda; a variante
   centrada de /clientes (`:749-751`) encolhe a valeta lateral para zero, e a direita
   (`:752-754`) inverte o lado. `blockquote > *:last-child{margin-bottom:0}` (:782-784)
   corta o pé do último parágrafo/`<p>` interno.

   DESVIO DECLARADO (água de aspas): o `blockquote:before` do vivo É gerado — medido
   18/10 em `qa/bqglyph` (`node bqglyph.mjs`, home e sobre, 1440): `content` é o
   caractere U+E900 da área de uso privado, `font-family: Avantage`, `font-size:150px`
   (6em dos 25px do blockquote), `opacity:.1`, `position:absolute; top:-.15em; left:0`
   (`09-style.css:755-766`). Não se porta: o corpus congelado não contém nenhum
   `.woff/.ttf` do Avantage, logo a forma do glifo não é reproduzível; sendo absoluto,
   ele também não move caixa alguma (as alturas medidas acima casam sem ele). */
blockquote {
    display: block;
    position: relative;
    margin: 0;
    padding: 1.6em 0 1.6em .8em;
    font-size: 1.5625em;
    font-style: normal;
    font-weight: 400;
    line-height: 1.3;
}

blockquote > *:last-child {
    margin-bottom: 0;
}

/* Clearfix do próprio corpus (`09-style.css:740-745`): o blockquote limpa flutuados. */
blockquote::after {
    content: " ";
    display: table;
    width: 100%;
    clear: both;
}

button {
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.15;
    margin: 0;
}

/* Os campos não têm corpo próprio no original: `font: inherit` (`09-style.css:243-246`,
   o bloco `input:not([checkbox]):not([radio]), textarea, select`) cola o field ao corpo da
   faixa — 16px ≥1200, 14px ≤1199, 13px ≤360 (`09-style.css:662`/`:31033`) — e é isso que faz
   o `height: 3.25em` (`:318-325`) descer de 52 → 45,5 → 42,25 de banda para banda. O
   `font-size: 1rem` que estava aqui era normalize.css importado: congelava todo campo em
   52px e deixava /contato +42,2px acima do vivo nas bandas de corpo 14 e 13. O mesmo bloco
   do corpus declara ainda `line-height: 1`, `width: 100%`, `padding: 1.25em`,
   `background: transparent` e `color: inherit`; a réplica os aplica por escopo
   (`.contact-form input` §7, `.btComment textarea` §6.7) em vez de global, porque o
   `<select>` e o `input[type=file]` do painel de comentários têm caixa própria. */
input:not([type=checkbox]):not([type=radio]),
textarea,
select {
    font: inherit;
    margin: 0;
}

/* ==========================================================================
   Layout
   ========================================================================== */

.container {
    width: 100%;
    /* A caixa é 1260 e o conteúdo é 1200 — não o inverso. Origem:
       `.bt_bb_section.bt_bb_layout_boxed_1200 > .bt_bb_port .bt_bb_cell
        { width:1200px !important; max-width:calc(100% - 60px) !important }`
       (`09-style.css:18167`), que vale em TODA largura, e o mesmo vão de 30px do
       `.btVerticalHeaderTop` (`09-style.css:3471`) e de `.gutter .port` em ≤1259
       (`09-style.css:1023`). Com `box-sizing:border-box`, `max-width:1260px` +
       `padding:0 30px` reproduz `min(1200px, vw − 60px)` nó a nó; `max-width:1200px` +
       valeta menor dava 12px de folga a mais em toda banda acima de 768.
       Terceira fonte, tinta medida no congelado `screenshots/01-home-591.png` a 591 CSS:
       ☰ em x=30, superheadline do herói em x=31, borda do botão do herói em x=30. */
    max-width: calc(var(--imass-container-max) + 2 * var(--imass-gutter));
    margin: 0 auto;
    padding: 0 var(--imass-gutter);
}

/* Faixa do builder SEM classe de espaçamento não tem forro NENHUM. Medido no vivo
   (`qa/bands-sections.mjs`): as duas faixas em caixa da home valem `padding:0/0` no
   `.bt_bb_port` e a caixa da `<section>` é exatamente a caixa da linha — 799,6 e 699,3 a 1440,
   1460,4 e 1389,1 a 992. O `padding: var(--imass-spacing-xl)` (60px) que a réplica dava como
   padrão não é degrau de escada nenhuma: 60px é o `medium` da escada de **separador**
   (3,75em sobre corpo 16, `09-style.css:22084`), enquanto a escada de **faixa** vale 5em
   (= 80px) no mesmo degrau. Cada faixa passa a declarar o próprio pé nas utilidades abaixo. */
.section {
    padding-block: 0;
}

/* Vocabulário literal das classes `bt_bb_top_spacing_*` / `bt_bb_bottom_spacing_*` do
   congelado, que o builder aplica ao `.bt_bb_port` da faixa (`09-style.css:10192-10229`,
   trap ≤768 em `:10287-10302`; `crush.css:934-968` dava 4em/8em e perde por ordem de
   documento). Em `em` porque o pé segue a escada do corpo: 80/70/42 no `medium` e 32/28/28 no
   `normal`, medidos nos três grupos de banda.

   O `.page-block` (faixa de página) declara AQUI o seu padrão — `large` nos dois lados, o
   degrau das 11 bandas do corpus que não nomeiam outro — e os degraus explícitos vêm DEPOIS
   na mesma folha, porque no builder a classe é o que existe: `.bt_bb_port` só ganha `padding`
   se a faixa carregar `bt_bb_*_spacing_*` (`09-style.css:10192-10229`), ou seja, SEM classe o
   pé é ZERO. Declarar o padrão em `:1786` (depois destas utilidades, mesma especificidade
   0,1,0) engolia qualquer degrau declarado — foi o erro de cascata que a rodada 19 registrou
   para o `2px` do ícone e que a rodada 20 cobrou de verdade na faixa densa de `/servicos`
   (`pt:0` + `bot:medium`), onde ele virava `140/140`. O preço de manter um padrão é o
   marcador `band-top-none` abaixo: a única forma de dizer "esta faixa não tem degrau de topo"
   sem reordenar a folha. */
.page-block {
    padding-top: var(--imass-band-spacing);
    padding-bottom: var(--imass-band-spacing);
}

.band-top-none {
    padding-top: 0;
}

.band-top-normal {
    padding-top: var(--imass-band-spacing-normal);
}

.band-bottom-normal {
    padding-bottom: var(--imass-band-spacing-normal);
}

.band-top-medium {
    padding-top: var(--imass-band-spacing-medium);
}

.band-bottom-medium {
    padding-bottom: var(--imass-band-spacing-medium);
}

.band-top-large {
    padding-top: var(--imass-band-spacing);
}

.band-bottom-large {
    padding-bottom: var(--imass-band-spacing);
}

/* O degrau de topo das três páginas de área (`extra_large` = 16em, trap ≤768 em 12em — ver o
   token em `:81`). No corpus são 3 usos, todos na mesma posição; sob a D-01 só a primeira
   faixa da página colapsada o paga. */
.band-top-extra-large {
    padding-top: var(--imass-band-spacing-extra-large);
}

/* ==========================================================================
   Botões — contrato tokens.md §4
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5em;
    padding: var(--imass-btn-padding);
    font-family: var(--imass-font-body);
    font-size: var(--imass-font-size-base);
    font-weight: 700;
    line-height: 1;
    text-transform: none;
    text-align: center;
    white-space: nowrap;
    border: none;
    border-radius: var(--imass-btn-radius);
    cursor: pointer;
    transition: all var(--imass-transition);
}

/* filled, scheme 6 (roxo) e 11 (grafite): hover NÃO troca cor — o inset engrossa */
.btn--primary,
.btn--primary:hover {
    background-color: var(--imass-primary);
    color: var(--imass-white);
    box-shadow: 0 -2px 0 0 var(--imass-edge) inset;
}

.btn--primary:hover {
    box-shadow: 0 -3px 0 0 var(--imass-edge) inset, 0 3px 10px rgba(0, 0, 0, .3);
}

.btn--dark,
.btn--dark:hover {
    background-color: var(--imass-dark);
    color: var(--imass-white);
    box-shadow: 0 -2px 0 0 var(--imass-edge) inset;
}

.btn--dark:hover {
    box-shadow: 0 -3px 0 0 var(--imass-edge) inset, 0 3px 10px rgba(0, 0, 0, .3);
}

/* `.bt_bb_button:hover a.bt_bb_link` (09-style.css:19160) e o submit do CF7
   (09-style.css:21664) levantam 3px — a transição `all 300ms` já anima o deslocamento. */
.btn:hover {
    transform: translateY(-3px);
}

.btn .btn-icon {
    width: 1.1em;
    height: 1.1em;
    flex: none;
}

/* ==========================================================================
   Header — tokens.md §3a
   ========================================================================== */

.site-header {
    /* Na faixa larga o cabeçalho é uma **sobreposição**: `.btContentWrap` começa em y=0 em
       todas as bandas medidas (0.2a), o `.port` do header é `position:static` dentro de
       `header.mainHeader{position:absolute}` e só vira `fixed` quando o estado sticky liga
       (`body.btStickyHeaderActive .mainHeader`). O z-index do header é 10002, não o do
       drawer — 10003 pertence ao `.mainHeader` em modo vertical. */
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10002;
    /* estado de topo: transparente, texto escuro sobre o slider */
    background-color: transparent;
    color: var(--imass-text);
    transition: background-color var(--imass-transition), box-shadow var(--imass-transition);
}

.site-header.is-sticky {
    position: fixed;
    background-color: var(--imass-white);
    box-shadow: 0 2px 20px 0 rgba(0, 0, 0, .15);
}

/* O `.port` do cabeçalho sangra a janela toda: os 60px de valeta vêm do seu próprio
   `padding`, não do `.container` de conteúdo (censo do corpus: `gutter` **0×** em
   `html/home.html`, e o vivo mede `port [0,0,vw,138]` com `padding:40px 60px 30px`). */
.site-header > .container {
    max-width: none;
    padding: 0;
}

.header-inner {
    padding: var(--imass-header-pad);
    transition: padding var(--imass-transition);
}

/* clearfix do `.port` — `.btContentHolder .port:after{content:'';display:block;clear:both}`
   (`09-style.css:1662`). Sem ele a linha colapsa: logo, menu e botão flutuam. */
.header-inner::after {
    content: '';
    display: block;
    clear: both;
}

.site-logo {
    float: left;
    /* `line-height:0` do `.logo` (`09-style.css:2062`): sem ele a caixa ganharia a altura
       da linha e o `margin-top:-15px` deixaria de subir só a tinta. */
    line-height: 0;
}

.site-logo img {
    height: var(--imass-logo-height);
    width: auto;
    display: block;
    /* Medido: caixa do logo `[60,40,207,53]` e tinta `[60,25,207,68]` — a imagem de 68px
       nasce 15px ACIMA da linha (`inline-custom.css:51`), então o prumo da linha fica em
       40+53=93 enquanto o logo chega a y=93. */
    margin-top: var(--imass-logo-shift);
    transition: height var(--imass-transition);
}

/* --- menu --- */
/* Os dois blocos à direita flutuam na ordem do DOM (`.topBarInMenu` antes do `<nav>` em
   `html/home.html:362-367`), por isso o vão do menu é `padding-left` e o do botão é
   `margin-left`: `nav{float:right;padding-left:50px}` (`09-style.css:2399`, `:2407`) e
   `.topBarInMenu{float:right;margin-left:50px;height:68px}` (`:2760`). */
.main-nav {
    float: right;
    padding-left: var(--imass-menu-gap);
    height: var(--imass-header-height);
    transition: height var(--imass-transition);
}

/* Logo interna do painel off-canvas: só existe na banda móvel (ver o bloco
   `@media (max-width:1199px)`); no desktop o logo já está na barra do topo. */
.main-nav .nav-logo {
    display: none;
}

.main-nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.main-nav > ul > li {
    float: left;
    position: relative;
    z-index: 5;
    padding-right: var(--imass-menu-gap);
    transition: padding-right var(--imass-transition);
}

/* `li:last-child{padding:0}` (`09-style.css:2175`) — sem isto o último item empurraria
   50px de vão que no original não existe e a aritmética do wrap (1103,5px de conteúdo
   contra `vw − 120`) cairia 50px cedo. */
.main-nav > ul > li:last-child {
    padding-right: 0;
}

.main-nav a {
    position: relative;
    display: block;
    padding: 0;
    line-height: var(--imass-header-height);
    font-family: var(--imass-font-body);
    font-size: 16px;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--imass-text);
    transition: color 200ms linear, line-height var(--imass-transition);
}

.main-nav a:hover {
    color: var(--imass-primary);
}

/* item ativo: tick de 10×2px à esquerda, não sublinhado */
.main-nav .is-current > a::after {
    content: ' ';
    display: block;
    position: absolute;
    z-index: 5;
    left: -15px;
    top: 50%;
    margin-top: -1px;
    width: 10px;
    height: 2px;
    background-color: var(--imass-primary);
    pointer-events: none;
}

/* submenu */
.menu-item-has-children {
    position: relative;
}

/* Seletor com a classe do pai de propósito: `.main-nav ul` (0,1,1) põe `padding:0` em todo
   ul do menu e vencia o `.sub-menu` solto (0,1,0) — o padding de 10px 0 medido no VIVO
   (`qa/suba-live.log`) nunca chegava à caixa (134,9px em vez de 154,9px). */
.main-nav .sub-menu {
    position: absolute;
    /* Rodada 28 (pedido do operador, 2ª passada: "algumas vezes o submenu quase cobre o texto
       do menu-pai"). O `top:100%` da 1ª passada já deixava a caixa rente à base do pai EM
       REPOUSO (gap:0 medido), mas o estado OCULTO ainda usava `translateY(-20px)`: durante o
       fade de 200ms a caixa subia 20px para DENTRO do `<li>` (topo 88 de um li que vai a 108)
       e era aí que cobria o texto — o problema era o deslocamento de entrada, não o repouso.
       Correção: a caixa desce mais 8px (`calc(100% + 8px)` = "ligeiramente mais abaixo") e o
       slide oculto cai de -20px para -8px, de modo que o ponto MAIS ALTO da entrada fica em
       108+8-8 = 108 (a base do li), nunca dentro dele. Slide-down preservado, texto do pai
       nunca coberto. DESVIO AUTORIZADO do contrato do vivo (`top:75%`, `qa/submenu-caret.log`);
       o triângulo (::before abaixo) desce junto via `margin-top` e continua apontando ao pai. */
    /* 4ª passada (operador: "ainda ficou longe"). O vão PERCEBIDO não é o `gap` CSS até a base
       do `<li>` (108), é a distância do TEXTO "SERVIÇOS" (y 64–83, medido em
       `qa/r28c-textgap.mjs`) até a caixa: em 112 eram ~29px de área vazia do li. O contrato do
       vivo (`top:75%` = 91) dava só 8px. Correção: caixa em **96** (`calc(100% - 12px)`, 5px
       mais abaixo que o vivo = "ligeiramente mais abaixo", e 16px mais perto que os 112 da
       3ª passada); slide oculto `-8px` ⇒ topo oculto 88, ainda 5px ABAIXO do texto (83), então
       a entrada nunca cobre os glifos. Triângulo reconectado via `margin-top:-21px`. */
    top: calc(100% - 12px);
    left: -20px;
    width: 270px;
    padding: 10px 0;
    background-color: var(--imass-white);
    box-shadow: 0 0 30px 0 rgba(0, 0, 0, .12);
    opacity: 0;
    /* O VIVO nunca põe `visibility:hidden` na caixa (medido: `vis:visible` com `opacity:0`):
       o que a tira do ponteiro é `pointer-events:none` (:2195), e o fade de 200ms corre
       inteiro visível. Com `visibility` + delay de 200ms a réplica só mostrava a caixa DEPOIS
       do fade (pop súbito medido em t60/t120: opacidade 0,58/0,92 com `vis:hidden`). */
    pointer-events: none;
    /* Rodada 16 (movimento): o original desliza o dropdown, não só o esmaece —
       `.menuPort ul > li > ul{opacity:0; transform:translateY(-20px)}` e o container
       `.menuPort nav ul{transition: all 200ms ease}` (11/11 páginas). Rodada 28 reduziu o
       offset para -8px (4ª passada, ver acima): o topo oculto (88) fica abaixo do texto (83). */
    transform: translateY(-8px);
    transition: opacity 200ms ease, transform 200ms ease;
    flex-direction: column;
    gap: 0;
}

.menu-item-has-children:hover > .sub-menu,
.menu-item-has-children:focus-within > .sub-menu {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

/* A tinta roxa dos itens: `inline-custom.css:93-95` — `.menuPort > nav > ul > li.on a{color:#88619e}`
   é um seletor DESCENDENTE, então quando o li-pai ganha `.on` (hover) TODAS as âncoras dentro
   dele — o link-pai E cada item do submenu — ficam roxas (`--imass-primary`), não só a que está
   sob o cursor. A réplica não tem o `.on` injetado pelo JS do tema-pai: ela abre o submenu por
   `:hover`/`:focus-within`, então o gatilho equivalente é o do próprio `.menu-item-has-children`.
   Medido no VIVO (`qa/subcor6.log`): sob hover puro no pai, 1º item do submenu = `rgb(136,97,158)`,
   enquanto a réplica dava `rgb(24,24,24)` — o `09-style.css` sozinho (`ul ul li a{color:#181818}`,
   `ul ul li a:hover{color:#e94d65}`) não explica o roxo; vem desta regra de marca. */
.main-nav .menu-item-has-children:hover a,
.main-nav .menu-item-has-children:focus-within a {
    color: var(--imass-primary);
}

/* Rodada 25 (submenus): a "seta" — o rabo de balão que aponta ao item-pai no topo da caixa
   do submenu. Contrato no original `09-style.css:2228-2285`:
   `.menuPort > nav > ul > li.menu-item-has-children:before` é um triângulo branco de 16×9
   (`border-left/right: 8px solid transparent` + `border-bottom: 9px solid #fff`), em
   `opacity:0` + `transform:translateY(10px)` no repouso e `opacity:1` + `translateY(0)` no
   `.on` (hover) com `transition:200ms ease all` e `transition-delay:100ms` na entrada.
   Horizontal: `left:50%; margin-left:-33px` — o li "SERVIÇOS" mede ~125,5px nos dois lados
   (texto 75,5 + `padding-right:50px`), então o ápice cai a ~29,75px da borda do li, que é
   também a borda esquerda da caixa (`left:-20px` + 270px de largura ⇒ a caixa começa 20px
   antes do li). Vertical: acompanha a caixa — na 4ª passada a caixa foi para
   `top:calc(100% - 12px)` (topo em 96); o triângulo desce junto via `margin-top:-21px`:
   base em 96 = topo da caixa, ápice em 87 (4px abaixo do texto "SERVIÇOS", y 64–83) —
   continua apontando ao menu-pai e conectado à caixa.
   Confirmado no VIVO (`qa/submenu-caret.log`) para o par de margens/bordas; o `top` é desvio
   autorizado do operador. */
.main-nav .menu-item-has-children::before {
    content: "";
    display: block;
    position: absolute;
    z-index: 3;
    left: 50%;
    top: 100%;
    width: 0;
    height: 0;
    margin-left: -33px;
    margin-top: -21px;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-bottom: 9px solid var(--imass-white);
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 200ms ease, transform 200ms ease;
    transition-delay: 0s;
    pointer-events: none;
}

.main-nav .menu-item-has-children:hover::before,
.main-nav .menu-item-has-children:focus-within::before {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 100ms;
}

.sub-menu a {
    position: relative;
    /* Ritmo do item medido no VIVO (`qa/suba-live.log`): caixa de 154,9px = 3 itens de 45px
       (`padding:12px 20px` + `line-height:1.5` sobre 14px) + 10px 0 da caixa. O vertical é o
       `.85714em` de `09-style.css:1720` resolvido em 14px; o horizontal computa 20px no vivo
       (não o `1em`=14px da folha — outra regra do tema-pai vence lá). */
    line-height: 1.5;
    padding: 12px 20px;
    font-size: 14px;
    font-weight: 400;
}

/* Rodada 24 (submenus): a barra horizontal de hover do original —
   `09-style.css:2319-2338`: `::before` com `width:0` em repouso, `width:10px` no hover,
   `height:2px`, `background:#e94d65`, centrado verticalmente (`top:50%; margin-top:-1px`). */
.sub-menu a::before {
    display: block;
    content: "";
    width: 0;
    height: 2px;
    background: var(--imass-accent, #e94d65);
    position: absolute;
    top: 50%;
    margin-top: -1px;
    left: 0;
    transition: width 200ms ease;
}

.sub-menu a:hover::before {
    width: 10px;
}

.sub-menu a::after {
    display: none;   /* o tick só existe no nível 1 */
}

/* --- botão "Acessar sistema" (acento do header) --- */
/* É `.topBarInMenu`: flutua à direita, na frente do `<nav>` (ver o bloco do menu e
   `html/home.html:362-367`), com a altura da linha para o centro óptico do widget. */
.header-access {
    float: right;
    display: flex;
    align-items: center;
    margin-left: var(--imass-menu-gap);
    height: var(--imass-header-height);
    transition: height var(--imass-transition);
}

.site-header.is-sticky .header-access {
    height: var(--imass-header-height-sticky);
}

.access-link {
    display: inline-flex;
    /* O glifo fica À ESQUERDA da etiqueta: no original o DOM é
       [`.bt_bb_button_text`, `.bt_bb_icon_holder`] e o `<a>` é
       `display:flex; flex-direction:row-reverse` (medido no vivo, 0.2a — `dir:row-reverse`,
       ícone 1238,2×10 e texto 1255,2×104,8, com `margin:0 7px 0 0` no holder). A classe do
       widget no congelado já anuncia o lado: `.btIconWidgetLeft`. */
    flex-direction: row-reverse;
    align-items: center;
    gap: .5em;
    /* `1rem 1.25rem` do widget (`09-style.css:8695`) ⇒ caixa 161,8×46 medido no vivo; com
       `line-height:1` sobre a fonte de 14px, 16+14+16 = 46 de prumo. */
    padding: 1rem 1.25rem;
    line-height: 1;
    border-radius: var(--imass-btn-radius);
    background-color: var(--imass-primary);
    color: var(--imass-white);
    font-size: 14px;
    font-weight: 700;
    box-shadow: 0 -2px 0 0 var(--imass-edge) inset;
    transition: all var(--imass-transition);
}

.access-link:hover,
.access-link:focus-visible {
    color: var(--imass-white);
    box-shadow: 0 -3px 0 0 var(--imass-edge) inset, 0 3px 10px rgba(0, 0, 0, .3);
}

/* O glifo do original é uma fonte de ícones: a caixa medida no vivo (0.2a) é
   `.bt_bb_icon_holder` **10×14** ao lado de `.bt_bb_button_text` 104,78 com 7px de vão
   (`0,5em`), e a tinta do SVG fica letterboxada nessa caixa de 10×14 como no glifo —
   é o que fecha a caixa do botão em 161,78×46 e, com ela, a aritmética do wrap
   (`207,3 + 684,4 + 50 + 161,78 = 1103,5` contra `vw − 120`, que dobra a linha em
   1200–1220 e não dobra em 1230, exatamente como no original). */
.access-link svg {
    width: 10px;
    height: 1em;
    flex: none;
    fill: currentColor;
}

/* --- trigger do drawer mobile ---
   Porta direta da coluna do Avantage. `.btVerticalMenuTrigger` tem `height:84px`
   (`09-style.css:3481`) e dentro dele `.bt_bb_icon` é uma caixa de 35×35 com
   `margin: 24,5px auto 0` (`09-style.css:3495`). As três barras são bordas de 2px
   `left:0 right:0` em `top:10%`, `top:50%` (com `margin-top:-1px`) e `bottom:10%`
   (`09-style.css:3503`, `:3569`, `:3556`) ⇒ tintas em 24,5+3,5=28, 24,5+16,5=41 e
   24,5+29,5=54. Medido no congelado `screenshots/01-home-591.png`: as três tintas do ☰
   começam exatamente em y=28, y=41 e y=54. O alvo de toque é a coluna inteira (35×84),
   como no original — não a tinta. */
.menu-toggle {
    display: none;
    position: relative;
    width: 35px;
    height: var(--imass-header-height);
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    color: var(--imass-text);
}

.menu-toggle span {
    position: absolute;
    left: 0;
    right: 0;
    height: 2px;
    background-color: currentColor;
    transition: transform 300ms ease;
    transform-origin: 50% 1px;   /* `09-style.css:3503` */
}

.menu-toggle span:nth-child(1) { top: 28px; }
.menu-toggle span:nth-child(2) { top: 41px; }
.menu-toggle span:nth-child(3) { top: 54px; }

/* Estado aberto = o X do original (`.btMenuVerticalOn`): as duas de fora giram para o meio
   e a do meio encolhe em escala (`09-style.css:3522`, `:3562`, `:3585`). */
.menu-toggle[aria-expanded="true"] span:nth-child(1) {
    top: calc(50% - 1px);
    transform: rotate(45deg);
}

.menu-toggle[aria-expanded="true"] span:nth-child(2) {
    transform: scaleX(0);
}

.menu-toggle[aria-expanded="true"] span:nth-child(3) {
    top: auto;
    bottom: calc(50% - 1px);
    transform: rotate(-45deg);
}

/* Cópia do botão "Acessar sistema" que só existe dentro do drawer (ver `$accessLink`
   em `layouts/frontend.php`); no desktop é `display:none` e não entra no fluxo. */
.nav-access {
    display: none;
}

/* ==========================================================================
   Home — contratos em tokens.md §3c (slider + card de serviço) e §6.2
   ========================================================================== */

/* --- 3.4 Cabeçalhos de seção ------------------------------------------------
   Escala por classe do builder (§2): a coluna de texto mede 1,5625em do corpo. */

.section-head {
    margin-bottom: var(--imass-spacing-lg);
}

.section-head--center {
    text-align: center;
}

.section-eyebrow {
    /* Escada do superheadline por classe de tamanho (`09-style.css:18242-18262`), toda em
       `rem`: huge/extralarge/large 1,125rem · medium 1rem · normal 0,9375rem · small/extrasmall
       0,875rem. A entrelinha é a MESMA quantia declarada no invólucro `_outside`
       (`:18217-18237`), e o vão é `margin: 0 0 .6em` (`:18241`) sobre o próprio tamanho.
       `rem` e não `em`/px porque `html{font-size:16px}` (`:662`) é fixo em toda banda:
       medido 18/18 · mb 10,8 a 1440 e 14,4/18 · mb 8,64 a 320 no vivo (`qa/eyebrow-ladder`). */
    font-family: var(--imass-font-eyebrow);
    font-size: 1.125rem;
    font-weight: 400;
    line-height: 1.125rem;
    color: var(--imass-text);
    margin: 0 0 .6em;
}

/* Degrau usado pela réplica: `size_medium` é o superheadline da faixa "SOLICITE UMA
   VISITA" da home — medido 16/16 · mb 9,6 nos dois viewports, e o corte de ≤360 NÃO o
   alcança (`:31046-31055` só nomeia huge/extralarge/large). Os outros degraus da escada
   (`normal` 0,9375rem, `small`/`extrasmall` 0,875rem) não viram classe aqui: as headlines
   `small` da réplica são os rótulos dos contadores, que têm classe própria (`.counter-sub`,
   rodada 14), e as `extrasmall` são o rodapé (`.footer-eyebrow`). */
.section-eyebrow--medium {
    font-size: 1rem;
    line-height: 1rem;
}

.section-title {
    /* `bt_bb_size_large` — cascata congelada (09-style.css): 3,75rem no topo da escada e
       2,4rem só dentro de `@media (max-width:1399px)`. O `rem` não segue a base do builder
       porque `html{font-size:16px}` (@16231, profundidade 0, fora de qualquer @media).
       `padding:0`: no original todo título de seção é `h*` dentro de `.bt_bb_headline`, e a
       folha do builder zera o `.4em` da regra global ali (`09-style.css:9657-9666`); o vivo
       mede `pb=0px` nos 13 headings da home e nos 6 de /sobre (`qa/h-styles-live-1440`). */
    font-family: var(--imass-font-heading);
    font-size: 3.75rem;
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -0.03em;
    margin: 0;
    padding: 0;
}

.section-title--normal {
    /* `size_normal` valeria 1,875rem; na home o `inline-custom.css:85113`
       `.home .bt_bb_size_normal.bt_bb_headline h3{font-size:2.5rem}` vence e não tem
       override por banda — medido 40px nas seis bandas. */
    font-size: 2.5rem;
}

.section-title--medium {
    /* `size_medium`: 2,5rem ≥1400px, 2,25rem abaixo. */
    font-size: 2.5rem;
}

/* size_small — rótulo dos contadores: sem override ≤1399 na cascata do original ⇒ 25px
   em toda a banda (as regras de 1399 do builder só cortam huge/extralarge/large/medium). */
.section-title--small {
    font-size: 1.5625rem;
}

/* Peso por widget: `bt_bb_font_weight_normal` (09-style.css:305340) vale para a headline
   inteira e o `<b>`/`<u>` do título herdam (`:841456`/`:841526` `font-weight:inherit`),
   então o texto pinta em 400 — não em 700 nem no 800 do padrão. */
.section-title--weight-normal {
    font-weight: 400;
}

/* <b> é a marcação medida do título; <u> no builder é acento gráfico, não link. */
.section-title b,
.hero-title b {
    font-weight: inherit;
}

.section-title u,
.hero-title u {
    text-decoration: none;
}

/* Cores medidas no vivo em /sobre (17/10) e escritas em `inline-custom.css`:
   `.bt_bb_headline b{color:#88619e}` e `.bt_bb_headline u{color:#202020}` — a regra é da
   CLASSE `bt_bb_headline`, não do widget de seção. Por isso ela alcança também o título do
   herói: re-leitura do congelado nesta rodada (`home.html`, nó do slide 1) mostra o `<h1>`
   do slider dentro de `<header class="bt_bb_headline bt_bb_dash_none bt_bb_superheadline
   bt_bb_size_huge">` — `<b>Integração em Meio Ambiente, Saúde e</b><br>\n<u>Segurança do
   Trabalho</u>`. A versão anterior restringia o par a `.section-title` com o argumento de
   que "os títulos de card não são `.bt_bb_headline`"; o argumento é vero para
   `.service-title` (que tem par próprio abaixo) e FALSO para `.hero-title`. Consequência
   medida na réplica: as duas cores não chegavam nunca ao carrossel e o título saía
   inteiro em `--imass-text` (1 linha, 1 cor) — exatamente o que o operador apontou. */
.section-title b,
.hero-title b {
    color: var(--imass-primary);
}

.section-title u,
.hero-title u {
    color: var(--imass-dark);
}

.section-sub {
    /* Mesma escada do superheadline, agora sobre `line-height: 1.5em` e `margin-top: 1.3em`
       próprios (`09-style.css:18272-18299`). Em `rem`: 18/27 · mt 23,4 a 1440 e
       14,4/21,6 · mt 18,72 a 320, ambos medidos no vivo (`qa/sub-ladder`). As sub-rúbricas
       da réplica são todas `size_large`; as `extrasmall` do rodapé têm classe própria. */
    font-size: 1.125rem;
    line-height: 1.5em;
    margin: 1.3em 0 0;
}

/* Escala medida no vivo: a 591px large vale 38,4px e medium 36px — os dois cortam dentro do
   mesmo `@media (max-width:1399px)` do builder (`09-style.css:1383240`, com `!important`). */
@media (max-width: 1399px) {
    .section-title {
        font-size: 2.4rem;
    }

    .section-title--medium {
        font-size: 2.25rem;
    }

    /* `size_normal` não tem override na cascata do original — precisa vir depois
       da regra base do `.section-title` para não ser engolido por ela. */
    .section-title.section-title--normal {
        font-size: 2.5rem;
    }

    /* Idem `size_small`, medido nó a nó na faixa de contadores em 18/10 (rodada 20): o corte
       de ≤1399 do builder nomeia `huge`/`extralarge`/`large`/`medium` e NÃO `small`, então o
       rótulo do contador vale 25px em TODA a banda — o vivo confirma 25/27,5 a 1440, 1200,
       992, 768 e 591 (`qa/deep-live-count.json`). Sem esta linha, a regra de cima (mesma
       especificidade 0,1,0, declarada depois) engolia o `--small` e o rótulo saltava para
       38,4/42,24 abaixo de 1400: +66 de Δh na faixa a 1200, +75 a 1199, +63 a 992, +149 a 768
       e +279 a 360. */
    .section-title.section-title--small {
        font-size: 1.5625rem;
    }
}

/* Corte tipográfico de ≤360px nas cabeçalhos de seção — a "Typography breakpoint start 360"
   do builder (`09-style.css:31031-31062`). Só os três tamanhos grandes entram: huge/extralarge
   /large vão a 0,9rem no superheadline e na sub-rúbrica. Medido no vivo a 320
   (`qa/eyebrow-ladder-live-320`, `qa/sub-ladder-live-320`): eyebrow 14,4/18 · mb 8,64 e
   sub 14,4/21,6 · mt 18,72. A entrelinha do eyebrow FICA 1,125rem — o corte é só de
   `font-size` no span interno (`_outside` não é nomeado na query), por isso 14,4/18 e não
   14,4/14,4. `size_medium` e `extrasmall` não aparecem na query e não mudam. O corte do
   TÍTULO huge (3rem) está no bloco de ≤360 do herói, §4. */
@media (max-width: 360px) {
    /* O `:not()` é o equivalente da lista de seletores do corpus, que nomeia UM degrau por
       vez (`huge`/`extralarge`/`large`): sem ele, a regra de corte — declarada depois —
       engoliria o `size_medium`, que mede 16/16 · mb 9,6 também a 320. */
    .section-eyebrow:not(.section-eyebrow--medium) {
        font-size: .9rem;
    }

    .section-sub {
        font-size: .9rem;
    }
}

/* --- Grades --------------------------------------------------------------- */

.grid-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--imass-spacing-lg) var(--imass-column-gap);
}

.grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--imass-spacing-lg) var(--imass-column-gap);
}

/* --- Par de colunas (linhas 6/6 do builder) -------------------------------- */

/* O vão VERTICAL do builder não existe. Censo do corpus congelado (18/10, rodada 19):
   as 11 folhas têm **2** declarações `gap`/`row-gap`/`column-gap` no total, ambas dentro de
   `.bt_bb_separator_v2 .bt_bb_separator_v2_inner` (`01-content_elements.crush.css:3633` e
   `:3661`) —widget que não ocorre nas 11 páginas. A linha é
   `.bt_bb_row_holder{display:flex;flex-flow:row wrap;justify-content:space-between}`
   (`:76-83`) sem `gap`: quando as duas colunas de 6 empilham, elas **encostam**, e o respiro
   vertical vem dos separadores dentro da coluna (ver `.bb-rule--void`), nunca do contentor.
   Medido no `/sobre`: a coluna em caixa fecha em 842,9 e a de mídia começa em 842,9 a 992;
   808,7 = 808,7 a 768 e 591. O `40px` daqui era invenção e valia +40 de Δy nas três bandas.
   O `column-gap` fica: a 6/6 lado a lado ele é a valeta de 20+20 (`:1195`), e ≥993 nas linhas
   em caixa é substituído por `0` porque ali a valeta é padding da coluna. */
.split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--imass-column-gap);
    align-items: start;
}

.split--center {
    align-items: center;
}

/* linha 4: headline à esquerda e VER TODOS à direita, ambos na base da célula */
.split--bottom {
    align-items: end;
}

.split-col--action {
    text-align: right;
}

.split-col--media img {
    margin-left: auto;
}

/* --- Linha 6/6 com conteúdo em caixa (sangra até a janela) ------------------ */

/* O builder marca a seção com `bt_bb_section_show_left_boxed_content` (texto à esquerda)
   ou `..._right_...` (texto à direita). A etiqueta tem dois efeitos, ambos congelados em
   `09-style.css` e medidos nó a nó na Rodada 18 (`qa/home-cols-live.json`):

   1. a célula da seção vira `width:100vw` (`:10282`), então a LINHA sangra até as bordas da
      janela; abaixo de 993 a mesma célula volta para a caixa de 1200 com vão de 30
      (`:18168`, dentro do `@media (max-width:992px)` de `:18105`) e as colunas empilham.
   2. as colunas ficam lado a lado, cada uma em `(100% + 2G)/2` — o `.bt_bb_row_holder` leva
      `margin-inline:-G` (medido, G = 20px) e cada coluna `padding-inline:G`, então a primeira
      começa em x=-G. A coluna de texto recebe `max-width:calc(1200px/12*6)` com
      `margin-left:auto` (`:15139`) ou `margin-right:auto` (`:17616`), conforme a variante —
      em ambas a caixa de 600 encosta no CENTRO da janela, não na borda.

   Caixa de tinta do texto: [V/2-G-600, V/2-G] na variante esquerda e [V/2+G, V/2+G+600] na
   direita. A 1440 isso é 100..700 e 740..1340; a 1260, 10..610; a 1200 e 1000 a caixa de
   600 já não cabe na meia-janela e o texto encosta na borda (0..580, 0..480) — os quatro
   casos batem com o vivo. O `max-width` abaixo é a caixa de 600 mais a valeta da coluna
   (600 + 2G). As duas colunas de mídia da HOME ainda levam `bt_bb_padding_double`
   (`01-content_elements.crush.css:1219` = +20px no `.bt_bb_column_content`, além dos 20px
   da coluna): é o que faz o `imass-10.png` medir 660 a 1440 quando o texto mede 600. Em
   `/sobre` e `/contato` as colunas de mídia são `padding_normal`, por isso o modificador
   `--double` só existe nas linhas da home.

   O vão mora FORA das `@media` porque vale nas duas bandas. Abaixo de 993 o `margin: 0 -20px`
   do `.bt_bb_row_holder` (`crush:1192`) e o `margin: 0 -30px` da linha do `/contato`
   (`crush:1553`) continuam empurrando as colunas para fora da célula, e o trap de 992 só troca
   o `padding` das colunas por `20px !important` (`09-style.css:18106-18121`). Medido na banda
   empilhada (`qa/bleed-rows.mjs`, 992): home e /sobre com coluna em [10,972] e tinta [30,932],
   a `--double` da home em tinta [50,892], e o /contato com coluna [0,992] e tinta [20,952]. */
.split--bleed {
    --bleed-gap: 20px;                      /* `01-content_elements.crush.css:1195` — o vão padrão do builder */
}

.split--bleed.contact-body__row {
    --bleed-gap: 30px;
}

@media (min-width: 993px) {
    .split--bleed {
        width: calc(100vw + 2 * var(--bleed-gap));
        margin-left: calc(50% - 50vw - var(--bleed-gap));
    }

    /* O builder não tem `gap`: o vão entre colunas é valeta das colunas, com o mesmo vão de
       overhang no `.bt_bb_row_holder` (`crush:1544-1552` para `bt_bb_column_gap_30`). Sob
       sangramento isso tem de ser reproduzido como valeta — com `column-gap` a conta da caixa
       de 600 encostada no centro não fecha. `column-gap:0` com dois classes para vencer o
       `column-gap:60px` de `.contact-body__row` (abaixo), que vale até 992. */
    .split.split--bleed {
        column-gap: 0;
    }

    .split--bleed > .split-col {
        padding-inline: var(--bleed-gap);
    }

    .split--bleed > .split-col--boxed {
        width: 100%;
        max-width: calc(600px + 2 * var(--bleed-gap));
    }

    .split--bleed > .split-col--boxed:first-child {
        justify-self: end;
    }

    .split--bleed > .split-col--boxed:last-child {
        justify-self: start;
    }

    .split--bleed > .split-col--double {
        padding-inline: calc(var(--bleed-gap) + 20px);
    }
}

/* A MESMA valeta existe abaixo de 993, onde a célula volta para dentro e a linha sangra só o
   `margin` do holder. Não é cosmética: é o que separa as três tintas medidas acima. O
   `padding-inline: 20px` é o `!important` do trap de 992 (`09-style.css:18115-18116`) e vale
   para TODAS as colunas da linha, inclusive a `--double`, que soma os seus 20 por cima
   (`crush:1219`) ⇒ 40. O `/contato` usa o vão de 30 da própria linha, então sangra 30 e fica
   com tinta [20,952] a 992, não [30,932]. */
@media (max-width: 992px) {
    .split--bleed {
        width: calc(100% + 2 * var(--bleed-gap));
        margin-left: calc(-1 * var(--bleed-gap));
    }

    .split--bleed > .split-col {
        padding-inline: 20px;
    }

    .split--bleed > .split-col--double {
        padding-inline: 40px;
    }
}

/* Ritmo interno das colunas em caixa. Fora do `@media` de sangramento de propósito: os
   separadores do builder existem em toda banda e só valem o que o corpo da banda vale —
   `bottom_spacing_normal` = **2em** (`01-content_elements.crush.css:3302`) e
   `top_spacing_small` = 1em (`:3332`). Medido a 1440 (`qa/textcol-1440-live.json`,
   `qa/service-box-live.json`): cabeçalho→conteúdo 32px e cada card da grade 2×2 fecha com
   16+32 = 48px (célula 251,2 = service 203,2 + 48), com as duas linhas encostadas — o vão
   vertical que o original tem NÃO é `gap` de grade, é o separador dentro da célula.
   A 14px de corpo os mesmos 2em/3em dão 28/42, que é o número que as rodadas de bandas
   móveis congelaram. */
.split--bleed .section-head {
    margin-bottom: 2em;
}

.split--bleed .grid-2 {
    row-gap: 0;
}

.split--bleed .grid-2 > .service {
    margin-bottom: 3em;
}

/* A ÚLTIMA coluna da grade fecha sem separador. No vivo cada `bt_bb_column_inner` traz o
   `bt_bb_separator bt_bb_border_style_none` (`m=16/32` a 16 de corpo, `m=14/28` a 14) DEPOIS
   do card, menos a última coluna da última linha interna — medida em 18/10 (`qa/coltree-*-home`
   1440 e 1199): a 1199 a linha 2 do vivo mede `max(137,2+42, 158,2) = 179,2` porque o card mais
   alto (Saúde e Ambulatórios, 158,2) está na coluna que não tem separador, enquanto a réplica
   dava `158,2 + 42 = 200,2` (+21,0 no gate, metade do +42 que o par tinha antes dos portes de
   entrelinha). A 1440 os quatro cards são iguais (203,2), então a regra é neutra ali. */
.split--bleed .grid-2 > .service:last-child {
    margin-bottom: 0;
}

/* --- Card de serviço ------------------------------------------------------- */

.service {
    display: flex;
    align-items: flex-start;
}

/* Holder do glifo (`09-style.css`, escada de `.bt_bb_service`):
       .bt_bb_size_large.bt_bb_service .bt_bb_icon_holder{font-size:50px;width:1.8em;height:1.8em;line-height:1.8em}
   → disco de 90 × 90 px (1,8 × 50), letraform a 50 px, e a CENTRATURA É DE LINHA, não de
   flex: o `line-height:1.8em` faz a linha tipográfica medir exatamente a altura do disco, e
   o glifo se apoia na linha de base que a fonte declara. Os 90 px são o valor medido no
   vivo nas rodadas anteriores — aqui ele deixa de ser número escrito e passa a ser
   aritmética da própria cascata, o que mantém o disco certo se o corpo do card mudar.
   `text-align:center` + `display:block` são os dois outros termos que a cascata imprime. */
.service-icon {
    flex: none;
    display: block;
    width: 1.8em;
    height: 1.8em;
    font-size: 50px;
    line-height: 1.8em;
    text-align: center;
    border-radius: 50%;
    color: var(--imass-white);
}

/* `inline-color-schemes.css`, disco por esquema: sch11 = `#202020`, sch6 = `#88619e`. O
   original pinta o disco com `box-shadow: 0 0 0 1em <cor> inset` sobre o holder de
   1,8em × 1,8em — sombra de 1em de spread sobre uma caixa de 1,8em cobre a caixa inteira,
   então é um fundo cheio; `background-color` é o equivalente exato e não paga o repaint da
   sombra. Declarado como desvio em `tokens.md`. */
.service--dark .service-icon {
    background-color: var(--imass-dark);
}

.service--primary .service-icon {
    background-color: var(--imass-primary);
}

.service-body {
    padding-left: 1em;                /* `padding: 0 0 0 1em` (`01-content_elements.crush.css:5063`) — 14px a 14 de corpo, 16px a 16 */
}

.service-title {
    /* `bt_bb_service_content_title` medido no vivo (18/10, 0.2a, `qa/service-tree`): a coluna
       resolve `font-size: 1.5625em` do corpo ⇒ **25px a ≥1200**, mas o `line-height` que ela
       imprime é **24px** — o VALOR USADO herdado do `body` (`1.5em` de 16px). O corpus não
       declara entrelinha aqui (`09-style.css:19490-19496` só família/peso/tamanho/entreletra;
       `01-content_elements.crush.css:5066-5070` só peso/tamanho/margem) e o nó original é um
       `div` (`9× <div class="bt_bb_service_content_title">` só na home congelada), fora das
       regras de `h1..h6`. A réplica emite `h3` (hierarquia de títulos), então a regra global
       de headings o alcança: depois do porte da task #54 ela dá `1.1` (27,5px) e `.4em` de
       `padding-bottom` (10px) — cada card ganharia +13,5px de altura. `inherit` devolve o
       valor usado do corpo nas três bandas (24 / 21 / 19,5) e o `padding:0` fecha o resto. */
    font-family: var(--imass-font-heading);
    font-size: 1.5625em;
    font-weight: 800;
    line-height: inherit;
    letter-spacing: -0.03em;
    color: var(--imass-text);
    margin: 0;
    padding: 0;
}

/* `inline-custom.css`: `<b>` do título é da marca, `<u>` é grafite — e nenhum sublinha. */
.service-title b {
    color: var(--imass-primary);
}

.service-title u {
    color: var(--imass-dark);
    text-decoration: none;
}

.service-text {
    /* corpo da coluna: medido 16px/24px a 1440 (`09-style.css:662` + `:669`) — herda do
       `body`, por isso não repete tamanho; só o forro de topo é próprio. */
    margin: 0;
    padding-top: 11.2px;         /* `padding-top: .7rem` de 09-style.css — `rem`, não `em`: vale 11,2 em toda banda */
}

/* `style_borderless` + `size_large` + sch4: `font-size:50px`, caixa `auto`, `line-height:1`,
   glifo `#88619e` sem disco (`inline-color-schemes.css`). A largura deixa de ser número:
   ela passa a ser o avanço da própria letraform, como no original. */
.service--borderless .service-icon {
    width: auto;
    height: auto;
    line-height: 1;
    background-color: transparent;
    color: var(--imass-primary);
}

/* a célula de headline da grade de features (§6.2: 3 colunas, 1ª célula é o título) */
.features-intro .section-title {
    margin: 0;
}

/* As duas linhas 4+4+4 da grade de features são `bt_bb_column_gap_45` ⇒ 45px de padding por
   lado em cada coluna = 90px entre textos (medido em home.html:2 linhas com a classe).

   ENTRELINHA: as duas `.bt_bb_row` do vivo são irmãs encostadas — a 1440 a 1ª vale `d=80 h=203,2`
   e a 2ª começa em `d=283,2`, exatamente 80+203,2 ⇒ vão 0. O vão visual é feito por outra coisa:
   cada coluna do corpus fecha com `bt_bb_separator bt_bb_border_style_none bt_bb_top_spacing_small
   bt_bb_bottom_spacing_normal`, ou seja **1em + 2em = 3em** (medido `m=16/32` a 16px de corpo e
   `m=14/28` a 14 — é a escada do separador, §6.19, não um trap). O censo do nó nessa faixa é
   **6 colunas, 5 separadoras**: a ÚLTIMA célula da faixa fecha sem, do mesmo jeito que
   `.split--bleed .grid-2 > .service:last-child` acima. Com 3em por célula e vão 0 a conta fecha
   no vivo nos dois regimes: a 1440 `max(132,155,2)+48 = 203,2` e `max(131,2+48, 155,2+48, 131,2)
   = 203,2` ⇒ faixa 406,4; empilhado a 992 `86+132+132+132+132+90 = 704` (a última célula vale só
   os 90 do ícone, sem os 42 da separadora). Nota de instrumento: as colunas do vivo usam
   `bt_bb_animation_fade_in zoom_out`, que escala 1,3 ⇒ o retângulo de borda de uma célula pega
   o quadro da animação (`203,2 × 1,3 = 264,1`) e inventa Δ; a caixa de layout (`offsetHeight`) é
   imune a transform, e é por ela que este porte foi medido. */
.features .grid-3 {
    column-gap: 90px;
    row-gap: 0;
}

.features .grid-3 > * {
    margin-bottom: 3em;
}

.features .grid-3 > :last-child {
    margin-bottom: 0;
}

/* --- Slider da home -------------------------------------------------------- */

.hero-slider {
    position: relative;
    overflow: hidden;
}

/* `adaptiveHeight: true` do `data-slick` (tokens.md §3c): a faixa tem a altura do slide
   ATIVO, não a do maior. Medido no vivo (`qa/hero-slides.json`, 11 bandas × s0/s2): a 591 a
   faixa vale 702,2 no slide 1 e 640,6 no slide 3 — com os quatro slides na mesma célula de
   grid a réplica ficava em 702,2 nos dois e o Δ de +61,6 (uma linha de título) ia para o
   rodapé da faixa, empurrando setas e dots. O porte é o mecanismo do slick: os inativos saem
   do fluxo (`position:absolute`, topo alinhado — `bt_bb_vertical_align_top`) e só o ativo dá
   altura; a transição de `height` em 600ms é o `$list.animate({height}, speed)` do plugin, e
   quem escreve o px é `initHeroSlider()` (auto não transiciona). */
.hero-track {
    position: relative;
    transition: height 600ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .hero-track {
        transition: none;
    }
}

/* Só o slide ativo está no fluxo (ver `.hero-track`); os outros ficam absolutos sobre o
   mesmo topo. O deslocamento de topo NÃO é forro de cabeçalho — a faixa nasce em y=0 (o
   header é `absolute` e sobrepõe) e quem desce o texto é a pilha de separadores do builder
   dentro da coluna, medida nó a nó em 0.2a (`qa/hero-slides.json`, 44 pares banda × slide):
     `bottom_spacing_extra_large` 16em  (12em ≤768, `09-style.css:22121`)
   + `bottom_spacing_normal` 2em, que só EXISTE de 993 para cima (`bt_bb_hidden_xs/_ms/_sm`)
   + `top_spacing_medium` 3,75em (3em ≤768, `09-style.css:22124`), colapsado com o anterior.
   Como os três são blocos vazios, o resultado é o MÁXIMO do par colapsado somado ao
   separador de topo: 19,75em ≥993, 16em 769–992, 12em ≤768 — sobre a base de `em` da banda
   (16px ≥1200 / 14px abaixo). Em px: 316 / 276,5 / 224 / 168, e o rodapé da faixa é o mesmo
   `extra_large` (256 / 224 / 168), não um `spacing-xl` nosso.
   `align-items:flex-start` é `bt_bb_vertical_align_top` declarado na coluna do congelado
   (`home.html`, `data-structure="7-5"`); centrado era o substituto do `min-height` antigo. */
.hero-slide {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: flex-start;
    font-size: var(--imass-builder-em);
    padding-top: calc(16em + 3.75em);
    padding-bottom: 16em;
    background-size: cover;
    background-position: 50% 100%;
    opacity: 0;
    visibility: hidden;
    /* `fade: true`, `speed: "600"`, `cssEase: "ease-out"` no `data-slick` de home.html.
       O `visibility` espera o fim do fade: com transição contínua ele trocaria no meio
       (50% de 600ms) e o slide entrante apareceria já com ~30% de opacidade. */
    transition: opacity 600ms ease-out, visibility 0s linear 600ms;
}

@media (min-width: 993px) {
    /* Nos slides 2 e 4 o 3º separador é `bottom_spacing_medium` (com `bt_bb_hidden_xs/_ms/_sm`),
       não `top_spacing_medium`: sem `margin-top` ele NÃO colapsa com o `bottom_spacing_normal`
       de 2em do nó anterior ⇒ o 2em soma em vez de ser engolido pelo máximo (`3,75em`).
       Congelado: `home.html` @235547 e @243054; vivo: `head.y` **348** ≥1200 e **304,5** em
       993–1199, contra 316/276,5 nos slides 1 e 3. Abaixo de 993 os dois separadores estão
       ocultos e as quatro faixas voltam a valer 16em — por isso a regra só existe nesta banda. */
    .hero-slide--sep_bottom {
        padding-top: calc(16em + 2em + 3.75em);
    }
}

@media (max-width: 992px) {
    /* Abaixo de 993 o separador de 2em está oculto (`bt_bb_hidden_sm`), então o par
       colapsado passa a ser max(16em, 3,75em) = 16em e o topo vale 224, não 276,5. */
    .hero-slide {
        padding-top: 16em;
    }
}

@media (max-width: 768px) {
    /* A escada `extra_large` cai para 12em e `top_spacing_medium` para 3em
       (`09-style.css:22121`/`:22124`, ambos dentro do MESMO `@media (max-width:768px)`),
       então max(12em, 3em) = 12em = 168px sobre a base de 14px. */
    .hero-slide {
        padding-top: 12em;
        padding-bottom: 12em;
    }
}

.hero-slide.is-active {
    /* único no fluxo ⇒ é ele que dá a altura da faixa (`adaptiveHeight`) */
    position: relative;
    opacity: 1;
    visibility: visible;
    transition: opacity 600ms ease-out, visibility 0s;
}

/* A coluna do texto é `data-width="7"` ⇒ 58,3333% e **largura total** de 992 para baixo
   (`01-content_elements.crush.css:124` dá a base, `:171` `@media (max-width:992px)` colapsa
   `data-width` 4–12 em 100%) — NÃO 1201, como esta regra dizia antes. Medido no vivo
   (`qa/hero-slides.json`): `flex-basis:58.3333%` a 1000/1100/1199, `100%` a 992.
   O `item_content` do original mede 1260px com 30px de padding (09-style.css,
   `.bt_bb_layout_wide … :not(.bt_bb_multiple_slides)`), ou seja, 1200 de caixa ⇒ 700px de
   coluna, 660px de texto com as valetas de 20px. Aqui a caixa é o `.container` de 1200 com
   14px de padding, então 58,3333% = 684px. */
.hero-content {
    width: 100%;
}

@media (min-width: 993px) {
    /* No original a coluna é `58,3333%` do `…_holder` que paga ±20px de valeta para fora
       do `.bt_bb_row` (1440: holder 100→1340 = 1240; `col-xxl-7` 723,3; tinta 683,3 =
       723,3 − 20 − 20). A réplica não tem o holder: a base é o `.container` (1200), então
       58,3333% = 700 e a caixa de tinta fica 16,67px mais larga — que é exatamente
       `40 × 5/12`, a fatia de valeta que sobraria na outra coluna. `calc()` devolve a tinta
       a 683,3 e o título do slide 0 volta a quebrar em 5 linhas a 1440. */
    .hero-content {
        width: calc(58.3333% - 16.667px);
    }

    /* Item (u): nos slides 2 e 4 a coluna de tinta é a SEGUNDA do row (ordem DOM do
       congelado: `col-xxl-5` @234961/@242470 antes da `col-xxl-7` @235151/@242660), então a
       tinta encosta na borda direita da caixa em vez da esquerda. Medido no vivo
       (`qa/hero-slides.json`): x da tinta 636,7 a 1440, 521,7 a 1200, 438,3 a 1000 — em todos
       os três casos exatamente `borda direita da caixa − 683,3/648,3/531,7`, ou seja, o
       espelhamento é alinhamento, não um deslocamento por banda. A ≤992 as duas colunas
       viram 100% e a de imagem tem altura 0, então a regra morre no ≥993. */
    .hero-slide--side_right .hero-content {
        margin-left: auto;
    }
}

.hero-eyebrow {
    /* Os quatro slides da home são `bt_bb_size_huge` (`qa/eyebrow-census.log` sobre
       `referencias/html/home.html`), então o superheadline vale 1,125rem com a mesma
       entrelinha em `_outside` — em `rem`, não em px: 18/18 · mb 10,8 a 1440 e
       14,4/18 · mb 8,64 a 320, ambos medidos no vivo. */
    font-family: var(--imass-font-eyebrow);
    font-size: 1.125rem;
    font-weight: 400;
    line-height: 1.125rem;
    color: var(--imass-text);
    margin: 0 0 .6em;
}

.hero-title {
    /* size_huge: 3,5rem entre 361 e 1399 (medido 56/61,6/−1,68 a 591px); a 360 para baixo o
       builder corta para 3rem — ver o bloco de ≤360 abaixo do próprio herói. */
    font-family: var(--imass-font-heading);
    font-size: 3.5rem;
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--imass-text);
    /* O vão título→botões do original é o separador `top_spacing_small` (1em) +
       `bottom_spacing_normal` (2em) sobre um bloco de altura zero: 14+28 = 42 a 591 e
       16+32 = 48 a 1440, ambos 3em da base da banda (`qa/hero-slides.json`).
       `calc()` com o token, não `em`, porque aqui `em` resolveria contra os 56/80px do
       próprio título. */
    margin: 0 0 calc(3 * var(--imass-builder-em));
    /* `padding:0` — o `<h1>` do slide é `.bt_bb_headline h1` no original, onde a folha do
       builder zera o `.4em` global (`09-style.css:9657-9666`); vivo `pb=0px` nos 4 títulos
       (`qa/h-styles-live-1440`). Sem esta linha o vão título→botões do gate do herói
       (log 38) ganharia 32px a 1440. */
    padding: 0;
}

@media (min-width: 1400px) {
    /* base da cascata do original acima do breakpoint responsivo */
    .hero-title {
        font-size: 5rem;
        line-height: 1.1;
    }
}

/* Corte de ≤360px do `size_huge` — `09-style.css:31037-31050`: título 3rem `!important` e
   superheadline/subheadline 0,9rem. Medido no vivo a 320 nos 4 slides (`qa/hero-ladder`):
   título 48px/52,8 e eyebrow 14,4/18 · mb 8,64, contra 56px e 18px em toda banda acima.
   Vive aqui, depois das regras do herói, porque `.hero-eyebrow`/`.hero-title` são declaradas
   abaixo do bloco de escada de ≤360 (§3.4) e um cortá-las lá não as alcançaria. */
@media (max-width: 360px) {
    .hero-eyebrow {
        font-size: .9rem;
    }

    .hero-title {
        font-size: 3rem;
    }
}

/* Os botões do herói são nós `.bt_bb_button` irmãos, não um flex container nosso:
   `bt_bb_align_left .bt_bb_button{float:left; margin-right:.5em}`
   (`01-content_elements.crush.css:3057`) e `.bt_bb_button{margin-bottom:.25em}` (`:3032`),
   ambos sobre a base da banda. Medido (`qa/hero-slides.json`): vão horizontal 8px a 1440 e
   7px ≤1199; e a caixa dos botões termina 4px/3,5px acima do separador de rodapé.
   `font-size` no `.btn` porque a réplica o dá 14px fixo (`--imass-font-size-base`), enquanto
   `bt_bb_size_normal{font-size:1em}` herda a base da banda ⇒ altura 52 ≥1200, 45,5 abaixo. */
.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: calc(.5 * var(--imass-builder-em));
    margin-bottom: calc(.25 * var(--imass-builder-em));
}

.hero-actions .btn {
    font-size: var(--imass-builder-em);
}

/* Setas — contrato do slider (`bt_bb_arrows_style_accent_light` +
   `bt_bb_arrows_position_bottom_right`; `arrows_size_normal` não tem regra, é a base):
   `09-style.css` `button.slick-arrow { width/height: 2,8125em; border-radius: 50%;
   font-size: 1em; line-height: 1; display: flex; justify-content/align-items: center;
   transition: 300ms ease all }` com `button.slick-arrow:before { font-size: 1,25rem }`,
   `…bottom_right button.slick-arrow { top: auto; bottom: 2em }`, `.slick-next { right: 1em }`
   e `.slick-prev { left: auto; right: 4,5em }`. A tinta sai de `#e94d65` (tema-pai e
   `accent_light`, com `!important`) e `inline-custom.css` — a ÚLTIMA folha — pinta
   **`#88619e`**, inclusive no hover; por isso o hover só levanta a pílula.
   `font-size` explícito é obrigatório: `<button>` não herda a fonte do documento (o UA
   stylesheet dá 13,33px) e sem ele os `em` abaixo renderizariam 37,5px.
   A `@media (max-width:1400px)` que esconde as setas da faixa larga é revertida pela regra
   mais específica de `bottom_right` (`display: flex !important`) ⇒ existem em toda banda. */
.hero-nav {
    position: absolute;
    top: auto;
    bottom: 2em;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.8125em;
    height: 2.8125em;
    padding: 0;
    border: none;
    border-radius: 50%;
    /* Medido no vivo (`qa/arrows.json`, 4 bandas): a fonte da seta é a BASE DA BANDA, não a
       do `body` — `1em` = 16px ≥1200 ⇒ caixa 45×45, `bottom:2em`=32, `right:1em`=16 e
       prev `right:4,5em`=72; abaixo, 14px ⇒ 39,375 / 28 / 14 / 63. Com `--imass-font-size-base`
       (14px fixo) a réplica só batia a 1199 para baixo. */
    font-size: var(--imass-builder-em);
    background-color: var(--imass-primary);
    color: var(--imass-white);
    cursor: pointer;
    transition: 300ms ease all;
}

.hero-nav--prev {
    left: auto;
    right: 4.5em;
}

.hero-nav--next {
    right: 1em;
}

.hero-nav:hover,
.hero-nav:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 -3px 0 0 rgba(24, 24, 24, .2) inset, 0 2px 10px rgba(0, 0, 0, .2);
}

.hero-nav svg {
    /* `1,25rem` — rem, não em: 20px em qualquer banda */
    width: 1.25rem;
    height: 1.25rem;
}

/* Dots — `.slick-dots` é `position:absolute; bottom:1em` em `01-content_elements.crush.css`
   e `09-style.css` sobe para `bottom: 1,25em` com `display:flex; justify-content:center`.
   Cada `li` é uma caixa **transparente** de `1em` quadrada com `margin: 0 3px` (passo de
   20px) e o desenho vem de dois filhos: a régua `:before { height:2px; background:
   currentColor; opacity:.2; transform:scaleX(.8) }` e o círculo `:after { inset:0;
   border-radius:50%; background:#e94d65 → #88619e (inline-custom.css); transform:scale(0) }`,
   ambos com `200ms ease all`. No hover a régua colapsa e o círculo entra em `scale(.8)`;
   no slide ativo a régua some e o círculo fica `scale(1)`. Os dots de 10px com borda
   branca da folha do plugin são superseded por essa cascata.
   Desvio declarado: `box-sizing: content-box` + `padding: 5px 0` amplia a caixa de toque
   para 24px de altura **sem** mover o desenho (`:after` usa `top/bottom: 5px`) e sem
   mudar o passo da linha; o `bottom` da fila compensa os 5px. */
.hero-dots {
    position: absolute;
    bottom: calc(1.25em - 5px);
    left: 0;
    right: 0;
    z-index: 2;
    display: flex;
    justify-content: center;
    margin: 0;
    padding: 0;
    /* Mesma base da banda das setas: no vivo a fila mede `font-size:16px` ≥1200 e `14px`
       abaixo, e o `bottom:1,25em` dela sai 20 / 17,5 respectivamente (`qa/arrows.json`). */
    font-size: var(--imass-builder-em);
    color: var(--imass-text);
}

.hero-dot {
    position: relative;
    box-sizing: content-box;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1em;
    height: 1em;
    margin: 0 3px;
    padding: 5px 0;
    border: 0;
    background: transparent;
    /* Caixa do dot é `1em` quadrada ⇒ 16×16 ≥1200 e 14×14 abaixo, como medido no vivo
       (`qa/arrows.json`); `<button>` não herda a fonte, então a base da banda entra aqui. */
    font-size: var(--imass-builder-em);
    color: inherit;   /* a régua é `currentColor`; sem isto o UA dá `buttontext` (0,0,0) ao botão */
    cursor: pointer;
}

.hero-dot::before {
    content: "";
    display: block;
    width: 100%;
    height: 2px;
    background: currentColor;
    opacity: .2;
    transform: scaleX(.8);
    transition: 200ms ease all;
}

.hero-dot::after {
    content: "";
    position: absolute;
    top: 5px;
    right: 0;
    bottom: 5px;
    left: 0;
    display: block;
    border-radius: 50%;
    background: var(--imass-primary);
    transform: scale(0);
    transition: 200ms ease all;
}

.hero-dot:hover::before,
.hero-dot:focus-visible::before {
    transform: scale(0);
    opacity: 0;
}

.hero-dot:hover::after,
.hero-dot:focus-visible::after {
    transform: scale(.8);
}

.hero-dot.is-active::before {
    transform: scale(0);
}

.hero-dot.is-active::after {
    transform: scale(1);
}

/* --- Linha de cabeçalho da faixa de artigos -------------------------------- */

/* A linha 6/6 de "ÚLTIMAS PUBLICAÇÕES" paga o vão pelo NÓ, não pela margem: cada
   `bt_bb_column_content` do corpus traz a separadora invisível
   `bt_bb_border_style_none bt_bb_bottom_spacing_medium` (3,75em, trap 3em ≤768 — §6.19) e o
   `bt_bb_headline` mede `mg=0/0` no vivo (18/10, `qa/band-tree.mjs`: célula 1 = 94,8+60 = 154,8 a
   1440; 71+52,5 = 123,5 a 992; 71+42 = 113 a 768). Então o `margin-bottom:40px` global de
   `.section-head` é neutralizado aqui e os 60px vêm do `<hr>` que a view emite — sem neutralizar,
   os dois somavam e a linha ficava em 194,8. */
.posts .section-head {
    margin-bottom: 0;
}

/* O invólucro do botão no builder (`01-content_elements.crush.css:3032`) leva `margin-bottom:
   .25em` — 4px a 16, 3,5 a 14. A faixa não imprime o invólucro (o `<a class="btn">` É o
   `bt_bb_link`, mapeamento de `theme.css` no fim do arquivo), então o pé mora no próprio link;
   sem ele a célula 2 media 112 contra 116 do vivo e o vão empilhado perdia 3,5. */
.posts .split-col--action .btn {
    margin-bottom: .25em;
}

/* --- Grade de artigos ------------------------------------------------------ */

/* Vão da grade = 1,25em nos dois eixos, e ZERO entre a linha de cabeçalho e a grade.
   Medido no vivo (18/10, `qa/posts-gap.mjs`): a segunda `.bt_bb_row` da faixa começa exatamente
   no `bot` da linha de cabeçalho em 1440 (2722=2722), 992 (3318=3318) e 768 (3093=3093) — o
   `margin-top:40px` anterior empurrava a grade para fora da cascata.
   O vão interno vem da folha do widget, não de `gap` de grid: em `09-style.css:25405` os itens
   `.bt_bb_gap_normal … .bt_bb_grid_item` levam `padding: 0 .625em 1.25em` e flutuam a 33,333333%
   (`01-content_elements.crush.css:5683`) com o contentor em `margin: 0 -.625em` (`:25399`).
   A conta fecha em grid: 3 × 386,67 + 2 × 20 = 1200 a 1440 (sangria de 10px do contentor é
   absorvida pelo recheio das células de borda) e o bleeding medido no vivo (x=110 w=1220 contra a
   faixa x=120 w=1200; 8,75px em 992) vale `.625em` nas bases 16/14, portanto o `em` aqui segue a
   escada do corpo (§6.4) como no original. */
.post-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.25em;
    margin-top: 0;
}

/* Anatomia do card, lida do próprio widget. O contêiner congelado em `home.html` é
   `.bt_bb_masonry_post_grid … bt_bb_look_image_below`, e "image below" não é ordem de fluxo:
   é camada. Em `09-style.css:25301-25317` a thumbnail vai a `position:absolute; left/top/
   right/bottom:0` e a imagem (`:25328-25336`) é centrada em tamanho natural por
   `left/top:50%` + `translate(-50%,-50%)` — sem recorte, sem `object-fit`. Por cima, o bloco
   de texto (`:25338-25351`) leva `padding:1.875em`, `min-height:22.5em`, `overflow:hidden`,
   `line-height:1.5` e, da regra base `:24620-24631`, `display:flex; flex-direction:column;
   justify-content:flex-end`; o `:after` (`:25352-25365`) é o véu `linear-gradient(to bottom,
   transparent 15%, #fff 50%)` a `opacity:.9` que mantém o texto legível sobre a foto, e os
   filhos vão a `z-index:10` (`:24632-24636`). O `min-height` é o que uniformiza a linha: é o
   bloco de texto que dita a altura do card, e a imagem — sendo camada — não soma nada.
   Removido daqui o `scale(1.04)` no hover que a réplica tinha: no post grid os pseudo-elementos
   de hover da thumbnail são `display:none` (`:24604-24612`) e não há regra de transform no `<img>`. */
.post-card {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Rodada 28 (pedido do operador: "tudo no tema é arredondado, menos os cantos dessas
       imagens"). O raio é o retangular da casa — os 20px de `.btAboutAuthor`
       (`btHardRoundedButtons`, `09-style.css:5085`); o `overflow:hidden` já existente clipa
       a camada de imagem e o véu do corpo ao retângulo arredondado. */
    border-radius: 20px;
}

.post-card-media {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: block;
}

/* DESVIO AUTORIZADO (relato do operador, item 4: "padronizar proporção das imagens"). O
   original centra a thumbnail em TAMANHO NATURAL (`left/top:50%` + `translate(-50%,-50%)`,
   sem recorte), o que medido na réplica dava proporções incoerentes na mesma linha: card 1
   `387×217` (16:9 limitado pela largura), card 2 SEM imagem (`btNoMedia`) e card 3 uma
   faixa de `296×77` flutuando no meio da caixa de 360px (`qa/cards-grid.log`). Aqui a
   imagem vira camada de recorte uniforme: preenche a caixa do card e é cortada por
   `object-fit:cover`, então toda capa tem a mesma proporção (a do card) e o véu branco do
   `.post-card-body` continua garantindo a legibilidade do texto por cima. */
.post-card-media img {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 50%;
}

.post-card-body {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
    min-height: 22.5em;
    padding: 1.875em;
    line-height: 1.5;
    color: var(--imass-text);
}

.post-card-body::after {
    content: "";
    display: block;
    position: absolute;
    top: 0;
    right: -1px;
    bottom: 0;
    left: 0;
    background: linear-gradient(to bottom, transparent 15%, #fff 50%);
    opacity: .9;
    pointer-events: none;
    z-index: 1;
}

.post-card-body > * {
    z-index: 10;
}

.post-card-body > :last-child {
    margin-bottom: 0;
}

/* Rodada 28: a linha de metadados (data + categorias) saiu dos cards da home a pedido do
   operador; as regras `.post-card-date`/`.post-card-meta`/`.post-card-category` que a
   rodada 26 criou foram removidas junto com o markup. */

.post-card-title {
    /* Cartaz da faixa "Artigos IMASS": a réplica promove a `h3` um título que no original é
       `h5.bt_bb_grid_item_post_title` — não há uma instância quer deste widget quer do
       `bt_bb_latest_posts_item_title` nas 11 páginas congeladas (censo 18/10: as ocorrências
       das duas classes são só dentro de `<style>` inline), então o que se porta daqui é a
       cascata, não um par medido. `padding:0` é a receita literal do original para esta
       classe (`01-content_elements.crush.css:5800-5805`: `font-size:1.4em; line-height:1.3;
       margin:0; padding:0`) — e é o indício de que o nó é heading: os `div` do builder
       (`.bt_bb_service_content_title`, `:5066`) zeram só a margem. O `letter-spacing` fica
       com a regra global (−,03em ⇒ −0,656px), como no original; `font-size`, `line-height` e
       o par de margens (10px/8px, ritmo medido do card) são próprios e vencem por classe —
       a divergência de margem contra `margin:0` do corpus fica registrada como item aberto. */
    font-family: var(--imass-font-heading);
    font-size: 21.875px;
    font-weight: 800;
    line-height: 26px;
    margin: 10px 0 8px;
    padding: 0;
}

.post-card-title a {
    color: var(--imass-text);
}

.post-card-title a:hover {
    color: var(--imass-primary);
}

.post-card-excerpt {
    /* O corte de 55 palavras é o medido na listagem (`Excerpt::teaser()`) e o widget da home
       não declara outro; o que o original limita é a CAIXA (`overflow:hidden` no bloco de
       texto). Como um resumo de 55 palavras passa dos 22,5em do card na coluna de 3 e
       desuniformizava a linha, o texto se limita a 4 linhas de 21px — reticência do próprio
       clamp. Desvio declarado: o grid da home é AJAX e o congelado não imprime nenhum card,
       então não há altura original nó a nó com que parear; vale o pedido do operador de
       alturas e resumos uniformes. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
    font-size: 14px;
    line-height: 21px;
    color: var(--imass-text-light);
    margin: 0 0 12px;
}

.posts-empty {
    margin: var(--imass-spacing-lg) 0 0;
    font-size: 15px;
    color: var(--imass-text-light);
}

/* --- Software / eSocial ---------------------------------------------------- */

/* O bloco de texto da linha é, no congelado, um `.bt_bb_text` com um `<blockquote>` e
   um `<ol>` irmãos — não um parágrafo solto. Medidas a 1440 (`qa/textblock-live`,
   corpo 16px): bloco [740 × 600 × 426,5]; blockquote fs=25 lh=32,5 caixa
   [740 × 600 × 242,5] com valeta 40/0/40/20; `<p>` interno [760 × 580 × 162,5] e sem
   margem; ol [756 × 584 × 184] com m=[0 0 16 16]; li [764 × 576 × 120] com m-l 8; ul
   aninhada [780 × 560 × 72] m=[0 0 16 16]; li-filho [788 × 552 × 24]. O `<blockquote>`
   e o vão de 1,3 do parágrafo vêm da regra global de citação (§ Base); aqui só a
   anatomia de lista do corpus, que a guarda (`ul,ol{padding-left:1.5em}`) não reproduce. */

/* `ul, ol { margin: 0 0 1em 1em; padding: 0 }` + `li { margin: 0 0 0 .5em }`
   (09-style.css:606-612, 619-622, 632-635). A guarda do tema dá `ul,ol{padding-left:1.5em}`
   ⇒ a caixa da lista sai 8px mais à esquerda no vivo e o texto cai no mesmo ponto
   (1em + .5em = 1,5em), mas a altura passa a ser a do box + vão, não do recheio.
   `ul ul { margin-bottom:0 }` (:610) NÃO cobre a lista aninhada de um `<ol>` — o seletor
   pede ancestral `ul` — por isso os três itens S-22xx fecham com 16px de vão e o segundo
   `<li>` do ol só começa em 3428,8 (medido). */
.software ol,
.software ul {
    margin: 0 0 1em 1em;
    padding: 0;
}

.software li {
    margin: 0 0 0 .5em;
    padding: 0;
}

/* --- Fundos de faixa (censo `data-background_image_src`, Fase 0) ------------
   As 11 páginas congeladas trazem 21 holders `.bt_bb_background_image_holder`;
   cinco deles carregam `bt_bb_parallax`. O holder é `absolute inset:0` sobre a
   section (01-content_elements.crush.css:1123-1143) e herda `cover`/`center` da
   section (crush.css:869-876), então a réplica pinta a foto no próprio elemento da
   faixa. Nenhum dos dois fundos da home leva véu: `::before` medido como
   `rgba(0,0,0,0)` nas duas faixas. */

/* Home: `bgn-team-2.jpg` SEM `bt_bb_parallax` (medido no vivo: holder sem a classe
   e sem `data-parallax`), ao contrário da mesma foto na faixa de contadores de
   /servicos, que tem velocidade 0,85. */
.services-split {
    background: url('/assets/themes/imass/img/backgrounds/bgn-team-2.jpg') 50% 50% / cover no-repeat;
}

/* --- Faixa de CTA ---------------------------------------------------------- */

/* `bgn-quote.jpg`, parallax 0,8 / offset 0 (seção `...897f7` da home congelada). */
.cta-band {
    text-align: center;
    background: url('/assets/themes/imass/img/backgrounds/bgn-quote.jpg') 50% 50% / cover no-repeat;
}

.cta-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 14px;
    margin-top: var(--imass-spacing-md);
}

/* O vão título→botão da faixa de CTA não é uma margem nossa: o corpus traz, dentro da
   `bt_bb_column col-xxl-12`, o `bt_bb_headline ... bt_bb_size_medium`, um
   `bt_bb_separator bt_bb_border_style_none bt_bb_bottom_spacing_normal` (= **2em**, a escada do
   separador §6.19) e o `bt_bb_button`, que em `01-content_elements.crush.css:3032` leva
   `margin-bottom:.25em`. Medido no vivo: vão 32 e pé 4 a 16px, vão 28 e pé 3,5 a 14px, dando
   conteúdo 69,6+32+52+4 = 157,6 a 1440 e 65,2+28+45,5+3,5 = 142,2 a 992. A réplica punha o par
   global `.section-head{margin-bottom:40px}` + `.cta-actions{margin-top:24px}` (colapsados no
   maior) e pé nenhum ⇒ +12 −3,5 = **+8,5 em todas as bandas** (+4,0 a ≥1200). Os dois `em`
   seguem a escada do corpo, então o porte vale nos dois regimes sem media query nova — e é
   escopado à faixa: `.section-head` a 40px continua certa nas outras faixas, que fecham Δh=0. */
.cta-band .section-head {
    margin-bottom: 2em;
}

.cta-band .cta-actions {
    margin-top: 0;
    margin-bottom: .25em;
}

/* --- Páginas de serviço (Fase 5) ------------------------------------------- */

/* O `padding` da faixa NÃO mora mais aqui: o padrão (`large` nos dois lados) e todos os
   degraus explícitos estão na família `:358-398`, onde um degrau declarado vence o padrão por
   ordem de documento — que é como o builder resolve (`09-style.css:10192-10229` só dá
   `padding` à faixa que CARREGA a classe; sem classe o pé é zero). */
.page-block {
    /* Âncora: o header fica sticky ao rolar e cobriria o título da área. */
    scroll-margin-top: calc(var(--imass-logo-height-sticky) + var(--imass-spacing-sm));
}

/* O header é transparente no topo (tokens.md §3a) e o `.btContentWrap` começa em y=0: no
   original NENHUM forro de banda paga o cabeçalho, quem o afasta é o próprio `8,75em` da
   faixa — medido 140 de forro contra 138 de header em 1440, ou seja, 2px de folga
   (`qa/sobre-top.mjs`). Por isso a primeira faixa NÃO leva termo de header em ≥768; o
   desvio declarado fica só no trap ≤767, abaixo. */

/* O título de uma área do original NÃO ocupa a largura da faixa: mora na 1ª coluna de uma
   linha `6+6` cuja 2ª coluna está VAZIA (`seguranca-do-trabalho.html` faixa 0: `row` →
   `col-xxl-6` do `bt_bb_headline` + `col-xxl-6` sem separadora nenhuma, que a 992/768 mede
   `offsetHeight` 0 porque a linha empilha). Medido `offsetWidth` da caixa do headline (imune
   ao `scale()` do reveal): **580 a 1440** e **550 a 1200/1199** (as metades de 1200/1140 menos
   os 40px da valeta de `20px` por lado) contra **932 / 708 / 531** de 992 para baixo, onde a
   coluna passa a ser a faixa toda. Consequência medida: com o corpo em 16 a escada do `h2` sobe
   para 60/66 e o título embrulha em TRÊS linhas (tinta 227 = 18 do olho + 198 do título) contra
   as duas da réplica de faixa cheia (161) — é o +66 por faixa de área que o censo da rodada 20
   achou SÓ em ≥1201, porque em 1260/1200/1199/992/768/591 os dois lados batem 113 (o pé cai
   para 42,24 e a metade continua bastando para duas linhas). A réplica paga a COLUNA, não o
   número: grade `6+6` com a tinta na primeira célula e a segunda inexistente no DOM, o mesmo
   precedente da separadora da faixa 0 de `/contato` (um `1em` pago por CSS em vez de marco
   vazio). */
.area-head {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--imass-column-gap);
    /* A separadora que fecha a coluna do headline é `bt_bb_border_style_none
       bt_bb_bottom_spacing_medium` = **3,75em** da escada do SEPARADOR (`09-style.css:22084`;
       `crush.css:3308` dava 4em e perde por ordem) — medido `mb=60` a 1440, `52,5` a 1199/992
       e `42` a 768/591, sempre sobre a escada do corpo, com o trap ≤768 cortando para `3em`
       (`:22117`). Não são os 40px do `.section-head` global. */
    margin-bottom: 3.75em;
}

@media (max-width: 992px) {
    .area-head {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 768px) {
    .area-head {
        margin-bottom: 3em;
    }
}

/* `bt_bb_column_gap_45` dá 45px de padding por lado em cada coluna ⇒ 90px entre textos;
   `bt_bb_column_gap_20` ⇒ 40px. Em grade, a valeta é o gap — sem sangria fora do container.
   O vão de LINHA é ZERO: linha alguma do builder tem vão vertical (medido nas três páginas de
   área, 1440/1199/992/768/591: `row2.top` = `row1.top` + `row1.height` exato) e quem separa as
   linhas é a separadora invisível `top_spacing_small` + `bottom_spacing_normal` =
   **1em + 2em = 3em** que fecha a célula (`09-style.css:22096` + `:22081`, a mesma escada do
   `medium` acima) — medido `m=16/32` a 1440 e `14/28` de 1199 para baixo, ou seja 48 / 42.
   As células que carregam a separadora são as do censo, não uma regra minha:
   - grade larga (2 linhas de 3): só a 1ª linha. A faixa 0 tem 4 separadoras (`medium` do
     headline + 3 × `small/normal`) para 6 colunas. No regime empilhado isso é visível nó a nó:
     a 992 as três primeiras colunas do vivo medem 132 (90 de tinta + 42) e as três últimas 90.
   - grade densa (2 linhas de 4): as 8 células. A faixa 2 mede 1ª linha 354 = 306 + 48 e 2ª 306
     = 258 + 48; a separadora da última linha entra ANTES do `padding-bottom: medium` (80) da
     faixa e é ela que fecha a tinta embaixo, por isso aqui não há exceção de cauda. */
.services-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    row-gap: 0;
    column-gap: 90px;
}

.services-grid--wide > * {
    margin-bottom: 3em;
}

.services-grid--wide > :nth-child(n+4) {
    margin-bottom: 0;
}

.services-grid--dense {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    row-gap: 0;
    column-gap: 40px;
}

.services-grid--dense > * {
    margin-bottom: 3em;
}

/* Variante medida nas grades de 4: `inline-flex` em coluna, ícone acima do texto, centro. */
.service--centered {
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.service--centered .service-icon {
    margin-bottom: 12.5px;
}

.service--centered .service-body {
    padding-left: 0;
}

/* Faixa de contadores de /servicos. No original é uma `<section>` IRMÃ das faixas de área —
   não um bloco dentro delas — e é isso que decide o ritmo: censo `seguranca-do-trabalho.html`
   = 4 faixas (`extra_large`/`large` da área, `large`/`large` + `margin-top:-4em` dos
   contadores, `—`/`medium` das grades de 4, `large` do ENDEREÇO), medidas no vivo a 1440 como
   `pt 256/pb 140`, `pt 140/pb 140` com `mt −64`, `pt 0/pb 80`, `pt 122,5`. O `−4em` é estilo
   inline do congelado em TODAS as três páginas e é escada do corpo, não número: `−64` a 1440,
   `−56` a 1199/992/768, `−52` a 360 (corpo 13). Ele sobrepõe o forro de `140` da faixa de cima
   em `64` porque é a FAIXA (com a foto em parallax) que sangra para dentro da anterior, nunca
   o conteúdo.
   Antes deste porte a réplica aninhava a faixa dentro do `.page-block` da área com
   `margin-top:-9px` e `padding:40px 0 140px` — dois números ajustados (o `40` de topo, que o
   vivo não tem: a 591 o forro do vivo é o próprio trap do degrau, `61,25`, e a 360 `56,88`).
   Os degraus agora vêm das classes da faixa (`band-top-large band-bottom-large` em
   `_counters.php`), que é também onde o `medium` da faixa densa passou a vencer o padrão. */
.counters-band {
    position: relative;
    margin-top: -4em;
    background: url('/assets/themes/imass/img/backgrounds/bgn-team-2.jpg') 50% 50% / cover no-repeat;
}

.counters {
    margin: 0;
}

/* A linha do headline da faixa de contadores fecha com separadora `bottom_spacing_normal`
   (= **2em**, `09-style.css:22081`), SEM gate nenhum: medido `mb=32` a 1440 e `28` de 1199
   para baixo, na coluna que vale em toda banda. Não são os 40px do `.section-head` global. */
.counters .section-head {
    margin-bottom: 2em;
}

.counters-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    /* Sem gap de linha: no original os retângulos das quatro colunas são contíguos
       (1228+191=1419, 1419+192=1611, 1611+131=1742) porque a valeta vertical é o
       separador `bt_bb_bottom_spacing_normal` (2em) DENTRO de cada coluna. */
    row-gap: 0;
    column-gap: 40px;
    text-align: center;
}

/* O censo da faixa de contadores tem 4 separadoras: a do headline (sempre visível) mais
   **3** nas colunas, carregadas de `bt_bb_hidden_md` + `bt_bb_hidden_lg` — a união das duas
   bandas (`01-content_elements.crush.css:845-861`) é `≥993`, e a réplica mede o mesmo no vivo:
   `display:none` com `mb=32` a 1440/1199 e `display:block` com `mb=28` a 992/768/591. Ou seja,
   a 1440 as quatro colunas fecham SEM valeta (linha `h=227` = só a tinta) e de 992 para baixo
   as três primeiras fecham com `2em` e a última não — é o par "última célula fecha sem" da
   grade larga, com o gate em cima. O porte sai do `padding-bottom: 28px` fixo (que existia
   nos dois regimes e em todas as quatro células) para `margin: 0 0 2em` nas três primeiras,
   desligado em ≥993. */
/* O censo dá a célula como `col-xxl-3 bt_bb_padding_double`: além da valeta da linha, o
   `.bt_bb_column_content` leva **20px por lado** (`01-content_elements.crush.css:1219`), e é
   isso que estreita a tinta do rótulo para **230px a 1440** (coluna 310 − 20/20 de coluna
   − 20/20 de content = 270; −20/20 = 230) e **491 a 591**. Sem este padding a réplica tinha
   270/531 de tinta: o rótulo "Documentos de Saúde e Segurança do Trabalho" embrulhava em
   duas linhas contra as três do vivo, e a régua/sub desciam — Δh +36 a 1440, +10 a 768,
   −16 a 360 antes deste porte (`qa/hl-pad.mjs`, 18/10). A grade mantém `column-gap: 40px`
   (a valeta `gap_20` da linha) ⇒ célula de 270 com 230 de tinta, exatamente o par do vivo. */
.counter {
    margin: 0;
    padding: 0 20px;
}

.counters-grid > .counter:nth-child(-n+3) {
    margin-bottom: 2em;
}

@media (min-width: 993px) {
    .counters-grid > .counter:nth-child(-n+3) {
        margin-bottom: 0;
    }
}

/* O valor é o holder `bt_bb_counter_holder.bt_bb_size_xlarge`, não um número:
   `09-style.css:22445-22469` dá `display:inline-block; height:1em; line-height:1` com
   `font-size: 3.75em` no degrau `xlarge` — e é ELE que vence a cascata (o `crush.css:8049`
   de `4em`/`1,2em` perde por ordem de documento, como nas outras famílias). O `em` resolve
   na escada do corpo: medido no vivo **60/60 a 1440**, **52,5/52,5 a 591** e **48,75 a 360**
   (`qa/count-live-cell.log`). O `52.5px` fixo que estava aqui era o valor de 1199 para baixo
   colado no desktop: a 1440 a réplica ficava 7px mais curta em cada célula (−36 na caixa da
   faixa) e o `px` não acompanha o trap de ≤360. */
.counter-value {
    margin: 0;
    font-family: var(--imass-font-heading);
    font-size: 3.75em;
    line-height: 1;
    height: 1em;
    overflow: hidden;
    font-weight: 200;
    color: var(--imass-primary);
    display: inline-block;
}

/* O vão valor→rótulo NÃO é margem: o holder é `inline-block` dentro de uma célula com
   `line-height:1,5` do corpo e a linha-box que o carrega sobra o descender do strut — medido
   **7px a 1440** (260 − 193 − 60) e **5px a 591** (713 − 655 − 53). Era o `13px` deduzido do
   bloco de 131px na rodada 14, quando o holder valia 52,5 também no desktop; com o `3.75em`
   de cima ele sai de graça, então o título fica no `margin:0` do `.section-title` global e
   dispensa tanto a margem quanto a raiz de BFC que a rodada 14 precisou para segurar os
   `.3em` de 7,5px da régua (agora `margin-bottom: 0` — sem margem inferior na última filha
   não há o que colapsar). */

/* Régua do rótulo — rodada 14, nono eixo. `tokens.md` §6.1 dizia "não há régua
   visível; não portar": leu só a cascata. O PNG congelado de 591px imprime as
   quatro. Em `06-seguranca-do-trabalho-591.png` (DPR 2, 1182×8524 = 591 CSS) há 4
   barras de 30,0×2 CSS px na cor da marca (device x 561–620 ⇒ CSS 280,5–310,
   centradas na página de 591) em y CSS 1329 / 1520,5 / 1711,5 / 1870 — as quatro
   `.bt_bb_headline.bt_bb_dash_bottom.bt_bb_size_small` da faixa. Largura =
   `1.875rem` do override `09-style.css:10124` (não os 4em da regra base).
   RODADA 20 REESCREVE OS VÃOS COM O DOM, não com o PNG: no vivo a régua é o `::after`
   do neto `.bt_bb_headline_content` e mede **`margin-top: 15px` (= `.6em` de 25) e
   nenhum `margin-bottom`**, e a sub-rúbrica é irmão do `<h4>` com **`margin-top: 18,2px`
   = `1,3em` da FONTE DELA (14px), por isso vale 18,2 nos dois regimes**
   (`qa/count-live-cell.log`: bloco do 4.º contador = 100 [três linhas 82,5 + 15 + 2]
   + 18,2 + 42 = 160,2, medido 160). A rodada 14 tinha repartido os mesmos 18,2 em
   `2 + 7,5 + 8,7` para casar o PNG com o holder de 52,5 que também estava errado; a
   aritmética nova fecha a caixa da faixa em Δ 0 e dispensa o `flow-root` do título. */
.counter-title::after {
    content: ' ';
    display: block;
    width: 1.875rem;
    margin: .6em auto 0;
    border-bottom: 2px solid var(--imass-primary);
}

.counter-sub {
    font-size: 14px;
    line-height: 21px;
    margin: 1.3em 0 0;
}

/* Borda da faixa tablet = 992px **inclusive**, medida na cascata congelada:
   `.bt_bb_column[data-width="N"]` → `@media (max-width:992px)` (`01-content_elements.crush.css`).
   Rodada 9, `referencias/tokens.md` §6.11. */
@media (max-width: 992px) {
    .grid-3,
    .split,
    .services-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Sem termo de linha: a valeta vertical continua sendo a separadora `3em` de cada célula
       (é ela que faz as três primeiras colunas do vivo medirem 132 contra 90 das três
       últimas, a 992). O `gap` de 40px daqui era um segundo vão SOMADO à separadora. */
    .services-grid {
        column-gap: var(--imass-column-gap);
    }

    /* As linhas de 4 colunas (`3-3-3-3`: contadores, cartões densos, rodapé) são as únicas
       que NÃO empilham de uma vez em 992 — `data-width="3"` cai para 50% nessa faixa e só
       vira 100% em 768. */
    .counters-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .services-grid--dense {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: 40px;
    }

    .split-col--action {
        text-align: left;
    }

    .split-col--media img {
        margin-left: 0;
    }

    /* O outro lado do par: a coluna de mídia com `bt_bb_align_right` continua com a foto
       encostada na DireITA da tinta abaixo de 993, só que agora a foto não preenche a coluna
       (a caixa dela é o natural de 817 e a coluna tem 892). Medido 18/10 (`qa/bleed-rows`,
       992): vivo img x=125 fim=942 contra tinta [50,892]; a réplica sem esta regra dava x=30.
       Vem depois da regra de cima porque `media` e `media-right` têm a mesma especificidade. */
    .split-col--media-right img {
        margin-left: auto;
    }

    /* `.grid-2` é a linha INTERNA 6+6 (os quatro cards de serviço da home), e o censo do
       builder é explícito sobre ela: `@media (max-width:992px)` dá `flex-basis:100%;
       max-width:100%` a `.bt_bb_column_inner[data-width="6"]`
       (`01-content_elements.crush.css:171-192`) — empilha em 992, não em 767. Confirmado no
       vivo (`qa/home-inner.mjs`, 992): as duas colunas internas de cada linha ficam em x=10
       uma e y = fim da outra, ou seja, os quatro cards viram UMA coluna. A réplica mantinha
       2×2 até 767 e por isso fechava Δh −116,9 (992) e −127,4 (768) na coluna em caixa. */
    .grid-2 {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 767px) {
    /* Rodada 18 (item s): este bloco tinha `.hero-title{font-size:2.5rem}` e
       `.hero-slide{min-height:560px}` — os dois eram muleta do `align-items:center` antigo,
       que precisava de uma altura mínima para não colapsar a faixa. O vivo mede 56px/61,6
       também a 591 (`qa/hero-slides.json`, 4 linhas de 61,6 = 246,4) e a altura da faixa é
       content-driven, então com o mecanismo portado as duas regras só estragavam. */

}

/* Empilha a **768px inclusive** — não é escolha nossa: `09-style.css`
   `@media (max-width:768px) { .bt_bb_column[data-width="3"], .bt_bb_column[data-width="2"] { flex-basis:100% } }`,
   e as colunas dos contadores e dos cartões densos carregam `data-width="3"`. 768px é largura CSS real
   (iPad em retrato), então a regra tem query própria em vez de morar no bloco ≤767 acima.
   Rodada 9: a nota anterior ("entre 769 e 1200 o original mantém 4 na linha") estava errada — a cascata
   resolve 25% até 993 e 50% de 992 para baixo; daqui segue exatamente isso.
   Caixa de texto do original a 591px = 551px (bordo direito x=571) contra 559px daqui — 8px, e o mais
   largo é o nosso; `tokens.md` §6.8. */
@media (max-width: 768px) {
    .counters-grid,
    .services-grid--dense {
        grid-template-columns: minmax(0, 1fr);
    }

    /* A grade de artigos NÃO empilha em 992 — empilha em 768 inclusive. Oráculo medido no vivo
       (18/10, `qa/posts-sizer.mjs`): o `.bt_bb_grid_sizer` do widget leva a mesma largura % dos
       `.bt_bb_grid_item` (`01-content_elements.crush.css:5683-5685`) e sobrevive no DOM mesmo com
       o AJAX morto, então ele conta as colunas que a folha impõe: 407/1220 (1440), 387/1160
       (1200), 316/950 (992) e 246/738 (780) = **3 colunas**; 726/726 (768) e 549/549 (591) = **1**.
       As duas folhas concordam: `crush:5711-5738` (`data-width="12"` → 100%) e
       `09-style.css:25419-25433` (`bt_bb_columns_3` → `flex-basis:100%`), ambas em
       `@media (max-width:768px)`. Antes desta virada a réplica empilhava `.post-grid` no bloco
       de 992 e dava 1 coluna entre 769 e 992 contra 3 do original. */
    .post-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* --- Clientes: carrossel de logos + depoimento (Fase 6) --------------------- */
/* Contrato em tokens.md §6.4: `slidesToShow` 4/3/2/1 nos breakpoints 993/769/481,
   autoplay 3000ms, transição 300ms ease-out, setas `size_large` (4,375em = 61,25px
   sobre a fonte 14px da coluna), glifo 2rem, `transparent_dark` (fundo zero, tinta
   #181818) e `position_outside` (−6em = −84px). */

/* O vão que separa o cabeçalho do carrossel NÃO é margem do `.section-head`: na linha 6+6 do
   original o headline é um `.bt_bb_headline` com `margin: 0` (medido `qa/headkids.mjs`) e o respiro
   vem dos dois separadores invisíveis de `2em` que o flanqueiam, contidos na coluna de grade.
   Com o par global de 40px ligado a coluna mediria 369,2 contra os 329,2 do vivo. */
.clientes-intro .section-head {
    margin-bottom: 0;
}

/* Widget sem vão próprio: no original a linha do slider é irmã da linha do cabeçalho e as duas
   ficam ENCOSTADAS (linha 1 em y=140 com 329,2 de altura, linha 2 em y=469 — `qa/tree.mjs`,
   18/10). O respiro que existia entre elas mora nos `2em` do separador de cauda, dentro da
   coluna. O `margin-top: 40px` que a réplica punha aqui somava 40 em /clientes (lá o vão
   colapsava com a grade, não com um separador) e em /sobre era engolido pelos 60px do sólido
   `medium` — ou seja: nunca foi medido, só disfarçado. */
.logo-carousel {
    position: relative;
}

/* `overflow:hidden` e NENHUM forro lateral: a trilha do original é a caixa cheia do
   `column_content` de 12 colunas. Medido no vivo (`qa/arrows-outside.mjs`, /sobre):
   `.slick-list` em x=120 w=1200 a 1440, x=30 w=1139 a 1199, w=932 a 992, w=708 a 768 — os
   `slide_to_show: 6` dão 200px de logo em ≥1200 e o `> img { width:100% }`
   (`09-style.css:20021-20023`) faz a altura de cada slide sair da ASPECTO × 200, que é o que
   paga a altura da linha (238 = o `Ritz_Leblon.jpg` natural 200×238). Os `padding: 0 68px`
   que a réplica punha aqui para abrigar as setas encolhiam a trilha para 1064 ⇒ logos de
   177,3, linha de 211 e faixa −27px mais baixa; e as setas NÃO precisam do vão: elas já vivem
   no sangramento, exatamente como no original, que em 1199 mede seta em x=−54 (fora do
   viewport) e em 1440 em x=24/1346. */
.logo-carousel__viewport {
    overflow: hidden;
}

.logo-carousel__track {
    display: flex;
    margin: 0;
    padding: 0;
    list-style: none;
    transition: transform 300ms ease-out;
}

.logo-slide {
    flex: 0 0 25%;
    max-width: 25%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.logo-slide__img {
    /* `width:100%` e nenhum teto de tamanho natural: a folha do builder põe
       `.bt_bb_slider .bt_bb_slider_item > img { width:100% }` (`09-style.css:20021-20023`) e o
       `object-fit: fill` do widget aceita ampliar. O teto de 300px que a réplica punha aqui
       (o natural mais comum, 300×114) só encostava na trilha em ≥1200 — abaixo disso a trilha
       passa dos 300 por slide e o teto encolhia a logo: a 992 a réplica media linha de 357
       contra 370,1 do vivo e a 768 357 contra 421,3, sempre 300×1,19 = 357 (`Ritz_Leblon`). */
    width: 100%;
    height: auto;
}

.logo-carousel__arrow {
    position: absolute;
    top: 50%;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 61.25px;
    height: 61.25px;
    margin-top: -30.625px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background-color: transparent;
    color: var(--imass-text);
    cursor: pointer;
    transition: all var(--imass-transition);
}

.logo-carousel__arrow svg {
    width: 32px;
    height: 32px;
}

.logo-carousel__arrow--prev {
    left: 0;
}

.logo-carousel__arrow--next {
    right: 0;
}

/* Hover do original usa o vermelho resíduo do tema-pai (#e94d65, tokens.md §1:
   não portar) — a réplica aplica a marca, como nos botões e nas setas da home. */
.logo-carousel__arrow:hover,
.logo-carousel__arrow:focus-visible {
    background-color: var(--imass-primary);
    color: var(--imass-white);
    transform: translateY(-3px);
}

@media (min-width: 1500px) {
    .logo-carousel__viewport {
        padding: 0;
    }

    .logo-carousel__arrow--prev {
        left: -84px;
    }

    .logo-carousel__arrow--next {
        right: -84px;
    }
}

/* Escada do carrossel: `data-slick` traz breakpoints 993/769/481, ou seja, uma acima de cada
   borda de faixa do builder (992/768/480) — leia "abaixo de". As queries abaixo usam as bordas
   INCLUSIVAS do builder, que é o que a cascata medida resolve; a fonte JS do slick não está no
   corpus congelado, então a semântica é inferida das faixas da grade, não lida. */
@media (max-width: 992px) {
    .logo-slide {
        flex-basis: 33.3333%;
        max-width: 33.3333%;
    }
}

@media (max-width: 768px) {
    .logo-slide {
        flex-basis: 50%;
        max-width: 50%;
    }
}

@media (max-width: 480px) {
    .logo-slide {
        flex-basis: 100%;
        max-width: 100%;
    }
}

.quote-band {
    position: relative;
    padding: var(--imass-band-spacing) 0;   /* .bt_bb_port: 122,5px desktop / 61,25px ≤768 */
    background: url('/assets/themes/imass/img/backgrounds/bgn-quote-2.jpg') 50% 50% / cover no-repeat;
}

/* Véu medido: section::before com content " " e rgba(255,255,255,.8), z-index 1. */
.quote-band::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background-color: rgba(255, 255, 255, .8);
}

.quote-band .container {
    position: relative;
    z-index: 2;
}

/* col-xxl-3 / col-xxl-6 / col-xxl-3: o depoimento vive na coluna do meio (600px). */
.quote-band__inner {
    max-width: 600px;
    margin: 0 auto;
}

/* A linha `3-6-3` de /clientes é a única 3-6-3 do corpus; nela `data-width="6"` cai a
   100% em ≤992, então o depoimento perde o teto de 600px e ocupa o container inteiro. */
@media (max-width: 992px) {
    .quote-band__inner {
        max-width: none;
    }
}

.quote {
    /* Coluna `bt_bb_align_center` ⇒ variante do corpus `blockquote{padding:1.6em 0}`
       (09-style.css:749-751), que tira os 0,8em laterais da forma base. O corpo da
       citação, o vão 1,3 e o pé zero do último filho vêm da regra global de blockquote. */
    padding: 1.6em 0;
    text-align: center;
}

.quote cite {
    font-style: normal;
    font-size: 20px;
    line-height: 26px;
}

/* ==========================================================================
   Contato (Fase 7) — contrato em tokens.md §6.6
   ========================================================================== */

/* Faixa 1: `top_spacing_large` + `bottom_spacing_medium` da ESCADA DE FAIXA
   (`09-style.css:10195-10229`, trap ≤768 em `:10287-10301`) = 140/80 a 16px e 61,25/42 a
   14px. Medido nó a nó no vivo e no congelado (`qa/topo-header.mjs`, 18/10): o `.bt_bb_port`
   da faixa vale `140px / 80px` em 1440 e `61,25px / 42px` em 768. O `42px` fixo que estava
   aqui era o valor do trap aplicado a toda largura — por isso a base da faixa media 42 em
   1440 contra 80 do vivo (`qa/faixa-ladder.mjs`). */
.contact-intro {
    padding: var(--imass-band-spacing) 0 var(--imass-band-spacing-medium);
}

/* Os 16px que separam o topo da página da faixa 1 NÃO são termo de header: no original é uma
   FAIXA PRÓPRIA, só com uma separadora invisível (`contato.html`, 1º `<section>` =
   `bt_bb_layout_boxed_1200` sem degrau nenhum, cujo único filho é
   `.bt_bb_separator.bt_bb_border_style_none.bt_bb_top_spacing_small` = `margin-top: 1em`,
   `09-style.css:22096`). Medido: a faixa seguinte nasce em y=16 (y=14 onde o corpo é 14) e a
   tinta do título em y=156 = 16 + 140, com o header absolute de 138 — ou seja, quem afasta o
   cabeçalho é a escada, exatamente como em `/sobre` (§1785). A réplica paga o mesmo `1em` no
   topo da faixa com `.bb-rule--top-small` (utilidade na família dos separadores, §2490) em vez
   de emitir uma landmark vazia; a tinta resultante é a mesma. */

/* `bt_bb_column_gap_30` = 30px de padding por lado ⇒ 60px entre as duas colunas. */
.contact-intro__row,
.contact-body__row {
    column-gap: 60px;
}

/* Coluna da headline: `vertical_align_middle`; coluna dos cartões: `vertical_align_bottom`. */
.contact-intro__row {
    align-items: end;
}

/* O `margin-bottom: 40px` global de `.section-head` (§733) é a nossa aproximação para a
   separadora invisível `top_spacing_small` + `bottom_spacing_normal` que fecha a coluna da
   headline no original. Com o nó porta-retrato em `.bb-rule--space`, o par seria 40 + 16/32
   = 88 e a linha ganharia 40 de fora; o `0` devolve a régua ao nó: 199,2 + 16 + 32 = 247,2. */
.contact-intro .section-head {
    margin-bottom: 0;
}

/* Linha interna `bt_bb_column_gap_40` medida: 20px de padding por lado em cada cartão.
   O vão ENTRE cartões empilhados não é do contentor (§902): cada uma das três colunas internas
   traz a MESMA separadora invisível `top_spacing_small` + `bottom_spacing_normal` — três nós
   depois de cada `.bt_bb_service` em `contato.html`, nenhum com gate `hidden_*` ⇒ 16+32 a corpo
   16 e 14+28 a corpo 14, sempre 3em. Por isso o `row-gap` é 0 e o par mora no card, como em
   `.split--bleed .grid-2 > .service` (§1045). A coluna fecha em 217,7 a 1440 = 169,7 do card mais
   alto + 48 do nó, e em 199,7 a 1199 = 157,7 + 42 (`qa/cards-tree.mjs`, 18/10). */
.contact-cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0 40px;
}

.contact-cards > .service {
    margin-bottom: 3em;
}

/* Faixa 2: só `bottom_spacing_large` + o triângulo decorativo do tema-pai. */
.contact-body {
    padding-bottom: var(--imass-band-spacing);
    background: url('/assets/themes/imass/img/backgrounds/bgn-triangle-red-right.png') 100% 68% / 12% no-repeat;
}

/* Mapa: `max-width:790px; margin-left:auto` sobre a coluna da esquerda.
   A imagem de cobertura fica no fluxo (z-index 2) e o mapa real viria por baixo
   (absoluto, inset 0, `height:auto !important`) — aqui ele só existe depois do clique. */
.map-cover {
    position: relative;
    max-width: 790px;
    margin-left: auto;
}

/* Camada de baixo: o mapa preenche a caixa que a cobertura em fluxo define. No original
   é `position:absolute; inset:0; height:auto !important` (09-style.css:21012-21024), e o
   `!important` existe justamente para anular o `style="height:776px"` impresso pelo
   builder no nó do mapa — altura que nunca chega a valer. Desde a troca do embed Google
   pelo Leaflet (ver contato/index.php) este nó é o contêiner `div` do mapa, não um
   `<iframe>`: `inset:0` + `height:100%` dá a ele a caixa que a moldura define, e o
   `invalidateSize()` no `load` realinha os tiles ao aspecto final. */
.map-cover__frame {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    border: 0;
    z-index: 1;
}

/* Camada de cima: moldura decorativa com janela orgânica, `pointer-events:none` para o
   clique atravessar para o mapa (09-style.css:20980-20995). */
.map-cover__matte {
    display: block;
    position: relative;
    width: 100%;
    height: auto;
    z-index: 2;
    pointer-events: none;
}

.contact-form__honeypot {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Formulário — o ritmo é o do corpus, em `em`, e **não** em px de uma banda. Medido 18/10 a 1440
   (`qa/col-tree`): linha 68px (campo 52 + 16 do `<p>`) + 10px da linha, e 61,5 + 8,75 a 1000 — ou
   seja, os dois números descem com o corpo. Antes desta nota a réplica tinha 45,5/8,75/14 px
   congelados na banda de 14, o que deixava /contato 59,5px mais curta em ≥1200.
   `.bt_bb_cf7_row{margin-bottom:.625em}` (`09-style.css:21699-21712`); no original a linha é um
   flex-item com padding lateral, então o `margin-bottom: 1em` do `<p>` que embrulha o campo não
   colapsa com o da linha — `flow-root` refaz essa caixa sem podar a sombra do foco. */
.contact-form__row {
    display: flow-root;
    margin-bottom: .625em;
}

/* No original todo conteúdo de linha vive num `<p>` com margin-bottom 1em — inclusive o submit.
   Sem isso a última linha ficaria 1em mais colada que as demais. */
.contact-form .btn {
    margin-bottom: 1em;
}

.contact-form input:not([type=hidden]),
.contact-form textarea {
    display: block;
    width: 100%;
    /* `height: 3.25em` + `line-height: 3.25` (`09-style.css:318-325`) e, por cima,
       `line-height: 1 !important` para os campos de texto e o `textarea`
       (`09-style.css:329-344`) ⇒ 52px a ≥1200, 45,5px a 14, 42,25px a 13. */
    height: 3.25em;
    /* `padding: 1.25em` (`09-style.css:254`) — 20px onde o corpo é 16 (medido no vivo). */
    padding: 1.25em;
    margin-bottom: 1em;          /* 1em do `<p>` que embrulha cada campo */
    font-family: var(--imass-font-body);
    /* O corpus não fixa corpo no campo: `font: inherit` (`09-style.css:245`) e a raiz do builder
       é o corpo da faixa. Declarar 14px aqui era o erro que somava os 6,5px × 5 campos + 15px do
       `textarea` em ≥1200. */
    line-height: 1;
    color: var(--imass-text);
    background-color: var(--imass-white);
    border: 1px solid rgba(24, 24, 24, .2);
    border-radius: 50px;
    outline: none;
    box-sizing: border-box;
    /* Rodada 16 (movimento): o framework anima os campos em `all 500ms ease`; a réplica
       tinha `var(--imass-transition)` = 300 ms. Os 500 ms entram no tempo; o escopo fica
       em borda+sombra (as duas propriedades que de fato mudam no foco), não `all`. */
    transition: border-color 500ms ease, box-shadow 500ms ease;
}

.contact-form textarea {
    /* `height:auto` (a folha dá 3,25em só para `input:not(checkbox|radio)` e `select`) ⇒ a caixa
       é `rows` × entrelinha + forro + borda: 5×16 + 40 + 2 = **122px a ≥1200**, 5×14 + 35 + 2 =
       107px na banda de 14 — os dois medidos no vivo (`qa/col-tree`, 1440 e 1000). */
    height: auto;
    border-radius: 26px;
    resize: vertical;
}

.contact-form input:not([type=hidden]):focus,
.contact-form textarea:focus {
    border-color: rgba(24, 24, 24, .4);
    box-shadow: 0 2px 10px 0 rgba(0, 0, 0, .12);
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
    color: rgba(24, 24, 24, .55);
    opacity: 1;
}

/* Utilitário: os campos do original só têm placeholder; os rótulos existem para leitor de tela. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Bandas estreitas: no original as duas linhas empilham (linhas `6-6` e `IN·4-4-4`
   da página /contato, ambas a 100% em `@media (max-width:992px)`) e a linha interna dos
   cartões mantém 690–742px (estouro). Aqui vira uma coluna só, sem estouro. */
@media (max-width: 992px) {
    .contact-intro__row,
    .contact-body__row {
        grid-template-columns: minmax(0, 1fr);
        column-gap: 0;
    }

    .contact-intro__row {
        align-items: start;
    }

    .contact-cards {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ==========================================================================
   Sobre (Fase 8) — contrato em tokens.md §6.5
   ========================================================================== */

/* Cada faixa de /sobre carrega UM só lado do espaçamento de banda, medido no vivo:
   `.bt_bb_port` da faixa 1 = `padding-top 61,25px / bottom 0` e o inverso na faixa 2
   (em desktop 122,5px pelos dois lados). A faixa 1 recorta a imagem de cobertura,
   como `.bt_bb_section_with_top_coverage_image` (09-style.css:10235). */
.page-block--top {
    position: relative;
    overflow: hidden;
    padding-top: var(--imass-band-spacing);
    padding-bottom: 0;
}

/* `.bt_bb_section_allow_content_outside > .bt_bb_port` fica acima da cobertura (z-index 3). */
.page-block--top > .container {
    position: relative;
    z-index: 2;
}

.page-block--bottom {
    padding-top: 0;
    padding-bottom: var(--imass-band-spacing);
}

/* O `margin-top` do primeiro nó de uma faixa NUNCA move a faixa. Motivo: o `.bt_bb_port` do
   builder é `display:flex` (`01-content_elements.crush.css:880-885`), item de flexão não
   colapsa margem com o pai, e a cadeia inteira (`cell > cell_inner > row_holder > column >
   column_content`) está dentro dele — medido no /sobre: a faixa 2 começa com 1em de separadora
   invisível e ainda assim cola na faixa 1 (`folga = −0,2`) com o sólido em `dy=76`
   (`qa/sobre-sep.mjs`, 18/10). Na réplica o contentor é bloco: com o `padding-top: 0` de
   `--bottom` o mesmo vão ESCAPIA e empurra a caixa da faixa — os 66,8px de folga que a rodada
   19 deixou em aberto e o censo da rodada 20 explicou. `flow-root` reproduz só a propriedade
   que importa do port: guarda os vãos dos filhos dentro da faixa e PRESERVA o colapso
   irmão-a-irmão, que o vivo também tem
   (1em+2em com 3,75em colapsado no maior = 76, não 108). */
.page-block > .container {
    display: flow-root;
}

/* Em ≥768 o forro da faixa é o `8,75em`/`4,375em` do builder, sem termo de header. Abaixo de
   768 o trap do original devolve `4,375em` = 61,25px e o título entra sob a barra móvel de 84px
   (defeito mobile declarado na página de planos) — aqui, e SÓ aqui, o header tem prioridade:
   `84 + 24` = 108px, o valor que a réplica media antes quando esta regra valia para todas as
   bandas. Medido a 591px em 18/10 (`qa/bandas.mjs`, topo da tinta = 108 × 61,3 do vivo).
   O `:not()` entra no censo da rodada 20: a faixa de abertura das páginas de área
   (`/servicos`) é `extra_large` = `12em` do trap ≤768, e 12em vale **168px a 591** e **156 a
   360** — bem acima da barra de 84, logo não há defeito a corrigir ali e o degrau do builder
   é que manda. Substituir por 108 inventava −60px de Δh na primeira faixa (medido no vivo
   `pt 168 / 156` × réplica `108`). A regra só pode operar onde o trap é MENOR que a barra. */
@media (max-width: 767px) {
    main > .page-block:first-child:not(.band-top-extra-large),
    main > .page-block--top:first-child,
    main > .contact-intro:first-child {
        padding-top: calc(var(--imass-header-box) + var(--imass-spacing-md));
    }
}

/* Cobertura do topo: absoluta, `top:-1px`, largura total e altura natural
   (medido a 591px: 591×159 para o PNG de 2500×673). */
.band-coverage {
    position: absolute;
    top: -1px;
    right: 0;
    left: 0;
    z-index: 1;
    display: block;
    width: 100%;
    height: auto;
    pointer-events: none;
    user-select: none;
}

/* Separador do builder: 2px sólidos rgba(24,24,24,.1) (medido `border-bottom`) com a escala
   de espaçamento de 09-style.css:22075-22110 — `normal` = 2em, `medium` = 3,75em (28px e
   52,5px ONDE O CORPO É 14; 32px e 60px onde é 16); o trap ≤768 corta `medium` para 3em
   (22114-22132) e não toca `normal`.
   Os separadores invisíveis da mesma linha entram como margem, porque linha alguma do
   builder tem vão vertical: medido linha→CTA = 52,5 + 28 = 80,5px exatos no vivo. */
.bb-rule {
    height: 0;
    /* separador sólido do builder com `top_spacing_normal` + `bottom_spacing_normal` =
       2em + 2em (`01-content_elements.crush.css:3302`): 28px quando o corpo é 14, **32px
       quando é 16** — medido 32/32 a 1440 em /sobre (`qa/textcol-1440-live`). */
    margin: 2em 0;
    border: 0;
    border-bottom: 2px solid rgba(24, 24, 24, .1);
}

/* Régua curta inline do `bt_bb_text` da home (linha 1): o próprio HTML do original traz
   `border-color:#b73235; width:100px; margin-left:1.25rem; border-width:4px` e a classe
   `bt_bb_bottom_spacing_medium` — medida a 1440 como caixa [759,6 × 100,1 × 4] com
   `margin: 0 0 60px 20px` (`qa/textblock-live`). O pé é `3,75em` da escala do separador
   (`09-style.css:22084`, que por ordem de documento vence os `4em` de
   `01-content_elements.crush.css:3308`), não 60px: 60 onde o corpo é 16 e 52,5 onde é 14 —
   o Δh de +7,5px que a linha 1 da home tinha em 1199/1000 (e zero em ≥1200) eram exatamente
   os 60px fixos (`qa/bleed-rows-compare`, 18/10). O recuo fica em `rem` porque é inline no
   HTML e `rem` nunca segue a escada do corpo (§3c.1). O trap ≤768 também o alcança: o nó
   congela com `bt_bb_bottom_spacing_medium` (`home.html`, @267449, imediatamente antes da
   separadora invisível da mesma coluna), então o pé é 3em = 42px e não 52,5 abaixo de 768 —
   os 10,5px de diferença eram o único motivo de a célula 1/1 medir −31,5 (não −42) em 768/591
   antes de os dois mecanismos entrarem. */
.bb-rule--accent {
    width: 100px;
    margin: 0 0 3.75em 1.25rem;
    border-bottom-width: 4px;
    border-bottom-color: #b73235;
}

@media (max-width: 768px) {
    .bb-rule--accent {
        margin-bottom: 3em;
    }
}

/* `medium` = 3,75em (`09-style.css:22084`; a folha do builder dava 4em em `crush:3308` e
   perde por ordem), com o trap de `@media (max-width:768px)` que corta para 3em
   (`09-style.css:22114-22132`). Em `em`, porque o valor é 60px a 16, 52,5 a 14 e 39 a 13 —
   fixar 52,5/42 em px errava as três bandas. A borda do trap é 768, não 767: é a borda
   escrita na folha (`22114`), e a banda 768 está no gate de `qa/bleed-rows.mjs`. */
.bb-rule--medium {
    margin: 3.75em 0;
}

@media (max-width: 768px) {
    .bb-rule--medium {
        margin: 3em 0;
    }
}

/* Separador **invisível** (`border_style_none`) com `top_spacing_small` + `bottom_spacing_normal`
   = 1em + 2em (`09-style.css:22096` e `:22081`) — 16+32 = 48px a ≥1200, 14+28 = 42 abaixo. Dois
   nós do congelado têm exatamente essa escada: o nó líder da coluna do formulário em /contato
   (`referencias/html/contato.html`, antes de `.bt_bb_contact_form_7`) e o nó que FECHA a coluna
   da headline da faixa 1 (`contato.html`, depois de `.bt_bb_headline`; medido no vivo a 1440 como
   `y=371,2 m=16/32 h=0`, e é ele que leva a coluna de 239,2 para os 247,2 da linha
   — `qa/intro-tree.mjs`, 18/10). Aquele primeiro nó das 4 faixas em /contato soma as classes
   `bt_bb_hidden_xs/_ms/_sm` (`crush.css:827-845`: ≤480, 481-768, 769-992), que somem com o
   separador até 992 — visível só de 993 para cima, exatamente onde a coluna volta a ser de 600;
   o da headline NÃO tem gate nenhum e vale em toda banda. Por isso o gate saiu desta utilidade e
   virou `.bb-rule--hidden-xs-ms-sm` abaixo: a escada é uma coisa, a banda é outra.
   A classe-base `.bb-rule` já traz `height: 0` e `border: 0`, por isso o par em `hr` só precisa
   desligar a borda de baixo. */
.bb-rule--space {
    border-bottom: 0;
    margin: 1em 0 2em;
}

/* Gate literal dos três nós `hidden_xs` + `hidden_ms` + `hidden_sm` do congelado: a união das
   três bandas é ≤992, então o nó só existe de 993 para cima. */
.bb-rule--hidden-xs-ms-sm {
    display: none;
}

@media (min-width: 993px) {
    .bb-rule--hidden-xs-ms-sm {
        display: block;
    }
}

/* Separadora invisível com UM só lado: `border_style_none` + `top_spacing_small` =
   `margin-top: 1em` (`09-style.css:22096`), sem pé. É o nó líder da faixa 0 de /contato
   (ver §2183). O trap ≤768 da escada (`:22114-22132`) corta `medium`, `large` e
   `extra_large` e não toca `small`, então 1em vale 16px onde o corpo é 16 e 14px onde é 14 —
   medido no vivo como o y da faixa seguinte (16 em 1440, 14 em 768). */
.bb-rule--top-small {
    border-bottom: 0;
    margin: 1em 0 0;
}

/* Os DOIS separadores invisíveis da coluna em caixa do /sobre (`border_style_none` +
   `bottom_spacing_normal` = `margin-bottom: 2em`, `09-style.css:22081`) trazem as classes
   `bt_bb_hidden_md` + `bt_bb_hidden_lg` do congelado (`sobre.html`, nós @232030 e @233994). Ao
   contrário do `--space` acima, que carrega `hidden_xs/_ms/_sm` e só existe de 993 para cima,
   ESTES só existem de 992 para baixo: `hidden_md` some em 993–1200 e `hidden_lg` em 1201–1400 e
   ≥1401 (`01-content_elements.crush.css:845-861`) — a união é exatamente `≥993`. Medido no vivo
   (`qa/coltree.mjs`, 992): o primeiro mora DENTRO da primeira coluna interna, depois do `<ul>`,
   e é o que faz aquela coluna ter 203 contra 175 da segunda; o segundo é o último filho da
   coluna em caixa e é a cauda de 28px abaixo dos ícones (`bottom` da coluna = 842,9 contra 814,9
   dos ícones). Sem eles a réplica fechava Δh −16 nas bandas empilhadas. O gate deste nó
   (`bt_bb_hidden_md` + `bt_bb_hidden_lg`) está na utilidade `.bb-rule--hidden-md-lg` abaixo. */
.bb-rule--void {
    border-bottom: 0;
    margin: 0 0 2em;
}

/* Gate literal do separador: são as classes `bt_bb_hidden_*` do congelado, que o builder resolve
   por banda (`01-content_elements.crush.css:845-861`: `_xs` ≤480, `_ms` 481-768, `_sm` 769-992,
   `_md` 993-1200, `_lg` ≥1201). `--hidden-md-lg` ⇒ some de 993 para cima (as duas linhas em
   caixa da home e os separadores de `2em` do /sobre); `--hidden-sm-md-lg` ⇒ some de 769 para
   cima (a cauda da coluna de mídia do /sobre). A escada (`--void`, `--void-medium`) é independente
   do gate: um nó pode trocar de pé sem trocar de banda. */
.bb-rule--hidden-md-lg,
.bb-rule--hidden-sm-md-lg {
    display: none;
}

@media (max-width: 992px) {
    .bb-rule--hidden-md-lg {
        display: block;
    }
}

@media (max-width: 768px) {
    .bb-rule--hidden-sm-md-lg {
        display: block;
    }
}

/* Terceiro separador invisível do /sobre, este na COLUNA DE MÍDIA (`sobre.html`, nó @235434,
   último filho de `.bt_bb_column_content`, depois do `<span>` da foto). É
   `border_style_none` + `bottom_spacing_medium` = **3,75em** (`09-style.css:22084`, que vence os
   4em de `crush:3308` por ordem) com trap de `@media (max-width:768px)` para **3em**
   (`:22114`), e carrega `bt_bb_hidden_sm` + `_md` + `_lg` (`01-content_elements.crush.css:845-861`:
   769-992, 993-1200, ≥1201) — a união é `≥769`, então ele **só existe de 768 para baixo**, ao
   contrário do `--void` acima (992) e do `--space` (993). Medido no vivo (`qa/sobre-media.mjs`,
   768): a coluna tem 738,9 contra 696,9 da foto e o nó é `h=0, mg=0/42`; a 992 o vivo mede 800
   contra 800 da foto, sem cauda — exatamente a banda em que ele some. Os 42px entram na altura
   porque `.bt_bb_column` é `display:flex; flex-flow:column` (`crush.css:1196-1201`) e o
   `.bt_bb_column_content` é item de flexão, ou seja, formatação independente: a margem do último
   filho NÃO colapsa para fora. Na réplica o `grid item` tem a mesma propriedade. A escada é a
   mesma das linhas em caixa da home, que carregam só `hidden_md`+`_lg` (visível até 992, com o
   pé de 52,5px nas bandas 769-992): o que muda entre os dois é o gate, não o tamanho. */
.bb-rule--void-medium {
    border-bottom: 0;
    margin: 0 0 3.75em;
}

@media (max-width: 768px) {
    .bb-rule--void-medium {
        margin-bottom: 3em;
    }
}

/* `bottom_spacing_large` da escada do separador = **8,75em** (`09-style.css:22087`) com o trap
   ≤768 em `4,375em` (`:22120`). Coincide com o degrau `large` da escada de FAIXA por construção
   (as duas folhas nomeiam o mesmo `8,75em`; o que as separa é o `medium`, 3,75em aqui contra
   5em na faixa). Uso medido no censo da rodada 20: a faixa densa de `seguranca-do-trabalho`
   NÃO tem degrau de topo (`pt=0` em toda banda) e abre com uma linha `col-xxl-12` cujo único
   filho é esta separadora, carregada de `hidden_xs`+`_ms`+`_sm` ⇒ `display:block` com
   `mb=140` a 1440 e `122,5` a 1199, `display:none` a 992/768/591. É ela, e não o `padding` da
   faixa, que produz os 280px de vão entre a última tinta dos contadores e o primeiro cartão
   denso em ≥993. O trap ≤768 entra por coerência de vocabulário; com o gate, nenhuma banda em
   que ele vale o alcança. */
.bb-rule--void-large {
    border-bottom: 0;
    margin: 0 0 8.75em;
}

@media (max-width: 768px) {
    .bb-rule--void-large {
        margin-bottom: 4.375em;
    }
}

/* --- Faixa 1: texto + lista de etapas / lista de diferenciais ---------------- */

/* linha interna 6+6 sem classe de valeta ⇒ 40px entre as duas colunas de lista. O `row-gap` é
   ZERO porque a valeta do builder é de COLUNA (`padding: 0 20px` em cada `.bt_bb_column`,
   `crush.css:1195`) e não de linha: medido no vivo em 992/768/591 as duas colunas empilham
   ENCOSTADAS (`y` da segunda = `bottom` da primeira, `qa/coltree.mjs`), e o `gap:40px` de grade
   soma 40px onde o original não soma nenhum — um dos dois mecanismos do Δh −16 da coluna em
   caixa do /sobre (o outro são os separadores invisíveis de `2em`, `.bb-rule--void`). */
.sobre-steps {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--imass-column-gap);
}

/* Empilha no mesmo corte de 992px das demais linhas de coluna do builder
   (`.bt_bb_column[data-width]` → `@media (max-width:992px)`). Precisa vir DEPOIS
   da definição acima: media query não soma especificidade, então a ordem de fonte decide. */
@media (max-width: 992px) {
    .sobre-steps {
        grid-template-columns: minmax(0, 1fr);
    }
}

.sobre-list {
    /* `ul { margin: 0 0 1em 1em; padding: 0 }` (09-style.css:606) sobre o corpo DA BANDA:
       14px onde o corpo é 14, 16px onde é 16 (medido `ul` a 1440 = m 0/16/16/16,
       `qa/textblock-live`). */
    margin: 0 0 1em 1em;
    padding: 0;
}

.sobre-list li {
    margin-left: .5em;           /* `li { margin: 0 0 0 .5em }` (09-style.css:632) — 8px a 16 */
}

/* --- Faixa 2: separador, carrossel, CTA e o trio institucional --------------- */

.sobre-marcas {
    /* Holder medido: `.bt_bb_background_image_holder` absoluto (crush.css:1123-1143) herdando
       o `background-position:center; background-size:contain` inline da section. */
    background: url('/assets/themes/imass/img/backgrounds/bgn-lines.png') 50% 50% / contain no-repeat;
}

/* Os separadores de faixa 2 mora na coluna do meio de uma linha 4+4+4, e a valeta do builder
   é de COLUNA (`padding: 0 20px` em cada `.bt_bb_column`, `crush.css:1195`) ⇒ a caixa útil de
   cada terço é `(100% − 2×valeta)/3`, a mesma expressão do `.grid-3` logo abaixo. Medido no
   vivo a 1440: separadora de **373,3px** (`qa/b2-sep.mjs`); a fórmula anterior,
   `(100% − 40px)/3`, dava 386,7 — 13,4px de régua porque descontava a valeta uma vez só em
   vez de uma vez por coluna. */
.sobre-marcas .bb-rule {
    width: calc((100% - 2 * var(--imass-column-gap)) / 3);
    margin-left: auto;
    margin-right: auto;
}

/* 6 por linha no desktop: `slidesToShow: 6` do `data-slick` medido em /sobre, com a mesma
   escada de /clientes (≤992 → 3, ≤768 → 2, ≤480 → 1). O modificador só vale a partir de 993
   — a borda da faixa desktop medida na grade é 993, e abaixo dela quem manda é a escada. */
@media (min-width: 993px) {
    .logo-carousel--six .logo-slide {
        flex-basis: 16.6667%;
        max-width: 16.6667%;
    }
}

.sobre-cta {
    max-width: calc(100% * 7 / 12);   /* col-xxl-7 medida; a coluna 5 do par está vazia */
}

/* A linha `7-5` de /sobre empilha em ≤992 (`data-width="7"` → 100% na cascata), então o
   CTA deixa de ser 58,33% e passa a ocupar a linha toda. */
@media (max-width: 992px) {
    .sobre-cta {
        max-width: none;
    }
}

.sobre-cta .section-head {
    margin-bottom: 28px;              /* separador `bottom_spacing_normal` dentro da coluna */
}

/* Coluna 1: citação + lede de 18px dentro de um <span>. A caixa da citação (1,5625em do
   corpo, valeta 1,6em/0,8em, vão 1,3, último filho sem pé) vem da regra global de
   blockquote (§ Base) — não há nada a declarar aqui além da cor herdada do corpo. */
.sobre-lede {
    margin: 8.75px 0 0;                 /* separador invisível `extra_small` = .625em */
    font-size: 18px;
    line-height: 21px;                  /* herda o line-height usado do corpo (px, não unitless) */
}

/* Coluna 2: Missão / Visão / Valores — 18px com margin-bottom de 1em próprio (18px medido). */
.sobre-mvv {
    margin: 0 0 18px;
    font-size: 18px;
    line-height: 21px;
}

/* Coluna 3: parágrafo final (último do bloco ⇒ sem 1em) + o vão de 8,75px até a foto. */
.sobre-especialistas {
    margin: 0 0 8.75px;
}

/* Fila social do fim da coluna em caixa do `/sobre` — superfície que o `bleed-rows` do log 40
   media como Δ`h` −50 em TODA banda ≥1200. Não era desvio de espaçamento: a réplica não emitia
   os quatro `.bt_bb_icon` que o original põe depois da segunda régua. Medido no vivo 18/10
   (`qa/sobre-icons.mjs`, 1440): caixas 58×50 em x = 100/158/216/274 (passo 58 = círculo de 50 +
   `padding-right:.5em` de 16px), invólucro `a.bt_bb_icon_holder` 50×50 SEM fundo, e o disco é o
   glifo: `:before` 50×50, raio 50%, `font-size:25px` (`09-style.css:18612-18615`:
   `bt_bb_size_small` ⇒ `width/height:2em`), traço branco e `box-shadow: <cor da rede> 0 0 0 25px
   inset` — ou seja, aqui a tinta é a MARCA (`#3b5998` facebook, `#dc4e40` google+, `#bd081b`
   pinterest, `#007bb5` linkedin), não o roxo do rodapé. O rodapé usa o esquema 6 com o par
   `--icon-*` (`tokens.md` §3b.4); esta fila usa as classes `.btIco*`, as mesmas da coluna de
   compartilhamento de artigo, e portanto as regras globais de pintura já existem (o bloco
   `.btIco…bt_bb_style_filled .bt_bb_icon_holder:before` da seção Artigos, com a régua do corpus
   em `01-content_elements.crush.css:3005-3011`) — abaixo só o fluxo e a geometria. Desde 19/10 o
   glifo daqui É a letraform FontAwesome (`Icon::fontAttr` no holder vazio, `assets/css/fonts.css`
   faz o `content`), e não mais um `<svg>`: com SVG a caixa fechava em 50×50 e a tinta não. As
   âncoras
   originais são `href="#"` e uma das redes é o Google+ (morto desde 2019): a fila é portada com
   a MESMA fonte dinâmica do rodapé, item (f). */
.sobre-social {
    display: flex;
    flex-wrap: wrap;
}

.sobre-social .bt_bb_icon {
    display: flex;
    line-height: 1;
    /* O vão NÃO é `gap`: é `padding-right: .5em` do próprio widget (`crush.css:2811-2816`),
       então ele encolhe com a base da banda — 8px onde o corpo é 16 (≥1200) e **7px** onde é 14,
       que é o passo 57 medido no vivo em 992 (`x` = 30/87/144/201) contra o 58 de ≥1200
       (`x` = 100/158/216/274). Com `gap: 8px` fixo a réplica derrapava 1/2/3px na banda estreita. */
    padding-right: .5em;
}

/* Invólucro e disco separados como no congelado: o `a.bt_bb_icon_holder` é o flex que segura o
   par (glifo, rótulo) — `crush.css:2911-2921` — e quem tem caixa de círculo é o `:before` dele
   (`:2922-2944`, `09-style.css:18612-18615`: `size_small` ⇒ `font-size:25px; width/height:2em`).
   Por isso o `font-size` do glifo mora no `:before`: é sobre ele que os `2em` da caixa e o `1em`
   do `box-shadow` da marca resolvem, e é ele que decide a tinta do desenho. */
.sobre-social .bt_bb_icon a.bt_bb_icon_holder {
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    line-height: inherit;
    text-decoration: none;
    box-shadow: none;
}

.sobre-social .bt_bb_icon a.bt_bb_icon_holder:before {
    display: flex;
    order: 1;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: center;
    line-height: normal;
    font-size: 25px;                  /* a base do `2em` do glifo e do anel de `1em` */
    width: 2em;                       /* 50px, como o `:before` do builder */
    height: 2em;
    border-radius: 50%;
    color: #fff;
    transition: all 280ms ease;
}

/* O hover não é reescrito aqui: as regras globais das `.btIco*` preenchidas (bloco da seção
   Artigos, `09-style.css:18896-18940`) já valem para esta fila — disco encolhe para anel de 2px
   e o traço assume a cor da rede. */

.sobre-photo {
    display: block;
    width: 100%;
    height: auto;
    /* `shape_hard-rounded` do builder é `border-radius: 50%` (crush.css:4618-4628), não
       cantão arredondado: num 1280×854 o recorte sai como elipse — é o que o desktop
       original mostra (medido `border-radius: 50%` no vivo). */
    border-radius: 50%;
}

/* ==========================================================================
   Artigos (Fase 9) — `/artigos`, arquivos de categoria/tag e post individual

   A faixa de artigos NÃO é uma `bt_bb_section` do builder: não há container de
   1200px. O fundo cinza (`wp-custom-css`: `.blog .btContentWrap, .single-post
   .btContentWrap, .archive .btContentWrap { background: #f6f6f6 }`) é full-bleed e
   quem manda na largura do texto é a valeta `.gutter > .port` (1260px) com o
   padding global `.port { padding: 40px 60px 30px }` (wp-custom-css, que vem depois
   do `09-style.css:1012` `.port { padding: 0 30px }`) ⇒ 1140px de conteúdo a partir
   de 1260px de viewport. Abaixo de 1260px o `@media (max-width:1259px)` de
   `09-style.css:1023` derruba o `max-width` e reduz os lados para 30px (medido
   `padding: 40px 30px 30px` a 591px).

   Todo número abaixo tem duas fontes: o corpus (`referencias/css/`) e o `getComputed-
   Style` do original a 591px em 17/10. O que só existe em desktop (>1260 / >1399) está
   sinalizado com `[desktop]` e é o que a Fase 10 vai re-medir.
   ========================================================================== */

/* --- A faixa: full-bleed, cinza, com as margens internas contidas ------------- */

/* O cinza é do wrapper do tema-pai, não de uma faixa do builder. Nenhum de
   `.btContentWrap` / `.btContentHolder` / `.btContent` tem padding ou border-top
   (`09-style.css:1036-1040`, `.btNoSidebar` ⇒ `padding: 0`), então as margens dos itens
   vazam para fora do cinza — comportamento padrão de bloco, medido no congelado a 1440 e no
   vivo a 591. O clearance do cabeçalho está na regra `main > .page-block.blog-band` abaixo. */
.blog-band .btContentWrap {
    background-color: #f6f6f6;
}

main > .page-block.blog-band {
    padding-bottom: 0;
}

/* O header é transparente (tokens.md §3a): a faixa começa sob ele, daí o forro na `section`.
   Os 4em do primeiro item (e os 3em/4em do último) COLAPSAM para fora do cinza — medido no
   original a 591px em 17/10 e no congelado a 1440 em 18/10 (`qa/topo-header.mjs`):
   `.btContentWrap`, `.btContentHolder` e `.btContent` têm todos o mesmo `top` (64px em 1440,
   56px onde o corpo é 14, que é exatamente o `margin-top` calculado do item
   — `body.btNoSidebar .btPostSingleItemStandard:first-of-type { margin-top: 4em }`,
   `09-style.css:4818`) e o mesmo `bottom` do último item. Nenhum dos três tem padding ou
   border-top, então o vazamento é o comportamento padrão de bloco.
   No original essa tinta de 64 fica DEBAIXO do header absolute de 138 — o print do vivo em
   1440 mostra a avatar do 1º card cortada pela barra. A política da casa (§2386) é o header
   ter prioridade, então o clearance entra como MARGEM da faixa, não como padding: com padding
   de 138 os 64 do item ficavam retidos DENTRO do cinza e a tinta caía em 202 (medido 18/10,
   `qa/topo-header.mjs replica 1440 /artigos`); com margem, os dois colapsam no `max()` e o
   cinza e o card nascem ambos em 138 — o que o original deixa ver, sem o corte. */
main > .page-block.blog-band:first-child {
    padding-top: 0;
    margin-top: var(--imass-header-box);
}

@media (max-width: 767px) {
    /* Mesma política mobile de §2391: barra de 84 + 24 de respiro. */
    main > .page-block.blog-band:first-child {
        margin-top: calc(var(--imass-header-box) + var(--imass-spacing-md));
    }
}

/* `btNoSidebar` (`09-style.css:1036-1040`): sem sidebar, o holder é `width:auto`. */
.blog-band .btContentHolder,
.blog-band .btContent {
    width: auto;
    padding: 0;
}

.blog-band .port {
    padding: 40px 60px 30px;
}

.blog-band .gutter > .port {
    max-width: 1260px;
    margin: 0 auto;
}

@media (max-width: 1259px) {
    .blog-band .gutter > .port {
        max-width: none;
        padding-left: 30px;
        padding-right: 30px;
    }
}

/* --- Ritmo dos itens --------------------------------------------------------- */

/* `body.btNoSidebar .btPostSingleItemStandard:first-of-type { margin-top: 4em }`
   (09-style.css:4821) medido 56px no vivo. */
.blog-band .btContent > :first-child {
    margin-top: 4em;
}

.btPostListStandard {
    padding-bottom: 2em;
}

.btPostListStandard:not(:last-of-type) {
    padding-bottom: 3em;                   /* 42px medido */
}

.btPostListStandard:last-of-type {
    padding-bottom: 0;
}

/* O divisor é do `<article>`, não da valeta: 1200px de largura máxima dentro da
   faixa full-bleed (medido `width: 591px` = largura do artigo a 591px). */
.btPostListStandard:not(:last-of-type)::after {
    display: block;
    content: "";
    width: 100%;
    max-width: 1200px;
    margin: 2.5em auto 0;                  /* 35px medido */
    border-bottom: 1px solid rgba(24, 24, 24, .2);
}

.btPostSingleItemStandard .btArticleMedia {
    margin-bottom: 2.5em;                  /* 35px medido */
    clear: both;
}

.btPostSingleItemStandard .btArticleHeadline,
.btPostSingleItemStandard .btArticleContent,
.btPostSingleItemStandard .btArticleShareEtc {
    margin-bottom: 2em;                    /* 28px medido */
    clear: both;
}

/* Na listagem a valeta já traz a data e o autor: o headline encurta (`:4871`). */
.btHasAuthorInfo.btPostSingleItemStandard .btArticleHeadline {
    margin-bottom: 1.5em;                  /* 21px */
}

/* --- Valeta do autor (listagem) ---------------------------------------------- */

/* 110px de reservado com a coluna de 90px absoluta (`:5267-5298`). Não mede-se em
   591px porque o `@media(max-width:620px)` a empilha — é o item `[desktop]` da
   Fase 10. */
.btHasAuthorInfo .btArticleContentHolder {
    position: relative;
    padding-left: 110px;
}

.articleSideGutter {
    position: absolute;
    top: 0;
    left: 0;
    width: 90px;
    line-height: 1.4;
    text-align: center;
}

.articleSideGutter .asgItem.avatar img {
    border-radius: 50%;
}

.articleSideGutter .asgItem.title {
    margin: 4px 0 0;
}

.articleSideGutter .date {
    opacity: .8;
}

.articleSideGutter .btArticleAuthor {
    color: inherit;
}

/* Sem arquivo de autor no `blogger` (desvio declarado em tokens.md §6.7): quando o
   avatar não existe, o marcador assume a caixa circular do `<img>` que ele substitui.
   Na VALETA ele é inline-flex, não flex: o `<img>` do original é substituído inline na linha
   (medido `disp=inline`) e `.articleSideGutter` carrega `line-height:1.4` (`:5274-5281`), então a
   caixa do item é a tinta + o strut abaixo da baseline — `.asgItem.avatar` vale 96,39 em corpo 16,
   95,59 em 14 e 50,19 em 13, contra 90/90/45 de um bloco flex. É o mesmo par fonte-×-SVG da rodada
   21 (`#60`, `#61`), aqui com o sinal invertido: em vez de matar o strut, devolvê-lo. */
.blog-band .avatar--mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    background-color: rgba(24, 24, 24, .12);
    color: var(--imass-primary);
}

.articleSideGutter .avatar--mark {
    display: inline-block;
    overflow: hidden;                   /* BFC: segura a margem interna E põe a baseline na borda
                                           inferior da margem — o que o `<img>` do original já faz.
                                           `inline-flex` NÃO serve: a baseline dele vem do SVG
                                           centralizado, a caixa fica a cavalo da baseline e o strut
                                           se anula (medido: 90 × 90, h=90 nos dois lados). */
}

.articleSideGutter .avatar--mark svg {
    display: block;
    margin: 25% auto;                   /* 22,5 + 45 + 22,5 = os 90 da caixa, em cada eixo */
}

.blog-band .avatar--mark svg {
    width: 50%;
    height: 50%;
}

/* --- Manchetes --------------------------------------------------------------- */

/* Os seis níveis, não dois: a folha do congela a âncora inteira
   (`09-style.css:9657-9666`, `display:block` + `margin:0` + `padding:0`). O tema portava
   só `h1, h2`; com o `.4em` da regra global, um `h3`/`h5` dentro de `.bt_bb_headline`
   ganharia padding que no original não existe. */
.bt_bb_headline h1,
.bt_bb_headline h2,
.bt_bb_headline h3,
.bt_bb_headline h4,
.bt_bb_headline h5,
.bt_bb_headline h6 {
    display: block;
    margin: 0;
    padding: 0;
}

.blog-band .btPostSingleItemStandard .btArticleHeadline .bt_bb_headline h2 {
    font-size: 2.8125rem;                  /* 45px medidos (`:4874`) */
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -.03em;                /* −1,35px medidos */
    font-family: var(--imass-font-heading);
}

/* `.btContent a { color: #88619e }` do inline não alcança o título: o texto do
   headline é `#202020` (`wp-custom-css` por cima de `09-style.css:4877`) e o link
   herda; no hover vira a marca (`:38` do mesmo bloco). */
.blog-band .bt_bb_headline_content,
.blog-band .bt_bb_headline_content a {
    color: #202020;
}

.blog-band .bt_bb_headline_content a:hover {
    color: var(--imass-primary);
}

/* Post individual: `h1` de 3,75rem (`09-style.css:9700-9707`), mas o
   `@media(max-width:1399px)` de `:30857/30875` corta para 2,4rem com `!important` —
   medido 38,4px a 591px; os 60px só existem acima de 1400px (`[desktop]`). */
.blog-band .btPostSingleItemStandard .btArticleHeadline .bt_bb_headline h1 {
    font-size: 3.75rem;
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -.03em;
    font-family: var(--imass-font-heading);
}

@media (max-width: 1399px) {
    .blog-band .btPostSingleItemStandard .btArticleHeadline .bt_bb_headline h1 {
        font-size: 2.4rem;
    }
}

/* Sobretítulo = linha de metadados das categorias (`crush:4440-4443` + `:18238-18249`). */
.blog-band .bt_bb_headline .bt_bb_headline_superheadline {
    display: block;
    font-family: var(--imass-font-eyebrow);
    font-weight: 400;
    letter-spacing: 0;
    margin: 0 0 .6em;
}

.blog-band .bt_bb_size_normal.bt_bb_headline .bt_bb_headline_superheadline {
    font-size: 15px;                       /* medidos; .6em ⇒ 9px */
}

.blog-band .bt_bb_size_normal.bt_bb_headline .bt_bb_headline_superheadline_outside {
    line-height: .9375rem;
}

.blog-band .bt_bb_size_large.bt_bb_headline .bt_bb_headline_superheadline {
    font-size: 18px;                       /* medidos; .6em ⇒ 10,8px */
}

.blog-band .bt_bb_size_large.bt_bb_headline .bt_bb_headline_superheadline_outside {
    line-height: 1.125rem;
}

/* Subtítulo = data + autor do post individual (`:18770-18777`, medido 18/27 com
   23,4px acima = 1,3em). */
.blog-band .bt_bb_headline .bt_bb_headline_subheadline {
    font-family: var(--imass-font-body);
    font-size: 18px;
    line-height: 1.5;
    margin: 1.3em 0 0;
}

/* --- Metadados (categorias, data, autor) ------------------------------------- */

.meta-icon {
    flex: none;
    width: 1rem;
    height: 1rem;
    margin-right: 6px;
    color: var(--imass-primary);           /* inline `:before { color: #88619e }` */
}

.btArticleDate,
.btArticleAuthor,
.btArticleComments,
.btArticleCategories {
    display: inline-flex;
    align-items: baseline;
}

.btArticleDate:not(:last-child)::after,
.btArticleAuthor:not(:last-child)::after,
.btArticleComments:not(:last-child)::after,
.btArticleCategories:not(:last-child)::after {
    display: inline-block;
    content: " ";
    width: 1.5rem;                         /* 24px medidos */
    height: 1px;
}

/* `:6238-6331` trata o contador como o quarto membro da família: `color: currentColor`
   (!important no original, desnecessário aqui), hover com opacidade `.4` e a cor da
   marca — que no congelado vem do `<style>` do filho, não do `#e94d65` do tema-pai. */
.btArticleComments {
    color: currentColor;
    text-decoration: none;
    transition: opacity 300ms ease;
}

.btArticleComments:hover {
    color: var(--imass-primary);
    opacity: .4;
}

/* A re-declaração `:6321-6331` do glifo `\f0e5` traz `margin-right: 5px`, não os 6px
   da família (`:6276-6282`). */
.btArticleComments .meta-icon,
.bt-comments-box .posted .meta-icon {
    margin-right: 5px;
}

/* `:6221` é `!important` no original — aqui basta porque nenhuma outra regra do
   tema colore o link dentro de `.btArticleCategories`. */
.btArticleCategories {
    line-height: 1.25;
    flex-wrap: wrap;
    text-transform: uppercase;
}

.btArticleCategories a {
    color: currentColor;
    transition: opacity 300ms ease;
}

.btArticleCategories a:hover {
    color: currentColor;
    opacity: .4;
}

.btArticleCategories a:not(:last-child)::after {
    display: inline-block;
    content: " ";
    width: .7rem;
    height: 1px;
}

/* --- Caixa de mídia ---------------------------------------------------------- */

.btMediaBox {
    position: relative;
    overflow: hidden;
}

.btMediaBox img {
    display: block;
    width: auto;
    height: auto;
}

/* Rodada 28 (pedido do operador: "Padronize a largura/altura das imagens destacadas na
   listagem da página 'Artigos' (e aplique os mesmos cantos arredondados citados
   anteriormente na Home)"). Escopo só na listagem: `.btArticleListItem` existe no
   `articles/_item.php` e NÃO no `single.php` (o post individual é
   `btPostSingleItemStandard gutter`, sem a classe de item de lista), então o post
   individual mantém a mídia na proporção natural medida. A img passa a cobrir uma caixa
   16:9 uniforme (largura cheia, `object-fit:cover` corta o excedente) e a caixa herda os
   20px retangulares da casa (mesmo raio dos cards da home, `09-style.css:5085`). */
.btArticleListItem .btMediaBox {
    border-radius: 20px;
}

.btArticleListItem .btMediaBox img {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

/* `09-style.css:520-545` (idêntico em `07-style.css`): invólucro de 16:9. */
.bt-video-container {
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
}

.btMediaBox.video iframe {
    display: block;
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    border: none;
}

/* --- Compartilhamento + botão `Continue reading` ----------------------------- */

.btPostSingleItemStandard .btArticleShareEtc {
    display: flex;
    align-items: center;
}

.btPostSingleItemStandard .btArticleShareEtc > div {
    flex: 1 1 50%;
    max-width: 50%;
}

.btPostSingleItemStandard .btArticleShareEtc > div.btReadMoreColumn {
    text-align: right;
}

/* A coluna fica a 40% de opacidade até o ponteiro entrar no artigo (`:5370-5389`), e o invólucro
   do ícone bloqueia eventos — só a âncora responde (`:5382-5389`).
   Além disso: a coluna só tem ícones, e no original a linha dela vale exatamente a caixa
   do ícone: medido `coluna h=32` com `ícone h=32` a 1440, `28/28` de 1199 a 768 e `26/26` a 360,
   **apesar de** a coluna carregar `line-height: 24/21/19,5`. A lei do vivo é
   `coluna = max(ícone, line-height)`, provada escrevendo `line-height` forçado na página viva
   (`qa/share-lh-live.mjs`): lh 0 → 32, 24 → 32, 40 → 40, 80 → 80, com o ícone parado em 32 nos
   quatro casos. O mecanismo é a `:before` ser **glifo de fonte**: a baseline dela cai DENTRO da
   caixa de 31,5, o ícone desce abaixo da baseline e engole o strut. A réplica pinta o círculo com
   `<svg>` (decisão de §3 — nenhuma das 16 famílias de ícone do Avantage se porta), que não tem
   baseline: alinhado pela borda inferior (`vertical-align: baseline` é o que o original declara),
   sobram **+7/+6/+6** de strut embaixo (39/34/34/48/48/44; `qa/share-va-ab2.mjs`, braço C).
   Porta-se `vertical-align: top` no ícone, que reproduz a MESMA LEI (`max(ícone, lh)`) sem anular
   a `line-height` declarada da coluna; o `line-height: 0` que estava aqui coincide em 6/6 bandas
   só porque a escada de corpo (24/21/19,5) nunca ultrapassa o ícone (32/28/26), e é número-certo
   com mecanismo-errado. A/B completo: A `lh:0` = B `lh` herdada + `va:top` = 32/28/28/42/42/39,
   iguais ao vivo em coluna, linha `ShareEtc` (53/46/46/88/88/82) e card (1023/985/869/834/853/749). */
.btShareColumn {
    opacity: .4;
    transition: opacity 300ms ease;
}

article:hover .btShareColumn {
    opacity: 1;
}

/* Nenhum dos dois nós fixa corpo: no original `.bt_bb_icon` é `line-height:1` +
   `padding-right:.5em` (`crush.css:2811-2817`) e o `a.bt_bb_icon_holder` é `display:flex` com
   `align-items:center` e `line-height:inherit` (`:2911-2921`) — os dois **herdam a escada do
   corpo**. Medido nó a nó, banda a banda (rodada 21, `qa/share-r21.mjs`), o vivo dá holder com
   `fs 16 / lh 16` e caixa `31,5 → 32` a 1440, `14 / 14` e `27,56 → 28` de 1199 a 768 e `13 / 13`
   com `25,5 → 26` a 360; o ícone vale 40 = 32 + 8 de `padding-right` (8/7/7/3,5/3,5/3,25 — os dois
   últimos do trap ≤768 já portado em `:4032`). O `font-size: 14px` e o `font-size: 1rem` que
   estavam aqui colavam 28 no desktop e 16 em ≤360, e a `line-height` herdada (24/21/19,5) fazia a
   linha do ícone valer 33-35 em vez de 28. */
.btShareColumn .bt_bb_icon {
    display: inline-block;
    line-height: 1;
    vertical-align: top;                   /* substituto medido da baseline do glifo (ver acima) */
    padding-right: .5em;
    pointer-events: none;
}

.btShareColumn .bt_bb_icon a.bt_bb_icon_holder {
    display: flex;
    align-items: center;
    line-height: inherit;
    pointer-events: auto;
    text-decoration: none;
    box-shadow: none;
}

/* O círculo É o glifo do original (`.bt_bb_icon_holder:before`): o corpo vem de
   `.btPostSingleItemStandard .btShareColumn .bt_bb_icon .bt_bb_icon_holder:before { font-size:
   1.125em }` (`09-style.css:5020`) e a caixa quadrada `1,75em` da folha do tema-filho, e os dois
   **resolvem sobre o corpo herdado de acima**: `1,125 × 16 = 18` ⇒ `1,75 × 18 = 31,5` a 1440,
   `15,75` ⇒ `27,5625` de 1199 a 768, `14,625` ⇒ `25,59` a 360 (re-medido 18/10, `qa/share-r21.mjs`
   — as 18 regras que casam com o nó estão impressas no log). O preenchimento da rede vem do
   `box-shadow … 1em inset` de `:18896-18940`. O `<svg>` que a réplica punha aqui saiu em 19/10
   junto com os `FILLED` de `Icon.php`: a letraform é a do `FontAwesome.woff` portado, e é ela que
   faz a tinta do glifo dentro do disco ser a do original. */
.btShareColumn .bt_bb_icon a.bt_bb_icon_holder:before {
    display: flex;
    order: 1;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: center;
    line-height: normal;
    font-size: 1.125em;
    width: 1.75em;
    height: 1.75em;
    border-radius: 50%;
    color: #fff;
    transition: all 280ms ease;
}

/* As quatro cores de marca sobre o disco preenchido — `09-style.css:18896-18940`, na íntegra
   (o `!important` da folha original não precisa: aqui não há regra de mesma especificidade
   disputando o `:before`). Valem na fila do /sobre (`.sobre-social`) e na coluna de
   compartilhamento do artigo, os dois portadores que carregam `.btIco*`; o rodapé fica de fora
   porque não tem a classe. O Pinterest (`#bd081b`, `:18963-18967`) entra porque a fila do
   rodapé e a do /sobre o imprimem (`f231`) e a aba Social do core tem a chave.
   `1em` de spread resolve sobre o `font-size` do glifo (25px no /sobre, 18px no card), que é
   exatamente o que cobre o disco — o mesmo número que o vivo lê em
   `getComputedStyle(holder,'::before').boxShadow`. */
.btIcoFacebook.bt_bb_style_filled .bt_bb_icon_holder:before { box-shadow: 0 0 0 1em #3b5998 inset; }
.btIcoTwitter.bt_bb_style_filled .bt_bb_icon_holder:before { box-shadow: 0 0 0 1em #1da1f2 inset; }
.btIcoLinkedin.bt_bb_style_filled .bt_bb_icon_holder:before { box-shadow: 0 0 0 1em #007bb5 inset; }
.btIcoPinterest.bt_bb_style_filled .bt_bb_icon_holder:before { box-shadow: 0 0 0 1em #bd081b inset; }
.btIcoWhatsApp.bt_bb_style_filled .bt_bb_icon_holder:before { box-shadow: 0 0 0 1em #3fbd50 inset; }

.btIcoFacebook.bt_bb_style_filled .bt_bb_icon_holder:hover:before { box-shadow: 0 0 0 2px #3b5998 inset; color: #3b5998; }
.btIcoTwitter.bt_bb_style_filled .bt_bb_icon_holder:hover:before { box-shadow: 0 0 0 2px #1da1f2 inset; color: #1da1f2; }
.btIcoLinkedin.bt_bb_style_filled .bt_bb_icon_holder:hover:before { box-shadow: 0 0 0 2px #007bb5 inset; color: #007bb5; }
.btIcoPinterest.bt_bb_style_filled .bt_bb_icon_holder:hover:before { box-shadow: 0 0 0 2px #bd081b inset; color: #bd081b; }
.btIcoWhatsApp.bt_bb_style_filled .bt_bb_icon_holder:hover:before { box-shadow: 0 0 0 2px #3fbd50 inset; color: #3fbd50; }

/* Botão `bt_bb_size_small` (`:19416-19422`): 12,25px, `padding: 1.2142857em
   1.42857142em` ⇒ 14,875 × 17,5px, `line-height: 1.1`, raio 50px de
   `btHardRoundedButtons` — escrito no elemento, porque o `<body>` do tema não traz
   a classe. O `margin-bottom: .25em` é da regra GLOBAL `.bt_bb_button`
   (`crush.css:2811-2817`) e resolve sobre o corpo do PRÓPRIO botão: medido 3,5 / 3,0625 /
   2,84375 px nas bandas de corpo 14 / 12,25 / 11,375 — sem ele a linha `.btArticleShareEtc`
   fica 1–2 px mais baixa que o vivo (53 × 51). */
.btReadMoreColumn .bt_bb_button {
    display: inline-block;
    font-size: .875em;
    line-height: 1.1;
    margin-bottom: .25em;
    transition: all 300ms ease;
}

.btReadMoreColumn .bt_bb_button a {
    position: relative;
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 1.2142857em 1.42857142em;
    border-radius: var(--imass-btn-radius);
    background-color: var(--imass-primary);
    color: #fff;
    font-family: var(--imass-font-body);
    box-shadow: 0 -2px 0 0 rgba(24, 24, 24, .2) inset;
    transition: all 300ms ease;
}

.btReadMoreColumn .bt_bb_button .bt_bb_button_text {
    order: 1;
    display: block;
    font-weight: 700;
}

/* A CAIXA do glifo é o avanço da letra: no vivo a `:before` vale `0,357143em × 1em` = 5×14 /
   4,375×12,25 / 4,0625×11,375, com `line-height:1` e `display:block` (medido nó a nó em
   `qa/glyph-r21.mjs`). O quadrado `1em×1em` que estava aqui colava 14 de largura e 17 de altura no
   glifo — o botão saía 170×51 contra o 161,33×49 do original. O vão é `.625em` de
   `09-style.css:19394-19396`, que VENCE o `.5em` do crush por ordem de folha (medido 8,75px a 14px,
   e é ele que fecha a soma: 107,578 + 8,75 + 5 + 17 + 17 = 161,328). O SVG que preenche esta caixa
   é o `\f105` redesenhado em viewBox alto (`Support/Icon.php`, `TIGHT_BOX`), escolhido por IoU
   contra o raster da fonte. */
.btReadMoreColumn .bt_bb_button .bt_bb_icon_holder {
    order: 2;
    display: block;
    width: .357142857em;
    height: 1em;
    margin-left: .625em;
}

.btReadMoreColumn .bt_bb_button .bt_bb_icon_holder svg {
    display: block;
    width: 100%;
    height: 100%;
}

.btReadMoreColumn .bt_bb_button:hover {
    transform: translateY(-3px);
}

.btReadMoreColumn .bt_bb_button:hover a {
    box-shadow: 0 -3px 0 0 rgba(24, 24, 24, .2) inset, 0 2px 10px rgba(0, 0, 0, .2);
}

/* --- Etiquetas (tags) do post individual ------------------------------------- */

.btPostSingleItemStandard .btArticleShareEtc .btTags ul {
    display: flex;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Fundo `rgba(24,24,24,.2)` (a cadeia de `:4972` vence o `#88619e` global do
   wp-custom-css por especificidade); só o hover fica roxo, porque o inline repete o
   seletor de `:4984` e vem depois no cascade. */
.btPostSingleItemStandard .btArticleShareEtc .btTags ul a {
    display: block;
    padding: .4em 1em;
    margin: 0 4px 4px 0;
    border-radius: 50px;
    font-size: .75rem;
    text-transform: uppercase;
    background-color: rgba(24, 24, 24, .2);
    color: currentColor;
    transition: all 300ms ease;
}

.btPostSingleItemStandard .btArticleShareEtc .btTags ul a:hover {
    background-color: var(--imass-primary);
    color: #fff;
}

/* --- Sobre o autor ----------------------------------------------------------- */

.btAboutAuthor {
    display: flex;
    width: 100%;
    margin: 0 0 3em;                       /* 42px medidos */
    padding: 2em;                          /* 28px medidos */
    border: 2px solid var(--imass-primary);
    border-radius: 20px;                   /* `btHardRoundedButtons` (`:5085`) */
}

.btAboutAuthor .aaAvatar {
    flex: 1 1 150px;
    vertical-align: top;                   /* `09-style.css:5092`, portado sem efeito medível: é item de flex */
    padding: 0 1em 0 0;
}

.btAboutAuthor .aaAvatar img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 50%;
}

.btAboutAuthor .aaTxt {
    flex: 0 1 100%;
    padding: 0;
}

.btAboutAuthor .aaTxt h4 {
    font-size: 1.3em;                      /* 18,2px medidos */
    margin-bottom: 0;
}

.btAboutAuthor .aaTxt > :last-child {
    margin-bottom: 0;
}

@media (max-width: 520px) {
    .btAboutAuthor {
        flex-direction: column;
    }

    .btAboutAuthor .aaAvatar {
        flex: 1 0 80px;
        padding: 0 0 20px;
    }

    .btAboutAuthor .aaAvatar img {
        width: 80px;
    }

    /* O `width:100%` do `<img>` é a tinta do gravatar; sem avatar, o marcador (`avatar--mark`,
       §6.20) assume a caixa dele. A régua de ≤520 só nomeava `img` e o marcador ficava em
       244×244 (medido) contra 80×80 do vivo. Especificidade: precisa de 3 classes para vencer
       `.blog-band .avatar--mark`. */
    .btAboutAuthor .aaAvatar .avatar--mark {
        width: 80px;
    }
}

/* --- Comentários (decisão (l)) ----------------------------------------------- */

/* Subset de `09-style.css:6398-7108` ancorado no HTML congelado de
   `single-e-social.html`. Ficam de fora as regras sem marca no corpus: `li.pingback`,
   `p.edit-link`, `.comment-edit-link`, `.comment-navigation`, `.star-rating` e
   `#cancel-comment-reply-link` — edição e pingback são do admin do WordPress, resposta
   e paginação pressupõem rosqueio, que a v1 não tem (plano §2.5). */

.bt-comments-box {
    margin: 2em 0;
}

/* `:6410-6439` dá 2em ao título solto da caixa e 1,5625em ao título do formulário; na
   réplica só existe o segundo (`h3#reply-title`). */
.bt-comments-box .comment-respond > h3 {
    margin: 0 0 .625em;
    padding: 0;
    font-size: 1.5625em;
}

.comment-reply-title {
    display: block;
}

.bt-comments-box ul.comments,
.bt-comments-box ul.comments li.comment {
    display: block;
    margin: 0;
    padding-left: 0;
    list-style: none;
}

.bt-comments-box > ul.comments {
    margin: 0 0 2em;
}

.bt-comments-box ul.comments > li {
    display: block;
    margin: 0;
    border-top: 1px solid rgba(24, 24, 24, .2);   /* a família `.btLightSkin` (`:6455`) */
}

.bt-comments-box ul.comments li > article {
    position: relative;
    display: flex;
    width: 100%;
    padding: 2em 0;
}

.bt-comments-box ul.comments li > article .commentTxt {
    flex: 1 1 100%;
    padding: 0;
}

.bt-comments-box ul.comments li > article .commentAvatar {
    flex: 0 1 75px;
    padding: 0 20px 0 0;
}

.bt-comments-box .vcard {
    position: relative;
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    align-content: flex-start;
    justify-content: space-between;
    padding-bottom: 1em;
}

.bt-comments-box .vcard h5.author {
    flex: 1 1 auto;
    margin: 0;
    padding: 0;
    line-height: 1.3;
    font-size: 1.2em;
}

.bt-comments-box .vcard h5.author a {
    color: inherit;
}

.bt-comments-box .vcard h5.author a:hover {
    color: var(--imass-primary);
}

/* `.posted` é Roboto Condensed 14px com o relógio `\f017` (`:6627-6652`) — o mesmo par
   do `relogio` da data do artigo, pintado pela marca no `<style>` do filho. */
.bt-comments-box .vcard .posted {
    display: flex;
    align-items: center;
    margin: 0;
    padding: 0 0 0 10px;
    line-height: 1.5;
    text-align: right;
    font-family: var(--imass-font-eyebrow);
    font-size: .875rem;
}

/* --- Formulário -------------------------------------------------------------- */

.bt-comments-box input,
.bt-comments-box textarea {
    transition: all 300ms ease;
}

/* `:6565-6571`: só a linha do corpo zera a linha do invólucro; rótulo e textarea voltam
   a 1,8. É o que assenta o rótulo no topo do textarea de 8 linhas. */
.bt-comments-box .btComment {
    line-height: 0;
}

.bt-comments-box .btComment textarea,
.bt-comments-box .btComment label {
    line-height: 1.8;
}

/* A mesma caixa medida do formulário de contato — `:237-247` (borda), `:241-247`
   (3,25em de altura, `padding: 1.25em`), `:493-507` (foco) e `btHardRoundedButtons`
   (raio 50px, textarea 26px) — aplicada por escopo próprio em vez de alargar
   `.contact-form`, cuja geometria já foi validada na Fase 7. */
.bt-comments-box input:not([type=hidden]):not([type=checkbox]),
.bt-comments-box textarea {
    display: block;
    box-sizing: border-box;
    width: 100%;
    height: 3.25em;
    padding: 1.25em;
    margin-bottom: 1em;
    font-family: var(--imass-font-body);
    line-height: 1;
    color: var(--imass-text);
    background-color: var(--imass-white);
    border: 1px solid rgba(24, 24, 24, .2);
    border-radius: 50px;
    outline: none;
    transition: border-color 500ms ease, box-shadow 500ms ease;
}

.bt-comments-box textarea {
    height: auto;
    border-radius: 26px;
    resize: vertical;
}

.bt-comments-box input:not([type=hidden]):not([type=checkbox]):focus,
.bt-comments-box textarea:focus {
    border-color: rgba(24, 24, 24, .4);
    box-shadow: 0 2px 10px 0 rgba(0, 0, 0, .12);
}

.bt-comments-box .comment-form {
    padding-bottom: 2em;
}

/* `:6823-6826` — os dois ramos da réplica caem no `padding-bottom: 0`: com a lista
   impressa (`.comments + .comment-respond`) e no estado do congelado, em que o
   formulário é o único filho de `#comments`. */
.bt-comments-box .comments + .comment-respond .comment-form,
.bt-comments-box > .comment-respond:only-child .comment-form {
    padding-bottom: 0;
}

/* `:6404-6407` — o guard `body:not(.woocommerce)` é do WordPress e cai; o `<p>` do
   botão perde os 14px globais porque o respiro de baixo vem do `padding-bottom` do
   form e dos 30px do `.port`. */
.bt-comments-box .form-submit {
    margin-bottom: 0;
}

/* O glifo do botão nasce de `[data-ico-fa]:before{content:attr(data-ico-fa)}`
   (`01-content_elements.crush.css:54-56`) com `\f1d8`; a réplica não porta a fonte e
   imprime o SVG `enviar` no mesmo papel: depois do rótulo, por `order: 2`
   (`:6962-6967`). */
.btCommentSubmit {
    display: flex;
    align-items: center;
    padding: 1.125em 1.875em;
    margin-top: .5em;
    border: 0;
    border-radius: var(--imass-btn-radius);
    background: var(--imass-primary);
    color: var(--imass-white);
    font-family: var(--imass-font-body);
    font-size: 1em;
    font-weight: 800;
    line-height: 1;
    box-shadow: 0 -2px 0 0 rgba(24, 24, 24, .2) inset;
    transition: all 300ms ease;
}

.btCommentSubmit:hover {
    transform: translateY(-3px);
    box-shadow: 0 -3px 0 0 rgba(24, 24, 24, .2) inset,
        0 0 0 2.5em var(--imass-primary) inset,
        0 2px 10px rgba(0, 0, 0, .2);
}

.btCommentSubmit .btnInnerText {
    order: 1;
    display: block;
}

.btCommentSubmit .bt_bb_icon_holder {
    order: 2;
    display: block;
    margin-left: .625em;
}

.btCommentSubmit .bt_bb_icon_holder svg {
    width: 1em;
    height: 1em;
}

@media (max-width: 520px) {
    /* `:7010-7046`: o cabeçalho do comentário empilha e o `.posted` passa a
       justificar à esquerda, separado do nome por uma linha pontilhada. */
    .bt-comments-box .vcard {
        flex-flow: row wrap;
        align-items: flex-start;
        justify-content: flex-start;
        padding: 0 0 10px;
        margin: 0 0 10px;
        border-bottom: 1px dotted rgba(24, 24, 24, .2);
    }

    .bt-comments-box .vcard h5.author {
        flex: 1 1 100%;
    }

    .bt-comments-box .vcard .posted {
        padding: 0;
        margin-top: .7em;
        text-align: left;
    }
}

/* --- Anterior / Próximo ------------------------------------------------------ */

.blog-band .btPrevNextNav.gutter {
    margin-bottom: 4em;                    /* `body.btNoSidebar .btPrevNextNav` (`:5954`) */
}

.btPrevNextNav .btPrevNextNav {
    display: flex;
    flex-flow: row nowrap;
    margin: 3em 0 4em;
    padding-top: 3em;                      /* 42px, medido no vivo */
    border-top: 1px solid rgba(24, 24, 24, .2);
}

.btPrevNextNav .btPrevNext {
    display: flex;
    align-items: center;
    flex: 1 0 50%;
    min-height: 1px;
    margin: 0;
    color: currentColor;
}

.btPrevNextNav .btPrevNext.btNext {
    flex-direction: row-reverse;
    text-align: right;
}

/* O círculo só existe quando o vizinho tem miniatura — no original o span
   `.btPrevNextImage` nem é impresso sem ela (`views/prev_next.php`). */
.btPrevNextNav .btPrevNext .btPrevNextImage {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 4.375em;
    height: 4.375em;                       /* 61,25px */
    margin: 0 1em 0 0;
    position: relative;
    overflow: hidden;
    border-radius: 50%;
    background-size: cover;
    background-position: center center;
    transition: all 500ms ease;
}

.btPrevNextNav .btPrevNext.btNext .btPrevNextImage {
    margin: 0 0 0 1em;
}

.pn-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1 0 100%;
    font-size: 2em;
    border-radius: 50%;
    background-color: var(--imass-primary);
    color: #fff;
    box-shadow: 0 -3px 0 0 rgba(24, 24, 24, .2) inset;
    opacity: 0;
    transform: scale(.5);
    transition: all 500ms ease;
}

.pn-arrow svg {
    width: 1em;
    height: 1em;
}

.btPrevNextNav .btPrevNext .btPrevNextItem {
    flex: 1 0 0%;
    min-width: 0;
}

.btPrevNextNav .btPrevNext .btPrevNextItem .btPrevNextDir {
    font-family: var(--imass-font-eyebrow);
    font-size: .875em;                     /* 12,25px medidos */
    line-height: 1;
    text-transform: uppercase;
    transition: opacity 300ms ease;
}

/* 18px/25,2 com teto de 2,8em: o original usa `-webkit-box` + line-clamp 2, que o
   Chromium resolve para `flow-root` no `getComputedStyle` — o mesmo par (medido
   `display: flow-root`, `max-height: 50,4px`, `overflow: hidden`). */
.btPrevNextNav .btPrevNext .btPrevNextItem .btPrevNextTitle {
    display: flow-root;
    overflow: hidden;
    max-height: 2.8em;
    font-family: var(--imass-font-heading);
    font-size: 1.125rem;
    font-weight: 800;
    line-height: 1.4em;
    transition: color 300ms ease;
}

.btPrevNextNav .btPrevNext:hover .btPrevNextTitle {
    color: var(--imass-primary);
}

.btPrevNextNav .btPrevNext:hover .btPrevNextImage {
    transform: translateY(-3px);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .2);
}

.btPrevNextNav .btPrevNext:hover .pn-arrow {
    opacity: 1;
    transform: scale(1);
}

@media (max-width: 620px) {
    .btPrevNextNav .btPrevNextNav {
        flex-direction: column;
    }

    .btPrevNextNav .btPrevNext {
        flex: 1 0 100%;
    }

    .btPrevNextNav .btPrevNext:nth-child(2) {
        margin-top: 1.5em;
        padding-top: 1.5em;
        border-top: 1px solid rgba(24, 24, 24, .2);
    }
}

/* --- Paginação --------------------------------------------------------------- */

/* Reconstrução: `class="paging` não ocorre nenhuma vez em `referencias/html/` (o
   original tem 7 posts e `posts_per_page=10`, então o bloco nunca renderiza). Os
   números vêm de `09-style.css:5805-5918` + do `font-family` do wp-custom-css.
   O círculo do original é `a:after`, isto é, o último filho do DOM — por isso o
   `flex-direction: row-reverse` de `:5909` NÃO é portado: aqui a seta já é o
   primeiro `<span>` e a ordem visual sai a mesma. */
.btPagination {
    font-family: var(--imass-font-heading);
    font-weight: 400;
    font-size: 1rem;
    line-height: 2.5rem;
    margin: 3em 0 4em;
    padding-top: 3em;
    border-top: 1px solid rgba(24, 24, 24, .2);
}

.btPagination .port {
    display: flex;
    justify-content: space-between;
}

.btPagination .port::after {
    display: block;
    content: "";
    height: 0;
    flex: 1 0 auto;
    order: 2;
}

.btPagination .paging.onLeft {
    order: 1;
}

.btPagination .paging.onRight {
    order: 3;
}

.btPagination .paging a {
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    color: inherit;
    font-family: var(--imass-font-heading);
    font-weight: 800;
}

.btPagination .paging a:hover {
    color: var(--imass-primary);
}

.paging-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.8125rem;
    height: 2.8125rem;                     /* 45px */
    border-radius: 50%;
    background-color: var(--imass-primary);
    color: #fff;
    box-shadow: 0 -2px 0 0 rgba(24, 24, 24, .2) inset;
    transition: all 500ms ease;
}

.paging-arrow svg {
    width: 1.25rem;
    height: 1.25rem;
}

.pagePrev .paging-arrow {
    margin-right: 10px;
}

.pageNext .paging-arrow {
    margin-left: 10px;
}

.btPagination .paging a:hover .paging-arrow {
    transform: translateY(-3px);
    box-shadow: 0 -3px 0 0 rgba(24, 24, 24, .2) inset, 0 2px 10px rgba(0, 0, 0, .2);
}

/* --- Post individual: a coluna de compartilhamento troca de lado ------------- */

/* `body.single .btPostSingleItemStandard .btShareColumn { text-align: right }`
   (`:5014`). O tema não tem as classes do WordPress no `<body>`, então a view do
   post individual marca a própria faixa. */
.blog-band--single .btPostSingleItemStandard .btShareColumn {
    text-align: right;
}

/* --- Bandas estreitas -------------------------------------------------------- */

@media (max-width: 768px) {
    .btPostSingleItemStandard .btArticleShareEtc {
        display: block;
    }

    .btPostSingleItemStandard .btArticleShareEtc > div {
        max-width: 100%;
        float: none;
        text-align: center;
    }

    .blog-band--single .btPostSingleItemStandard .btShareColumn {
        text-align: center;
    }

    .btPostSingleItemStandard .btArticleShareEtc > div.btReadMoreColumn .bt_bb_icon,
    .btPostSingleItemStandard .btArticleShareEtc > div.btShareColumn .bt_bb_icon,
    .btPostSingleItemStandard .btArticleShareEtc > div.btTagsColumn .bt_bb_icon {
        padding-left: .25em;               /* 3,5px medidos no vivo */
        padding-right: .25em;
    }

    .btPostSingleItemStandard .btArticleShareEtc > div:first-child {
        padding-bottom: 1em;
    }

    .btPostSingleItemStandard .btArticleShareEtc > div.btTagsColumn .btTags ul {
        justify-content: center;
    }
}

@media (max-width: 620px) {
    /* A valeta de 110px vira cabeçalho empilhado (`:5333-5368`). */
    .btHasAuthorInfo .btArticleContentHolder {
        padding-left: 0;
        clear: both;
    }

    .btHasAuthorInfo .articleSideGutter {
        position: relative;
        left: 0;
        width: auto;
        margin: 0;
        padding: 0 0 1em;
        clear: both;
    }

    .btHasAuthorInfo .asgItem.avatar {
        width: 45px;
        float: left;
        margin-top: -4px;
    }

    .btHasAuthorInfo .asgItem.title,
    .btHasAuthorInfo .asgItem.date {
        padding-left: 55px;
        text-align: left;
    }
}

/* --- Estado vazio ------------------------------------------------------------ */

.blog-band .posts-empty {
    margin: 0;
}

/* ==========================================================================
   Flash do framework — envio de formulário (sem Tabler nem jQuery no tema)
   ========================================================================== */

.flash-stack {
    padding-top: var(--imass-spacing-md);
}

.flash {
    max-width: var(--imass-container-max);
    margin: 0 auto var(--imass-spacing-sm);
    padding: 14px 24px;
    font-size: 14px;
    line-height: 21px;
    border-radius: 50px;
    border: 1px solid transparent;
}

.flash--success {
    color: var(--imass-dark);
    background-color: rgba(136, 97, 158, .1);
    border-color: var(--imass-primary);
}

.flash--error,
.flash--warning {
    color: var(--imass-dark);
    background-color: rgba(24, 24, 24, .06);
    border-color: rgba(24, 24, 24, .35);
}

.flash--info {
    color: var(--imass-text-light);
    background-color: rgba(24, 24, 24, .04);
    border-color: rgba(24, 24, 24, .15);
}

/* ==========================================================================
   Footer — contrato em tokens.md §3b
   ========================================================================== */
/* Rodapé = UMA seção do builder (`home.html`: `.bt_bb_section.bt_bb_layout_boxed_1200
   .bt_bb_top_spacing_large`) com cinco linhas: 4 colunas de widgets, um separador sólido
   de 2px, a faixa `4/8` (crédito + menu) e um separador invisível de remate. Decomposição
   medida nó a nó em 18/10 (`qa/foot-tree-live-1440.log`, a 1440, topo do rodapé = 0):
   122,5 (forro de cima) + 350,3 (colunas) + 30 (2 + 28) + 27 (faixa) + 28 (remate) = 557,8.

   O `font-size` NÃO é 12,25 fixo: é `.875em` da folha do tema-pai (`09-style.css:4414`) e
   portanto segue a escada do corpo (16/14/13 — ver `--imass-builder-em`), o que dá 14 ≥1200,
   12,25 de 361 a 1199 e 11,375 ≤360. Os dois forros são o mesmo número lido por outra via:
   `8.75em` é `bt_bb_top_spacing_large` (`:10207`, `4.375em` em ≤768 `:10291`) e os `2em` de
   remate são o `.bt_bb_separator bt_bb_border_style_none` de `m=28px/0px` da última linha
   (`m=24,5px/0px` a 992, medido — `2em` sobre 12,25 ✓). O `line-height` sai daqui de
   propósito: o vivo herda o COMPRIMENTO já resolvido do corpo (24px ≥1200, 21px abaixo), e
   é isso que faz a faixa inferior medir 24 de entrelinha a 1440 e 21 a 992. */
.site-footer {
    position: relative;
    background-color: var(--imass-white);
    color: var(--imass-text);
    font-size: .875em;
    padding: 8.75em 0 2em;
}

/* bgn-footer.png: textura 99,1% transparente, contain, ancorada embaixo à esquerda */
.site-footer::before {
    content: "";
    position: absolute;
    inset: 0;
    background: url('/assets/themes/imass/img/backgrounds/bgn-footer.png') left bottom / contain no-repeat;
    pointer-events: none;
}

.site-footer .container {
    position: relative;
}

/* As quatro colunas são `.bt_bb_row.bt_bb_column_gap_10` sobre `.bt_bb_cell` de 1200: cada
   coluna é `col-xxl-3` de 305 com `padding-inline: 20px` ⇒ tinta de **285** e vão de **20**
   entre tintas (4×285 + 3×20 = 1200). Com `--imass-spacing-md` (24) a réplica desenhava
   282. O `row-gap` é 0: a 992 a segunda linha de colunas COLA na primeira (top=107,2+338,5
   = 445,7 e a linha de baixo começa em 445,7, `qa/foot-tree-live-992`) porque o vão quem faz
   são os separadores terminais, abaixo. `align-items: start` porque o vivo NÃO estica: as
   quatro colunas medem 347,8 / 350,3 / 337 / 255 (`foot-leaf-live-1440`) e a linha fecha na
   mais alta (350,3, a do mapa). */
.footer-columns {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0 20px;
    align-items: start;
}

/* Cada coluna do vivo termina num par de `.bt_bb_separator bt_bb_border_style_none`: um de
   `m=0/0` (nada) e um de `m=28px/52,5px` = **5,75em** (80,5 a 14; 70,44 a 12,25) —
   `09-style.css:22087`+`:22105` na folha de opções. São eles que dão 347,8/350,3/255 às
   colunas 1, 2 e 4; a de eSocial é a única sem remate (texto fecha em 337 = altura da
   coluna, `qa/foot-leaf-live-1440`). Sem isso a réplica tinha de esticar tudo a 337 para
   bater a coluna do meio e ficava 80,5 curta nas demais — e o rodapé inteiro 48,8 px baixo. */
.footer-col {
    padding-bottom: 5.75em;
}

.footer-esocial {
    padding-bottom: 0;
}

.footer-eyebrow {
    font-family: var(--imass-font-eyebrow);
    font-size: 14px;
    font-weight: 400;
    line-height: 15.4px;
    color: var(--imass-text);
    margin: 0 0 8.4px;
}

.footer-title {
    /* No vivo o par eyebrow+título é UM só `<h5 class="bt_bb_headline_tag">` e a folha do
       builder trava `margin: 0; padding: 0` em `.bt_bb_headline h1..h6` (`09-style.css:9657-9665`)
       — o vão de 14px que separa o título do sub NÃO é margem do título, é `margin-top: 1em`
       do próprio sub (`09-style.css:18299-18301`). Medido 18/10 (`qa/foot-leaf-{live,replica}-1440`):
       h5 m=0/0 (caixa 45,8 = 15,4 + 8,4 + 22) e a réplica, com os 12px de `margin-bottom`,
       começava o sub 2px alto (57,8 contra 59,8). */
    font-family: var(--imass-font-heading);
    font-size: 20px;
    font-weight: 800;
    line-height: 22px;
    letter-spacing: -0.6px;
    color: var(--imass-text);
    margin: 0;
    /* `padding:0` — idem `.section-title`: no vivo é `h5.bt_bb_headline_tag` sob
       `09-style.css:9657-9666` e mede `pb=0px` (`qa/h-styles-live-1440`, 4 nós de rodapé). */
    padding: 0;
}

/* As três headlines portadas do rodapé são `<b>` no congelado
   (`<span class="bt_bb_headline_content"><span><b>Encontre-nos</b></span></span>`) e
   `inline-custom.css` pinta `.bt_bb_headline b` com a cor da marca. Mesma regra que já
   vale para `.section-title b` (:514). */
.footer-title b {
    font-weight: inherit;
    color: var(--imass-primary);
}

/* `.bt_bb_size_extrasmall … .bt_bb_headline_subheadline { font-size: .875rem !important;
   margin-top: 1em }` (`09-style.css:18299-18301`) — o sub-título escapa da corrente de `em`
   do rodapé e volta à base de 16px do `html`. Tinta medida no congelado: 436 px de largura
   para "Venha visitar nossa empresa…" contra 381 px da réplica em 12,25px; o `measureText`
   em 14px fecha em 437 px.
   O `margin` é do LADO DE CIMA, não de baixo: medido 18/10 o vivo lê `m=14px/0px` e a caixa
   inteira do cabeçalho (eyebrow+título+sub) fecha em 101,8px — os 14px que a réplica punha
   embaixo existiam, mas no lugar errado, e eram a única coisa segurando a lista de contatos. */
.footer-sub {
    font-size: 14px;
    line-height: 1.5em;              /* 21 — o sub tem `line-height` próprio na folha de opções,
                                         NÃO herda os 24 da base do rodapé (caixa de 2 linhas
                                         = 42 no vivo, `qa/foot-leaf-live-1440`) */
    margin: 14px 0 0;                 /* 1em sobre a tinta de 14px do próprio sub */
}

/* (f) — Ícones sociais dinâmicos do rodapé.
   A caixa NÃO é a da coluna de compartilhamento de artigo: o `bt_bb_size_small` do rodapé
   tem override própria na folha de opções (`09-style.css:18612-18615`:
   `.bt_bb_size_small.bt_bb_icon .bt_bb_icon_holder:before { font-size: 25px; width: 2em;
   height: 2em }`) — círculo de **50×50** com o glifo em **25px**. Medido 18/10 no vivo
   (`qa/foot-ico-live`): holder 50×50 em x = 1035 / 1092 / 1149 / 1206 ⇒ passo de 57, que é
   o círculo mais o `padding-right: .5em` do ícone (`.5em` de 14,
   `01-content_elements.crush.css:2861-2862`). A réplica desenhava 30,4.
   O círculo É o `:before` do holder, como no vivo: a âncora vem vazia e traz
   `data-ico-fontawesome` (`home.html`), então a caixa `2em` e a sombra de `1em` resolvem sobre
   os 25px da letra. Antes o círculo era o invólucro `a` com um `<svg>` de 25px dentro — a caixa
   batia e a tinta não (19/10).

   A COR não é a da rede. O censo dos 11 congelados (`referencias/html/`, todos os `.html`) mostra que os
   quatro ícones do rodapé **não** carregam classe `.btIco*`: carregam
   `bt_bb_color_scheme_6 bt_bb_style_filled bt_bb_shape_circle bt_bb_size_small` com o par
   inline `--icon-primary-color:#ffffff; --icon-secondary-color:#88619e`, e é o secundário que
   pinta o disco — `getComputedStyle(holder, '::before').boxShadow` =
   `rgb(136,97,158) 0 0 0 25px inset` (18/10, `qa/esoc-ico-live`). As `.btIco*` de marca vivem em
   TRÊS sítios do congelado, não num: a coluna de compartilhamento do artigo (`single-e-social.html`
   e `single-sem-categoria.html`), a MESMA coluna repetida nos 7 cards do arquivo (`artigos.html`) e
   a fila social do /sobre (`sobre.html`) — nos dois primeiros com `bt_bb_size_xsmall`, no /sobre com
   `bt_bb_size_small` (a mesma override de 25px/`2em` do rodapé) e com `btIcoGooglePlus` +
   `btIcoPinterest` onde o arquivo põe Twitter + WhatsApp. O rodapé da `home.html` não tem nenhuma.
   Retirar `btIco*` do markup do rodapé é o que devolve o roxo e desliga a pintura de
   marca por cima do glifo.
   Hover medido (`qa/ico-hover-live`): o disco passa a BRANCO com anel de 2px na cor da marca
   e o glifo assume essa mesma cor.
   A ponte cabeçalho→ícones é um separador do vivo com `m=14px/8,75px` (sub acaba em 101,8,
   ícone começa em 124,5 ⇒ 22,75). */
/* O vão NÃO é `gap`: é o `padding-right: .5em` do próprio `.bt_bb_icon`, resolvido sobre a
   base da coluna (medida 14px no vivo, `iconFs` de `qa/foot-soc.mjs` ⇒ 7px ≥1200). Com `gap`
   fixo o passo não encolhia nas bandas estreitas — o mesmo erro já corrigido em `.sobre-social`.
   A fila é 57 = 50 do círculo + 7 do vão, com `x` = 1035/1092/1149/1206.

   O disco É o `:before` do holder, não o `<a>` nem um `<svg>` filho: é assim que o congelado
   monta (`home.html` imprime `data-ico-fontawesome` na âncora vazia) e é o que faz a caixa
   `2em × 2em` e o `box-shadow … 1em inset` saírem do MESMO `font-size` que desenha a letra —
   a receita de `01-content_elements.crush.css:2922-2944` e `:2993`. Pintar o círculo no `<a>`
   e colar um SVG de 25px dentro dava a caixa certa (50×50) com a tinta errada: 8,5 × 17,0 px
   no Facebook contra 12,5 × 24,0 medidos no vivo (varredura PIL no raio 23, 19/10). */
.footer-social-icons {
    display: flex;
    flex-wrap: wrap;
    margin-top: 22.75px;
}

.footer-social-icons .bt_bb_icon {
    display: inline-block;
    line-height: 1;
    font-size: 14px;                  /* base do `.5em` do vão, medida no vivo */
    padding-right: .5em;
}

.footer-social-icons .bt_bb_icon a.bt_bb_icon_holder {
    display: flex;
    flex-flow: row nowrap;
    justify-content: flex-start;
    align-items: center;
    align-content: center;
    line-height: inherit;
    font-weight: normal;
    text-decoration: none;
    box-shadow: none;                 /* quem pinta é o `:before`, não o invólucro */
}

.footer-social-icons .bt_bb_icon a.bt_bb_icon_holder:before {
    display: flex;
    order: 1;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: center;
    line-height: normal;
    font-size: 25px;                  /* `09-style.css` trava o glifo de `size_small` em 25px */
    width: 2em;                       /* 50px — a caixa medida do círculo */
    height: 2em;
    border-radius: 50%;
    color: #fff;
    transition: all 280ms ease;
}

.footer-social-icons .bt_bb_style_filled .bt_bb_icon_holder:before {
    box-shadow: 0 0 0 1em var(--imass-primary) inset;   /* 1em de 25px = 25px, como no vivo */
}

.footer-social-icons .bt_bb_style_filled .bt_bb_icon_holder:hover:before {
    background-color: #fff;
    box-shadow: 0 0 0 2px var(--imass-primary) inset;
    color: var(--imass-primary);
}

/* A lista de contatos NÃO encosta no sub: no vivo há um `bt_bb_separator
   bt_bb_border_style_none` de `m=0px/14px` entre o `<header>` e o primeiro ícone
   (medido 18/10, `qa/foot-leaf-live-1440`: sub termina em 101,8 e a lista começa em
   115,8). O `font-size: 14px` é o do `.bt_bb_icon` do vivo (folha do builder
   `09-style.css:18617`: o rótulo do ícone volta à base de 16px do `html` com
   `.875rem`); sem ele o `.625em` do separador de cada linha resolvia em 7,66px sobre os
   12,25px herdados e o passo saía 23,0 contra os 24,15 medidos no vivo. */
.footer-info {
    list-style: none;
    padding: 0;
    margin: 14px 0 0;
    font-size: 14px;
}

/* Cada linha é, no original, um `.bt_bb_icon` `borderless xsmall` seguido de um
   `.bt_bb_separator bt_bb_bottom_spacing_extra_small` (`09-style.css:22075`,
   `margin-bottom:.625em`). O par glifo+rótulo é `display:flex` com `align-items:center`
   (`01-content_elements.crush.css:2911-2921`) e o rótulo tem `line-height:1.1`
   + `padding-left:.5em` (:2980-2983). Caixa da linha = 14px × 1,1 = 15,4px.
   O `.625em` resolve sobre os 14px da linha, não sobre os 12,25px herdados: medido 18/10
   no vivo (`qa/foot-leaf-live-1440`) o separador entre ícones lê `m=0px/8,75px` e o passo
   é 24,15 (139,9 − 115,8) — a nota anterior derivava 23,2 do HTML congelado e era 1,09px
   curta por linha. */
.footer-info li {
    display: flex;
    align-items: center;
    margin-bottom: .625em;
}

/* A caixa do glifo borderless NÃO é o avanço da letra: o original trava
   `width:1em !important; height:1em !important` em todo ícone `bt_bb_style_borderless`
   (`09-style.css:18679-18682`) e centraliza o traço dentro dela pela receita de flex-coluna do
   crush (`:2922-2931` — `display:flex; flex-flow:column; align-items:center;
   justify-content:center`). Medido 19/10 no vivo (`qa/fa-pseudo.mjs`, 1440): `:before` = 14×14
   nas cinco linhas de âncora. A TINTA, varrida em pixels sobre
   `shots/{live,replica}-foot-rows.png` a 4× (`qa/glyph-ink.py`), é 11,0 no auscultador, 12,0 no
   WhatsApp e no globo, 14,0 no envelope e 8,25 no pino — os avanços reais do `.woff`, que são
   11/12/14/12/8 nos DOIS ambientes medidos em canvas com o mesmo ficheiro (SHA-256 `ba0c59de…`,
   o do próprio tema Avantage). Daí a tinta nascer a 1,5 / 1,0 / 0 / 1,0 px da borda esquerda da
   caixa e o rótulo do vivo em x = 141; sem o `1em` a réplica o punha em 138.
   A linha do endereço lê 10,3 e não é outra largura: é o MESMO `1em` encolhendo como
   `flex-shrink` (o max-content do rótulo dela não cabe nos 278 da coluna), o que devolve o
   x = 130,3 do vivo. Por isso o item encolhe aqui — `flex: 0 1 auto`, não `none`. */
.footer-info-ico {
    flex: 0 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1em;
    height: 1em;
    line-height: normal;                /* a caixa de 14px vem do `1em`, não do corpo da linha */
    font-size: 14px;
    margin-right: .5em;
    color: #88619e;
}

/* O rótulo de cada `.bt_bb_icon` é o `> span` do holder: `.875rem` (14px) por
   `09-style.css:18609` — override de topo, fora de qualquer `@media`, que vence o
   `.875em` da folha crush por ordem de fonte — e `line-height:1.1` em :2980. A mesma
   override redefine o glifo (`:before{font-size:14px}`, :18604). A linha do endereço
   também é um `> span` de ícone, não uma âncora, então recebe o par junto.
   O menu `.btBottomFooterMenu` NÃO recebe nenhuma dessas overrides: ele herda a base do
   rodapé, que é `.875em` do corpo — 14px/24px ≥1200 e 12,25px/21px de 361 a 1199. Medido
   18/10 (`qa/foot-band2-live-1440.log` × `-992`): `a` de "Início" com 33,7 de tinta a 1440
   e 29,5 a 768, exatamente o par 14/12,25 (a nota antiga, que travava 12,25, tinha a
   largura da 2ª banda como se fosse a única). */
.footer-info a,
.footer-address {
    color: var(--imass-text);
    font-size: 14px;
    line-height: 1.1;
}

.footer-nav a {
    color: var(--imass-text);
    transition: 200ms ease opacity;   /* `09-style.css:4438-4442` */
}

/* O hover do rodapé NÃO muda de cor nos rótulos. Medido 18/10 com `hover()` real
   (`qa/foot-hover-*` e `qa/foot-ico-hover-*`): o link do menu passa a `opacity: .5` com a
   cor intacta (`09-style.css:4438-4447`, que ainda anula a cor com `color: currentColor`)
   e nas linhas de contato o que muda é só o GLIFO, de `#88619e` para `#191919`
   (`.bt_bb_style_borderless:hover a.bt_bb_icon_holder:before { color: var(--secondary-color) }`,
   `01-content_elements.crush.css:3021-3023`; o par inline do widget é
   `--icon-primary:#88619e` / `--icon-secondary:#191919`), enquanto rótulo, link e holder
   ficam exatamente como estavam. Na réplica o glifo é um `<svg>` irmão do `<a>`, então o
   gatilho é a linha inteira — mesma área de acerto do `.bt_bb_icon` do original, inclusive
   na linha de endereço, que no vivo é `span` e não âncora.
   A regra anterior pintava menu e contatos de roxo e não tinha fonte no corpus. */
.footer-nav a:hover {
    opacity: .5;
    color: currentColor;
}

.footer-info li:hover .footer-info-ico {
    color: #191919;
}

.footer-address {
    margin: 0;
}

/* Coluna PRESENÇA: entre o `<h5>` do título e o mapa há um `bt_bb_separator` de
   `m=0px/14px` (vivo: título fecha em 45,8 e o `<img>` começa em 59,8). A variável de
   banda (16px) deixava a réplica 2px baixa no topo e 2px alta no fim da coluna. */
.footer-map img {
    margin-top: 14px;
}

/* Coluna eSocial: no vivo a ordem é **logo primeiro, texto depois** (`home.html`: o
   `<span>` do upload `es-logo1.png` e só então o `<header class="bt_bb_headline
   desc-esocial bt_bb_dash_top bt_bb_subheadline bt_bb_size_extrasmall">`, com um
   separador `m=28px/8,75px` entre eles que colapsa nos 14px efetivos medidos — 92 → 106).
   `inline-custom.css:101` trava `width: 80%` (228 de 285) e a folha do builder devolve o
   par do subheadline de `extrasmall`: `font-size: .875rem` (14) + `line-height: 1,5em`
   (21) + `margin-top: 1em` (14). A caixa de 11 linhas mede 231 no vivo; com 12,25px em
   largura total a réplica fechava em 189 (9 linhas). */
.footer-esocial img {
    margin-top: 0;
}

.footer-esocial p {
    width: 80%;
    font-size: 14px;
    line-height: 1.5em;
    margin: 14px 0 0;
}

/* A faixa inferior é a 3ª linha da seção do rodapé e vem COLADA nas colunas: a linha dos
   widgets fecha em 472,8 e o separador sólido começa em 472,8 (`qa/foot-tree-live-1440`),
   sem margem. O par medido do separador é `2px + m=0/28px` (`qa/foot-leaf-live-1440`,
   `[col 5] altura=30`), e 28 = `2em` sobre a base do rodapé — a 992 a mesma régua lê
   24,5 (`2em` de 12,25 ✓). Antes a réplica punha 40 de margem acima e 24 de forro abaixo. */
.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    /* topo com topo, não centro com centro. No vivo a faixa são DUAS colunas do builder e as
       duas caixas nascem no mesmo y (medido 19/10, `qa/foot-credit.mjs`: texto do crédito em
       845,4, `<img>` da agência em 845,4 e o `ul` do menu em 845,4). Com `align-items: center`
       o menu de 24px centralizava no crédito de 27 e caía 1,5px abaixo (846,9) — é o
       desalinhamento vertical da logo que o operador apontou, e a diferença de 3px entre as
       duas alturas é do próprio crédito (a imagem de 20 assentada na baseline estoura a linha,
       ver o bloco `.footer-credit` abaixo), não do menu. */
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--imass-spacing-sm);
    margin-top: 0;
    padding-top: 2em;
    /* O divisor é uma linha do builder SEM classe de ocultação, então aparece nas
       duas variantes: `.bt_bb_separator.bt_bb_border_style_solid` com
       `border-bottom:1px solid #ccc` (`01-content_elements.crush.css:3277`), o
       `style="border-width: 2px"` inline (`html/home.html`, faixa acima do menu) e a
       cor do tema-pai por cima: `.btLightSkin … { border-bottom-color:
       rgba(24,24,24,.1) }` (`09-style.css:22044-22053`). */
    border-top: 2px solid rgba(24, 24, 24, .1);
}

/* O menu do rodapé não é flex: no original a faixa é uma linha `4/8`, o crédito fica na
   coluna da esquerda (`x=120`) e o menu na da direita, encostado na borda de tinta
   (última âncora termina em `x=1320`, `qa/foot-band2-live-1440`). As duas regras que fazem
   isso são `margin: 0 -1em` no invólucro (`09-style.css:4429-4433`) e `margin: 0 1em` +
   `display:inline-block` + `white-space:nowrap` em cada item (`:4434-4439` e `:4469-4473`);
   o `-1em` devolve exatamente o `1em` que sobra à direita do último item, então a conta
   fecha na borda. A réplica montava a faixa em flex com `gap: 18px` e ordem invertida
   (menu à esquerda em `x=120`, crédito à direita), e o vão entre âncoras não seguia a base.
   O `text-align:right` vem da coluna `bt_bb_align_right` do congelado. */
.footer-nav ul {
    list-style: none;
    margin: 0 -1em;
    padding: 0;
    text-align: right;
}

.footer-nav li {
    display: inline-block;
    margin: 0 1em;
    white-space: nowrap;
}

/* O sub-menu da menu do rodapé não aparece em NENHUM viewport: a folha do tema-pai
   tem `.btSiteFooter .btBottomFooterMenu li ul { display:none }` sem `@media`
   (`09-style.css:4474`). As três páginas de serviço continuam no HTML, escondidas. */
.footer-nav .footer-nav-sub {
    display: none;
}

/* O crédito desktop é, no original, UMA linha de texto com a imagem flutuando ao lado
   (`<div style="float:left">IMASS – …Por</div><div style="float:left;margin-left:8px">logo</div>`,
   `html/home.html` faixa `bt_bb_hidden_xs bt_bb_hidden_ms`). O glifo medido é a caixa:
   a régua da faixa fecha em 27 px (`qa/foot-band2-live-1440`) contra 24 do `line-height`
   herdados — a imagem de 20 assentada na BASELINE estoura a linha em 3 px. Por isso o
   invólucro NÃO é flex (flex centralizaria os dois e devolveria 24) e o vão é o
   `margin-left: 8px` do float, não um `gap`: com `gap` a largura do bloco dava 320,9
   contra 316,4 do vivo, deslocando a logo 4,5 px para a direita. */
.footer-credit {
    display: block;
    flex: 0 0 auto;    /* sem isso a linha flex encolhe o bloco para o min-content
                          (275,4 = a altura do texto sem a logo) e a imagem cai para a
                          2ª linha: a faixa passaria de 27 para 44 px */
    margin: 0;
}

.footer-credit a {
    margin-left: 8px;
}

/* Faixa de copyright desktop (`.bt_bb_hidden_xs.bt_bb_hidden_ms` do original). */
.footer-copyright {
    display: none;
    margin: 0;
}

.footer-credit img {
    display: inline;                   /* o reset global (`img { display:block }`, linha 190
                                          desta folha) jogaria a logo para uma linha própria
                                          dentro do `<a>` inline — caixa anônima de bloco — e a
                                          faixa do crédito saltaria de 27 para 44 px. No
                                          original a logo é um atômico inline ASSENTADO NA
                                          BASELINE: é exatamente isso que estoura a linha de
                                          27 px (texto 16 + estouro 4 em cima + 7 em baixo). */
    vertical-align: middle;            /* 19/10: o operador apontou que a logo estava "mais alta
                                          do que deveria" — na baseline ela estoura 4 px para
                                          cima e 7 px para baixo, enquanto o texto fica no fundo.
                                          Com `middle` os dois se encontram no centro da linha
                                          de 24 px (texto 16 + 4 em cima + 4 em baixo; logo 20
                                          + 2 em cima + 2 em baixo). */
}
                                          24 para os 27 px medidos (`qa/foot-band2-live-1440`,
                                          img y=+502,8 h=20 contra strong y=+506,8 h=16, os
                                          dois fechando em 522,8 = a baseline) */
    height: 20px;                      /* `width="41" height="20"` no congelado e 41×20 medidos
                                          no vivo; eram 22 aqui */
    width: auto;
}

/* ==========================================================================
   WhatsApp Flutuante — padrão nativo dos temas DWP (D-06): o mesmo FAB de
   provecta (`assets/css/theme.css:1283-1368`) e construtoraset (`:679-733`),
   4rem, gradiente verde, glifo branco, balão de rótulo.

   Por que o wrapper (`.imass-fab-nav`) e não a âncora carregando a animação: medido 19/10
   (`qa/fab-r25-replica-home.log`) no estado anterior — com `animation: imass-fab-in … both`
   NA ÂNCORA, o `transform` do `:hover` (`translateY(-2px)`) nunca aplicava, porque uma
   animação preenchida vence o valor declarado. Repouso `matrix(1,0,0,1,0,1,8e-07)` → hover
   `matrix(1,0,0,1,0,0)`: zero de elevação, botão morto ao ponteiro. É a razão declarada no
   comentário do padrão (`provecta:1285-1287`) e agora a nossa também.

   O balão é CSS (`::after`), não `title`: é o que a casa faz, e o motivo medido é que o
   `title` nativo não tem tempo, posição nem tinta controláveis — e o FAB não tinha NENHUM
   rótulo visível (nenhum pseudo gerado: `content:none` nos dois estados, 19/10).
   ========================================================================== */

@keyframes imass-fab-in {
    from { opacity: 0; transform: translate(1rem, 1rem) scale(.9); }
    to   { opacity: 1; transform: none; }
}

@keyframes imass-fab-float {
    from { transform: translateY(0); }
    to   { transform: translateY(-3px); }
}

.imass-fab-nav {
    position: fixed;
    right: clamp(1rem, 3vw, 1.5rem);
    bottom: clamp(1rem, 3vw, 1.5rem);
    z-index: 1040;
    animation: imass-fab-in 600ms ease-out 2s both,
               imass-fab-float 6s ease-in-out 2.8s infinite alternate;
    will-change: transform;
}

.whatsapp-float {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    border-radius: 50%;
    background-image: linear-gradient(135deg, #25d366 0%, #128c7e 100%);
    /* Glifo branco a 1,75rem — os mesmos 28px da casa. A tinta é LETRAFORM (f232 da
       FontAwesome portada, §5): a âncora anterior trazia um `<svg>` de duas sub-rotas sem
       `fill-rule`, o contraforme do fone se fechava no nonzero e saía um blob branco de
       28×28 (`qa/fab-glyph-fab.png`). Custo de contraste declarado na casa: branco sobre
       #25d366 = 1,98:1 e sobre #128c7e = 4,14:1 — abaixo do piso de 3,0 na metade clara. */
    color: #fff;
    font-size: 1.75rem;
    line-height: 1;
    box-shadow: 0 12px 28px rgba(0, 0, 0, .25);
    text-decoration: none;
    transition: transform .2s ease, box-shadow .2s ease, filter .2s ease;
}

/* Travas de estado: `a:hover{color:var(--imass-primary)}` (`:234`) tem especificidade 0,1,1
   e pintaria o `currentColor` do glifo de roxo no hover — o mesmo vazamento que a casa
   documenta para o reboot do Tabler (`provecta:1319-1323`). */
.whatsapp-float:hover,
.whatsapp-float:focus,
.whatsapp-float:active,
.whatsapp-float:visited {
    color: #fff;
    text-decoration: none;
}

.whatsapp-float:hover {
    transform: translateY(-2px);
    box-shadow: 0 16px 36px rgba(0, 0, 0, .28);
    filter: brightness(1.02);
}

.whatsapp-float::after {
    content: 'Fale pelo WhatsApp';
    position: absolute;
    right: calc(100% + .5rem);
    bottom: 50%;
    transform: translateY(50%) translateX(4px);
    padding: .35rem .6rem;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, .75);
    color: #fff;
    font-size: .875rem;
    white-space: nowrap;
    box-shadow: 0 8px 20px rgba(0, 0, 0, .25);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease, transform .2s ease;
}

.whatsapp-float:hover::after,
.whatsapp-float:focus-visible::after {
    opacity: 1;
    transform: translateY(50%) translateX(0);
}

@media (prefers-reduced-motion: reduce) {
    .imass-fab-nav {
        animation: none;
    }

    .whatsapp-float,
    .whatsapp-float::after {
        transition: none;
    }
}

/* ==========================================================================
   Preloader de marca — `#btPreloader` do tema-pai (Fase 2 varredura de superfície, 17/10)

   Oráculo: markup no corpo de 11 de 11 páginas congeladas (`home.html`: `#btPreloader` é o
   primeiro filho de `<body>`, antes de `.btPageWrap`) e contrato em `09-style.css`
   :1133-1215 (camada + logo), :1218-1269 (as caixas) e os `@keyframes lds-ellipsis1/2/3`
   de :1292/:1329/:1366; `z-index` em :1007-1009.

   Dois valores vêm do `<style>` inline do tema (`avantage-style-inline-css`), não da folha:
    - `.btPreloader .animation .preloaderLogo{height:68px}` — vence os `140px` de
      `09-style.css:1199` (mesma especificidade, escrita depois) e é o mesmo `68px` do logo
      do header;
    - `.btLoader > div, .btLoader > span{background:#88619e}` — é `--imass-primary`; o
      `#e94d65` de `09-style.css:1231` é o vermelho do tema-pai, que aqui nunca chega.

   O que NÃO se porta, com o motivo medido:
    - a "pílula" `.animation > div:first-child{background:#e94d65;padding:.7em 1.2em;
      border-radius:5px}` (:1168-1178): os três seletores são `.btAccentDarkHeader`,
      `.btLightAccentHeader` e `.btTransparentLightHeader`; o `<body>` do imass é
      `btTransparentDarkHeader` (`home.html`) ⇒ a regra não casa e o logo fica sem caixa;
    - a 5ª/6ª caixas: `:1264-1269` as põe `display:none`, então há 4 pontos visíveis dos 5
      `<span>` impressos — o markup é portado inteiro, o CSS é que esconde;
    - `.bodyPreloader`: zero regras em `09-style.css`; é bandeira do `main.js` do tema-pai.

   Desvios: as 3 caixas não giram sob `prefers-reduced-motion` (o `#88619e` pulsando em loop
   é o único movimento infinito da página) e `<noscript>` esconde a camada no layout.
   ========================================================================== */
.btPreloader {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 100000;
    display: flex;
    align-items: center;
    width: 100%;
    background-color: inherit;
    text-align: center;
    opacity: 1;
    transform: translate(0, 0);
    transition: all 800ms ease;
}

.btPreloader .animation {
    display: block;
    width: 100%;
    transform: translateY(0) scale(1);
    transition: transform 300ms ease, opacity 300ms ease;
}

.btPreloader .animation > div img {
    margin: 0 auto;
}

.btPreloader .animation .preloaderLogo {
    display: block;
    width: auto;
    height: 68px;
    line-height: 1;
    transition: all 500ms ease;
}

.btRemovePreloader .btPreloader {
    opacity: 0;
    transform: translate(0, -100%);
}

.btRemovePreloader .btPreloader .animation {
    opacity: 0;
    transform: translateY(0) scale(.9);
    transition: transform 500ms ease, opacity 500ms ease;
}

.btLoader {
    display: inline-block;
    position: relative;
    width: 64px;
    height: 64px;
}

.btLoader > span {
    position: absolute;
    top: 27px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--imass-primary);
    animation-timing-function: cubic-bezier(0, 1, 1, 0);
}

/* O shorthand `animation:` mora nos nth-child — como no original — de propósito: ele
   RESETA o `animation-timing-function` da regra acima para `ease` (especificidade maior
   ganha). Medido com `getComputedStyle` (`qa/preloader-dots.log`): o vivo computa `ease`,
   e a réplica que separava os longhands computava `cubic-bezier(0,1,1,0)` — os pontos
   saltavam +7 px nos primeiros 50 ms do ciclo e engatinhavam no resto (perfil fase×x na
   sonda), o "passo defeituoso" visto em tela. */
.btLoader > span:nth-child(1) {
    left: 6px;
    animation: imass-ellipsis1 .6s infinite;
}

.btLoader > span:nth-child(2) {
    left: 6px;
    animation: imass-ellipsis2 .6s infinite;
}

.btLoader > span:nth-child(3) {
    left: 26px;
    animation: imass-ellipsis2 .6s infinite;
}

.btLoader > span:nth-child(4) {
    left: 45px;
    animation: imass-ellipsis3 .6s infinite;
}

.btLoader > span:nth-child(5) {
    display: none;
}

@keyframes imass-ellipsis1 {
    0% {
        transform: scale(0);
    }
    100% {
        transform: scale(1);
    }
}

@keyframes imass-ellipsis3 {
    0% {
        transform: scale(1);
    }
    100% {
        transform: scale(0);
    }
}

@keyframes imass-ellipsis2 {
    0% {
        transform: translate(0, 0);
    }
    100% {
        transform: translate(19px, 0);
    }
}

@media (prefers-reduced-motion: reduce) {
    /* `:nth-child(n)` casa tudo com a mesma especificidade (0,2,1) do shorthand acima;
       sem ele o `animation: none` perdia para os nth-child e o desvio declarado morria. */
    .btLoader > span:nth-child(n) {
        animation: none;
    }
}

/* ==========================================================================
   Páginas de erro — `.btErrorPage` do tema-pai (Fase 0 extensão + 9.7)

   Oráculo: `referencias/html/erro-404.html`, congelado de
   https://imass.com.br/{caminho-falso} em 17/10, re-medido ao vivo (a 591px) com
   `getComputedStyle` no mesmo dia. Corpus: `09-style.css` (bloco "Error page",
   :1419-1640) + os `@media` tipográficos de :30857/:30925/:31032 + o
   `inline-custom.css:40-49` do cliente, que é o que decide cor do traço e a
   ausência do overlay.

   O que NÃO se porta, com o motivo medido:
    - o overlay claro (`bt_bb_background_overlay_light_solid`): o `inline-custom.css:46-49`
      do cliente o desliga (`:before{display:none}`) — medido `display:none` no vivo;
    - o traço acima da manchete (`.btErrorPage … .bt_bb_headline_content:before`):
      o `09-style.css:10106` mata `border-width` e `border-color` com `!important` e a
      re-declaração da página de erro (09-style + inline-custom) não tem `!important`,
      então perde. Medido `borderTopWidth: 0px`, `borderTopColor: rgba(0,0,0,0)` — a caixa
      existe (112px de largura, centrada) mas é invisível e não empurra nada;
    - `.error404 .btContentWrap{padding-top:0!important}`: no original o wrap é deslocado
      pela altura do header fixo; aqui a faixa é a primeira filha de `main` e `main` não
      tem padding, então não há o que zerar.

   A copy é a medida, em inglês, inclusive o `<title>` em português: é assim que o
   original responde (item (k) do plano propõe a tradução ao operador).
   ========================================================================== */

.btErrorPage {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Duas regras no corpus; a segunda (`min-height/height:100vh`, flex-centrada) é a que
       vale — a primeira (`70vh`, `background-position:10% bottom`) fica sem efeito. */
    min-height: 100vh;
    height: 100vh;
    background: url('/assets/themes/imass/img/backgrounds/bgn-404.jpg') 50% 50% / cover no-repeat;
}

/* `bt_bb_layout_boxed_1200` + o espaçamento `top/bottom_spacing_large` do builder.
   O `max-width` do port é [desktop]: a 591px ele mede `none` no original, e o cap só
   aparece na faixa larga — re-medir na Fase 10. */
.btErrorPage .bt_bb_port {
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    width: 100%;
    max-width: var(--imass-container-max);
    margin-inline: auto;
    padding-block: var(--imass-band-spacing);   /* medido 61,25px a 591px [desktop: 122,5px] */
}

/* A valeta de 30px por lado do builder mora no `.bt_bb_cell` (`09-style.css:833`,
   `max-width: calc(100% - 60px)`) — medido: port 591px, coluna 531px. O `<div>` extra do
   cell_inner/cell não é portado; o inseto entra direto na coluna, que é o mesmo caixa. */
.btErrorPage .bt_bb_column {
    flex: 1 1 100%;
    min-width: 0;
    max-width: calc(100% - 60px);
    padding: 0;                                 /* medido `padding:0` — sem `.bt_bb_row_holder` */
    text-align: center;
}

/* --- Superheadline: o texto ladeado por dois traços ------------------------- */

.btErrorPage .bt_bb_headline_superheadline {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 0 .6em;                           /* medido 10,8px sobre 18px */
    font-family: var(--imass-font-eyebrow);
    font-size: 1.125rem;                        /* 18px medidos; ≤360px cai para .9rem */
    font-weight: 400;
    line-height: 1;                             /* medido 18px */
    letter-spacing: 0;
    color: var(--imass-text);
}

.btErrorPage .bt_bb_headline_superheadline::before,
.btErrorPage .bt_bb_headline_superheadline::after {
    content: ' ';
    display: block;
    flex: 0 0 auto;
    width: 4.375rem;                            /* `bt_bb_size_huge` [≤768px: 2.5rem, medido 40px] */
    margin-top: -1px;
    border-top: 2px solid var(--imass-primary); /* `inline-custom.css:1` por cima do #e94d65 */
}

.btErrorPage .bt_bb_headline_superheadline::before {
    margin-right: 10px;
}

.btErrorPage .bt_bb_headline_superheadline::after {
    margin-left: 10px;
}

/* --- Manchete --------------------------------------------------------------- */

.btErrorPage .bt_bb_headline h2 {
    font-family: var(--imass-font-heading);
    font-size: 4.375rem;                        /* 70px só acima de 1399px [desktop] */
    font-weight: 800;
    line-height: 1.1;                           /* medido 61,6px sobre 56px */
    letter-spacing: -.03em;                     /* medido −1,68px sobre 56px */
    color: var(--imass-text);                   /* medido #181818, não o #202020 do corpo */
}

/* --- Subheadline: o CTA ----------------------------------------------------- */

.btErrorPage .bt_bb_headline_subheadline {
    margin-top: 2em;                            /* 28px medidos sobre o corpo de 14px */
    font-size: 1em;
}

/* O pill é o componente `.btn--primary` da §4 — os números medidos deste bloco
   (padding 15,75/26,25px, raio 50px, #88619e, inset −2px, hover −3px + sombra) já são
   os dele; aqui só entra o centrado. */

@media (max-width: 1399px) {
    .btErrorPage .bt_bb_headline h2 {
        font-size: 3.5rem;                      /* 56px medidos a 591px */
    }
}

@media (max-width: 768px) {
    .btErrorPage .bt_bb_headline_superheadline::before,
    .btErrorPage .bt_bb_headline_superheadline::after {
        width: 2.5rem;                          /* 40px medidos a 591px */
    }
}

@media (max-width: 360px) {
    .btErrorPage .bt_bb_headline h2 {
        font-size: 3rem;                        /* 48px — `09-style.css:31043` */
    }

    .btErrorPage .bt_bb_headline_superheadline {
        font-size: .9rem;
    }
}

/* ==========================================================================
   Reveal de scroll — `.animate` / `.animated` do Bold Page Builder
   (censo 17/10, rodada 5: 94 elementos `.animate` no `<body>` de 10 das 11 páginas
   congeladas; a réplica não tinha nenhum).

   Fonte do contrato (nada aqui é chutado):
    - cascata `01-content_elements.crush.css`, todas em `[base]`, zero media query:
        .animate                       transition: transform 1000ms cubic-bezier(.190,1,.220,1),
                                                  opacity 1000ms cubic-bezier(.190,1,.220,1)
        .bt_bb_animation_fade_in       opacity: 0        → .animated { opacity: 1 }
        .animate[class*="move_up"]     translate3d(0, 30px, 0)   ┐
        .animate[class*="move_left"]   translate3d(30%, 0, 0)    │ .animated → translate3d(0,0,0)
        .animate[class*="move_right"]  translate3d(-30%, 0, 0)   ┘
        .animate[class*="zoom_out"]    scale(1.3)  /  zoom_in scale(.7)  → .animated scale(1)
      `move_left` = o elemento vem da DIREITA (+30%); `move_right` = vem da ESQUERDA (−30%).
    - stagger por posição da coluna na linha (`.bt_bb_row_holder`, que é o pai):
        nth-child(n) → 200ms × n   (200/400/600/800…)
        .animate aninhado dentro do 1º filho → 300ms + 100ms × (n−1)   [não usado na réplica]
        .btArticleListItem → 200ms fixo (a regra `:not(.btArticleListItem)` exclui o card de
        listagem do stagger; `09-style.css:5688` repete os 200ms)
    - disparo: `content_elements_misc.js` → IntersectionObserver `{root:null,
      rootMargin:'0px', threshold:0}`, one-shot (`unobserve` no primeiro entry), armado no
      `window.load` (+500ms quando o `<body>` tem `bodyPreloader`, que é o caso do imass).
      Fallback do original (browser sem IO) = `isOnScreen()` a cada scroll, com 75px de folga.

   Nomes da réplica: `data-reveal` leva o VARIANTE medido (`fade` = fade_in, `zoom` =
   fade_in+zoom_out, `up` = fade_in+move_up, `left`/`right` = fade_in+move_*) e o estado
   final é `.is-revealed` (análogo de `.animated`). A bandeira de armado é outro atributo,
   `data-reveal-arm`, para `[data-reveal]` casar só com conteúdo — com o mesmo nome, o
   `<html>` entrava na própria seleção (19 nós na home em vez dos 18 medidos, 17/10).

   Três desvios, todos deliberados e nomeados:
    1. **Armar só com JS.** No original o `opacity:0` vem da folha e o elemento nasce
       invisível: sem JS, a página inteira fica branca. Aqui o estado oculto só existe sob
       `html[data-reveal-arm="on"]`, atributo que um script inline no `<head>` põe antes da
       primeira pintura; `theme.js` o troca para `off` quando não há IO ou quando o usuário
       pede menos movimento. Same pixels para quem tem JS, nenhuma página em branco para
       quem não tem. (Mesma lógica do `<noscript>` do preloader, rodada 9.7/2.6.)
    2. **`prefers-reduced-motion: reduce` desliga.** O original não tem essa guarda; a
       réplica já trata reduced-motion no autoplay do herói e no parallax de faixa.
    3. **`overflow-x: clip` no `<main>`.** Medido a 591px com as transições congeladas e os
       nós armados: `documentElement.scrollWidth` 679 contra viewport de 591 = 88px de
       transbordamento horizontal, e o maior ofensor é exatamente os 15% de 591px que o
       `scale(1.3)` de uma coluna de largura toda empurra para fora (`.cta-band .container`
       terminava a 680px). O builder corta isso só em layout wide
       (`01-content_elements.crush.css:1359`, `overflow-x: clip` no `.bt_bb_row`); as faixas
       do imass são `bt_bb_layout_boxed_1200`, ou seja, no original o mesmo deslocamento
       estoura. A réplica tem outra regra (zero rolagem horizontal — cabeçalho da seção
       Responsivo), então o corte é no invólucro full-bleed `<main>`: nada visível é
       ceifado, só o que já estava fora do viewport.
   ========================================================================== */

main {
    overflow-x: clip;
}

[data-reveal] {
    transition: transform 1000ms cubic-bezier(.190, 1, .220, 1),
                opacity 1000ms cubic-bezier(.190, 1, .220, 1);
    transition-delay: 200ms;                     /* coluna 1 da linha */
}

html[data-reveal-arm="on"] [data-reveal]:not(.is-revealed) {
    opacity: 0;
}

html[data-reveal-arm="on"] [data-reveal="up"]:not(.is-revealed) {
    transform: translate3d(0, 30px, 0);
}

html[data-reveal-arm="on"] [data-reveal="left"]:not(.is-revealed) {
    transform: translate3d(30%, 0, 0);
}

html[data-reveal-arm="on"] [data-reveal="right"]:not(.is-revealed) {
    transform: translate3d(-30%, 0, 0);
}

html[data-reveal-arm="on"] [data-reveal="zoom"]:not(.is-revealed) {
    transform: scale(1.3);
}

/* Stagger — rodada 16 corrige o modelo da rodada 15. A escada do `.animate` do builder
   (`01-content_elements.crush.css`) é MONOTÔNICA `200·N` pelo `nth-child` dentro do
   contentor/`.bt_bb_row_holder` (medido: nth-child(1)=200, (2)=400, (3)=600, (4)=800 …
   até (20)=4000), SEM reset por linha visual. O `3n`/`4n` cíclico daqui estava certo só
   quando o contentor tinha exatamente a largura da linha do builder; quando uma grade é
   mais estreita que o row-holder e embrulha (ex.: row-holder de 6 colunas que a 591px
   rende 3 por linha), o original segue subindo (coluna 4 = 800, 5 = 1000, 6 = 1200) e a
   réplica reiniciava em 200. Logo: escada monotônica por contentor, com teto prático em
   2400 ms (a partir do 13º filho; nenhum row-holder real do imass passa de ~12 reveals). */
.grid-3 > [data-reveal]:nth-child(2),
.services-grid--wide > [data-reveal]:nth-child(2),
.services-grid--dense > [data-reveal]:nth-child(2),
.counters-grid > [data-reveal]:nth-child(2),
.split > [data-reveal]:nth-child(2) {
    transition-delay: 400ms;
}

.grid-3 > [data-reveal]:nth-child(3),
.services-grid--wide > [data-reveal]:nth-child(3),
.services-grid--dense > [data-reveal]:nth-child(3),
.counters-grid > [data-reveal]:nth-child(3) {
    transition-delay: 600ms;
}

.grid-3 > [data-reveal]:nth-child(4),
.services-grid--wide > [data-reveal]:nth-child(4),
.services-grid--dense > [data-reveal]:nth-child(4),
.counters-grid > [data-reveal]:nth-child(4) {
    transition-delay: 800ms;
}

.grid-3 > [data-reveal]:nth-child(5),
.services-grid--dense > [data-reveal]:nth-child(5) {
    transition-delay: 1000ms;
}

.grid-3 > [data-reveal]:nth-child(6),
.services-grid--dense > [data-reveal]:nth-child(6) {
    transition-delay: 1200ms;
}

.services-grid--dense > [data-reveal]:nth-child(7) {
    transition-delay: 1400ms;
}

.services-grid--dense > [data-reveal]:nth-child(8) {
    transition-delay: 1600ms;
}

.services-grid--dense > [data-reveal]:nth-child(9) {
    transition-delay: 1800ms;
}

.services-grid--dense > [data-reveal]:nth-child(10) {
    transition-delay: 2000ms;
}

.services-grid--dense > [data-reveal]:nth-child(11) {
    transition-delay: 2200ms;
}

.services-grid--dense > [data-reveal]:nth-child(n+12) {
    transition-delay: 2400ms;
}

@media (prefers-reduced-motion: reduce) {
    [data-reveal] {
        transition: none;
    }

    html[data-reveal-arm] [data-reveal]:not(.is-revealed) {
        opacity: 1;
        transform: none;
    }
}

/* ==========================================================================
   Responsivo — sticky do cabeçalho horizontal (≥1200)

   As regras de encolhimento do Avantage são todas escopadas pelo modo de menu
   (`inline-custom.css:68` `.btStickyHeaderOpen .port`, `:72`
   `.btStickyHeaderActive.btMenuHorizontal .mainHeader .btLogoArea .logo img`, e a linha
   `calc(68px*.5)` do `inline-custom.css:40`), e o logotipo da banda móvel tem regra
   própria que NÃO encolhe (`:55` `.btMenuVertical .btLogoArea .logo img{height:68px;
   margin-top:10px}`). Por isso ficam num bloco ≥1200 em vez de soltas no `.is-sticky`
   base: aplicadas em ≤1199 elas esmagariam a barra de 84 e colapsariam o painel do
   drawer em 34px de altura.

   Contrato medido no vivo (0.2a, `qa/port-oracle.json`, 1440 × scrollY 549):
   caixa `[0,0,1440,84]` = 30 + linha 34 + 20; logo 45,5×138,7 com a mesma tinta 15px
   acima da linha (`[60,15,…]`); `li` com `line-height:34px`; `.topBarInMenu` 34 de caixa
   com o botão de 46 a transbordar simetricamente (`[1218,24,…]`); sombra
   `rgba(0,0,0,.15) 0 2px 20px` (não os 30px que a réplica tinha).
   ========================================================================== */

@media (min-width: 1200px) {
    .site-header.is-sticky .header-inner {
        padding: var(--imass-header-pad-sticky);
    }

    .site-header.is-sticky .site-logo img {
        height: var(--imass-logo-height-sticky);
    }

    .site-header.is-sticky .main-nav {
        height: var(--imass-header-height-sticky);
    }

    .site-header.is-sticky .main-nav > ul > li > a {
        line-height: var(--imass-header-height-sticky);
    }

    .site-header.is-sticky .header-access {
        height: var(--imass-header-height-sticky);
    }
}

/* ==========================================================================
   Responsivo — drawer à direita (off-canvas de 320px do Avantage)

   A borda **1199/1200** é medida, não derivada: o próprio Avantage troca o modo do
   cabeçalho em JS conforme a janela, e o vivo (0.2a) pega a costura — viewport 1199 ⇒
   `body.btMenuVertical` (barra fixa de 84px + painel off-canvas), viewport 1200 ⇒
   `body.btMenuHorizontal` (linha `port` de 138px com logo à esquerda e menu/botão à
   direita). Acima disso as grades de conteúdo seguem a família ≤992 de `tokens.md`
   §6.11; só o cabeçalho muda de banda aqui.
   ========================================================================== */

@media (max-width: 1199px) {
    :root {
        /* Linha do cabeçalho na banda móvel = 84px, não 70. Duas medidas independentes:
           a regra `.btVerticalHeaderTop .btVerticalMenuTrigger { height:84px }`
           (`09-style.css:3481`, nível de topo, sem `@media` — vale enquanto o corpo está
           em modo vertical, que é a mesma banda do drawer abaixo) e o congelado
           `screenshots/01-home-591.png`: o logo tinta de y=10 a y=77,5 (68px de imagem,
           `--imass-logo-height`) ⇒ caixa centralizada em 84 dá prumo 8 e fim 76; as três
           barras do ☰ saem em y=28/41/54, que é `margin-top:24,5px` + `10/50/90%` de uma
           caixa de 35 dentro dos mesmos 84 (`09-style.css:3495`). */
        --imass-header-height: 84px;
        /* Na barra móvel a caixa pintada é a própria barra: `position:fixed`, 84px, sem
           forro de 40/30 (o forro de 40/60/30 é do `.port` horizontal). */
        --imass-header-box: 84px;
        /* Largura do painel off-canvas = os 320px fixos do builder
           (`.btMenuVertical .mainHeader{width:320px}`, `09-style.css:3723`); o mesmo valor
           é o tamanho do empurrão da página ao abrir. `88vw` só como teto em janelas <360. */
        --imass-drawer: min(320px, 88vw);
    }

    /* Na banda móvel o cabeçalho volta a ser a barra `[☰][logo]` de sempre, e ela é
       `position:fixed` — é `.btVerticalHeaderTop` (`09-style.css:3461`), com z-index
       10003 (`:3459`), enquanto em modo horizontal o header é sobreposição absoluta. */
    .site-header {
        position: fixed;
        z-index: 10003;
    }

    .site-header > .container {
        padding: 0 var(--imass-gutter);
    }

    .header-inner {
        display: flex;
        /* `flex-start`, não `center`: o logo da barra móvel tem `margin-top` próprio
           (`inline-custom.css:55`), e centrado o empurraria para 8px enquanto o congelado
           de 591 tints de y=10 a y=77,5. */
        align-items: flex-start;
        justify-content: flex-start;
        gap: 1rem;
        min-height: var(--imass-header-height);
        padding: 0;
    }

    /* Em flex o clearfix viraria um item (e ganharia o `gap`), e nada aqui flutua. */
    .header-inner::after {
        display: none;
    }

    .site-logo {
        float: none;
    }

    /* `.btMenuVertical .btLogoArea .logo img{height:68px;margin-top:10px}`
       (`inline-custom.css:55`) — na barra móvel o logo desce 10 do topo da caixa de 84,
       não sobe os 15px do modo horizontal. Congelado `screenshots/01-home-591.png`:
       tinta de y=10 a y=77,5 (68px) ⇒ 10 + 68 = 78, com 6px de sobra no fundo da barra. */
    .site-logo img {
        margin-top: 10px;
    }

    .menu-toggle {
        display: block;
    }

    /* Painel off-canvas à ESQUERDA, não à direita: `.btMenuVerticalLeft .mainHeader`
       (`09-style.css:3992-3997`) é `left:0; transform:translateX(-100%)` e abre em
       `translateX(0)` (:3999-4004). A curva é a do próprio builder: `transform 1s
       cubic-bezier(.23,1,.32,1)` (:3674-3677 e :3733-3736). Ao abrir, a PÁGINA inteira
       é empurrada para a direita — `.btMenuVerticalLeft.btMenuVerticalOn .btContentWrap,
       .btVerticalHeaderTop, .btSiteFooter{transform:translateX(320px)}` (:3678-3684) — e a
       logo da barra some (`... .btVerticalHeaderTop .logo{opacity:0;pointer-events:none}`
       :3694-3697). Não há véu escuro: o que aparece à direita é o conteúdo deslocado. */
    .main-nav {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        float: none;
        width: var(--imass-drawer);
        height: auto;
        /* A coluna de 200px do painel NÃO vem de `width:200px` em item nenhum: no vivo ela é
           o conteúdo do `.port` do drawer, cujo `padding:40px 60px 30px` (CSS inline de opções
           do tema Avantage, medido em `qa/live-panel-chain.mjs`) recorta 320−120=200 a x=60 —
           logo, âncoras e botão de acesso herdam a mesma coluna. Os 10px extras do topo
           (logo a y=50, não y=40) são a linha de caixa do `.btHorizontalMenuTrigger` vazio
           (0×0) que precede a logo no `.port`; a réplica os dobra no padding-top. */
        padding: 50px 60px 30px;
        background-color: var(--imass-white);
        box-shadow: none;
        overflow-y: auto;
        overscroll-behavior: contain;
        text-align: center;
        z-index: 10003;
        transform: translateX(-100%);
        transition: transform 1s cubic-bezier(.23, 1, .32, 1);
        visibility: hidden;
    }

    .main-nav.is-open {
        transform: translateX(0);
        visibility: visible;
    }

    /* O empurrão da página, chaveado no `nav-lock` que o JS já alterna no <body>. A
       transição fica na BASE (não só sob `nav-lock`) para o fechamento também deslizar. */
    .site-main,
    .site-footer,
    .menu-toggle {
        transition: transform 1s cubic-bezier(.23, 1, .32, 1);
    }

    .site-logo {
        transition: opacity 1s cubic-bezier(.23, 1, .32, 1);
    }

    body.nav-lock .site-main,
    body.nav-lock .site-footer {
        transform: translateX(var(--imass-drawer));
    }

    /* A barra do topo acompanha: o ☰ vira o botão de fechar na borda direita e a logo
       some — o painel tem a própria logo. */
    body.nav-lock .menu-toggle {
        transform: translateX(var(--imass-drawer));
    }

    body.nav-lock .site-logo {
        opacity: 0;
        pointer-events: none;
    }

    /* O empurrão de +320px faz o conteúdo transbordar a janela (`scrollWidth` 710 a 390) e no
       celular o Chrome responde ao transbordo alargando o viewport de layout: `innerWidth`
       ia a 710, `innerHeight` a 1537 e o painel "crescia" para 320×1537 sem que nenhuma
       regra de altura tivesse mudado (`qa/viewport-probe.mjs`, `qa/lock-variants.mjs`).

       O original tranca isso em duas peças: `body.btMenuVerticalOn{width:100vw;overflow:hidden}`
       (`09-style.css:4358-4362`, comentado como "Prevent horizontal scroll on small screens
       when menu is open") e o invólucro `div#top.btPageWrap{overflow:hidden}`, que é quem
       CLIPA o conteúdo empurrado (medido no vivo: `.btContentWrap` com `translateX(320)` e
       `scrollWidth` 788 dentro de um `.btPageWrap` de 390). A réplica não tem esse invólucro
       — `.site-main` e `.site-footer` são filhos diretos do `body` — e o `overflow` do `body`
       sozinho é propagado ao viewport (o `html` é `visible`), então o `body` não recorta nada.
       Travar o `html` encerra a propagação e devolve ao `body` o papel de recorte.
       Resultado medido: `scrollWidth` 390, `innerHeight` 844 e painel 320×844, igual ao vivo. */
    html.nav-lock {
        overflow-x: hidden;
    }

    body.nav-lock {
        width: 100vw;
        overflow: hidden;
    }

    /* Logo própria do painel (`.btMenuVertical .mainHeader .logo`, :3789-3792), centrada
       no topo; some fora da banda móvel. */
    .main-nav .nav-logo {
        display: block;
        /* Rodada 28 (pedido do operador: "A logo no menu mobile está deformada. Ajuste-a por
           favor, e dê um pouco mais de espaçø entre a logo e os menus abaixo"). O contrato do
           vivo (padding 0 2em ⇒ coluna de 144, mais `height:68px` fixo) ESTICAVA a logo fora
           da proporção natural 250×82 — lixo do original que a rodada anterior mantinha. Aqui
           virou DESVIO AUTORIZADO: sem padding lateral, a img ocupa os 200px cheios da coluna
           em proporção natural (200×65,6), e o `margin-bottom:16px` abre o vão pedido até os
           menus de baixo. */
        padding: 0;
        margin: 0 0 16px;
    }

    .main-nav .nav-logo img {
        display: block;
        width: 100%;
        height: auto;
    }

    .main-nav ul {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        /* `.menuPort{padding-top:1em}` (`09-style.css:4160-4166`): 16px de corpo, e é isso
           que põe a primeira âncora em y=134 (50+68+16). O `padding-bottom` do `.menuPort`
           NÃO fica aqui: no vivo ele vem DEPOIS do botão (`.topBarInMenu` é irmão do `nav`
           dentro do `.menuPort`), então desce para a margem de `.nav-access`. */
        padding: 16px 0 0;
    }

    .main-nav > ul > li {
        float: none;
        padding-right: 0;
    }

    /* O fio separador entre as linhas — inclusive sob o item corrente e sob a última. A
       largura de 200 já vem da coluna do painel; forçar `width:200px` aqui era o remendo
       de antes da coluna existir. */
    .main-nav li {
        border-bottom: 1px solid rgba(24, 24, 24, .1);
    }

    .main-nav a {
        /* `1em 2em` de `.btMenuVertical .mainHeader nav ul li a` (`09-style.css:3855`);
           em 16px ⇒ 16/32 e caixa de 50 com `line-height:1.1` (17,6 medido no vivo). */
        display: block;
        padding: 1em 2em;
        line-height: 1.1;
        min-height: 0;
        text-align: center;
    }

    .main-nav .is-current > a::after {
        display: none;   /* no drawer o estado vem do fundo, não do tick */
    }

    /* Item corrente = bloco roxo cheio com letra branca (medido no vivo: bg
       rgb(136,97,158), color rgb(255,255,255)), não letra roxa sobre branco. */
    .main-nav .is-current > a {
        background-color: var(--imass-primary);
        color: var(--imass-white);
    }

    /* Chevron do `.subToggler` (40×57, opacity .5, vira 180° aberto) como afixo da âncora
       pai, encostado à direita da caixa de 200. */
    .main-nav .menu-item-has-children > a {
        position: relative;
    }

    .main-nav .menu-item-has-children > a::after {
        content: "";
        position: absolute;
        right: 12px;
        top: 50%;
        width: 8px;
        height: 8px;
        margin-top: -6px;
        border-right: 2px solid currentColor;
        border-bottom: 2px solid currentColor;
        transform: rotate(45deg);
        opacity: .5;
        transition: transform 300ms ease;
    }

    .main-nav .menu-item-has-children.is-open > a::after {
        transform: rotate(-135deg);
        opacity: 1;
    }

    /* `.main-nav ul` (0,1,1) vence uma classe solta — por isso o seletor do
       submenu no drawer carrega a classe do pai.

       `font-size:16px` ancora o `.9em` do subitem: sem ele o `.sub-menu` herda os 14px do
       `body` na banda móvel e `.9em` dava 12,6px (medido em `qa/mobile-replica-detail.mjs`),
       contra 14,4px do vivo — que herda 16 do menu. Como o `padding:1em 2em` do subitem é
       relativo à PRÓPRIA fonte, o mesmo desvio aparecia no vão (12,6/25,2 contra 14,4/28,8). */
    .main-nav .sub-menu {
        position: static;
        min-width: 0;
        width: auto;
        padding: 0;
        font-size: 16px;
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transform: none;
        box-shadow: none;
        display: none;
    }

    .main-nav .menu-item-has-children.is-open > .sub-menu {
        display: flex;
    }

    /* A seta (rabo de balão) é afixo da caixa dropdown do desktop; no drawer o submenu é
       inline (`position:static`), então o triângulo absoluto em `top:75%` ficaria solto
       abaixo do item-pai. Some com ele aqui. */
    .main-nav .menu-item-has-children::before {
        display: none;
    }

    /* Subitens: 0.9em (14,4) e sem caixa-alta; o `1em 2em` herdado vira 14,4/28,8 por ser
       relativo à própria fonte — exatamente o medido no vivo. O peso 700 volta aqui porque
       no drawer vale `.btMenuVertical .mainHeader nav ul li a{font-weight:700}`
       (`09-style.css:3855-3860`) sobre os subitens também (medido `fw:700` no vivo), enquanto
       o dropdown do desktop os põe em 400 (regra acima, :724) — sem o 700 "Medicina
       Ocupacional" não quebra em duas linhas como no vivo. */
    .sub-menu a {
        font-size: .9em;
        font-weight: 700;
        text-transform: none;
    }

    /* Na banda móvel o botão sai da linha do cabeçalho e passa a viver no fundo do
       drawer — `.nav-access`, cópia da mesma âncora. `.topBarInMenu` é o último bloco do
       painel porque `.menuPort` inverte a coluna (`09-style.css:3816`), e o widget tem
       `margin: .5em .375em 0` (`09-style.css:3964`). */
    .header-access {
        display: none;
    }

    .nav-access {
        display: block;
        /* `.topBarInMenu{margin:32px 0 0}` medido no vivo (`qa/live-drawer-gaps.mjs`): o vão
           de 32px entre a última âncora e o wrapper do botão. O `16px` de baixo é o
           `padding-bottom` do `.menuPort` (`09-style.css:4160-4166`), que no vivo vem
           DEPOIS do botão porque ele é irmão do `nav` dentro do `.menuPort`. */
        margin: 32px 0 16px;
    }

    /* `.main-nav a` estica todo `<a>` do painel porque no original o painel só tem item de
       menu; o botão é outro papel (`.topBarInMenu`, não `nav ul li a`) ⇒ devolve-lhe a forma
       do desktop, que é a mesma âncora na outra banda. Medido no vivo (0.2a, painel aberto):
       `.topBarInMenu a` = **161,8×46**, a mesma caixa do desktop — não a largura do painel. */
    /* Botão de acesso em pílula roxa centrada (medido no vivo: fundo rgb(136,97,158),
       letra branca, raio cheio), não a âncora nua do desktop. */
    .main-nav .nav-access .access-link {
        display: inline-flex;
        padding: 16px 20px;
        justify-content: center;
        min-height: 0;
        font-size: 14px;
        line-height: 14px;
        background-color: var(--imass-primary);
        color: var(--imass-white);
        border-radius: 999px;
        /* O widget do original é um `inline-block` centrado pelo `text-align` da célula com
           `margin:8px 0 0 12px` (`qa/drawer-gap.mjs`, cadeia `.topBarInMenu`): os 8px abrem o
           wrapper para 54 de altura e os 12px deslocam a pílula de x=79 para x=85. */
        margin: 8px 0 0 12px;
        /* `.main-nav a` caixa-alta os itens de menu; o botão do original não
           (`textTransform:none` medido no vivo em `.topBarInMenu a`, e a regra de
           maiúsculas é do menu: `.menuPort nav > ul > li > a` em `inline-custom.css:60`). */
        text-transform: none;
    }

    /* Sem véu escuro: no original a página é EMPURRADA, não escurecida. O overlay fica
       transparente — só captura o clique fora e segura a rolagem (`nav-lock`). */
    .nav-overlay {
        position: fixed;
        inset: 0;
        z-index: 10002;
        background: transparent;
        opacity: 0;
        visibility: hidden;
        transition: opacity var(--imass-transition);
    }

    .nav-overlay.is-open {
        opacity: 1;
        visibility: visible;
    }
}

@media (min-width: 1200px) {
    .nav-overlay {
        display: none;
    }
}

body.nav-lock {
    overflow: hidden;
}

/* Tokens de ritmo de faixa: o forro corta em **768px inclusive**, medido na cascata
   congelada (`tokens.md` §6.11) — `.bt_bb_section.bt_bb_top_spacing_medium > .bt_bb_port`
   vale `5em` acima de 768 e `3em` em ≤768. O bloco ≤767 abaixo só mantém a escala do `h2`,
   medida no vivo a 591px; a linha do cabeçalho mudou de banda nesta rodada e hoje é decidida
   pelo corpus (84px em ≤992, acima). */
@media (max-width: 768px) {
    :root {
        --imass-spacing-xl: 40px;
        --imass-band-spacing: 4.375em;    /* trap ≤768 do original: 8,75em → 4,375em (61,25 a 14px) */
        --imass-band-spacing-medium: 3em; /* trap ≤768 (`09-style.css:10288`/`:10297`): 42px a 14px */
        --imass-band-spacing-extra-large: 12em; /* trap ≤768 (`09-style.css:10294`/`:10303`): 168px a 14px */
    }
}

@media (max-width: 767px) {
    h2 {
        font-size: 28px;
    }
}

/* Rodapé = duas linhas do builder: widgets `3-3-3-3` e barra de copyright `4-8`.
   Ritmo medido na cascata (`tokens.md` §6.11): 4 → 2×2 em ≤992 → 1 coluna em ≤768.
   A faixa inferior EMPIHA em ≤992 mas NÃO centraliza: a 992 o crédito continua na
   esquerda (`x=30`, tinte do col-4 virou linha inteira) e o menu continua à direita
   (`bt_bb_align_right`), com vão 0 entre os dois — `qa/foot-band2-live-992.log`.
   O `text-align:center` que existia aqui vinha de `.btFooterCopy`, classe que não está
   em nenhuma das 11 páginas congeladas; a centralização real acontece só na linha mobile
   (`bt_bb_align_center`), no bloco ≤768 abaixo. */
@media (max-width: 992px) {
    .footer-columns {
        grid-template-columns: repeat(2, 1fr);
    }

    .footer-bottom {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
    }
}

/* ≤768 = os dois breakpoints de ocultação do builder juntos: `xs` (≤480) e `ms`
   (481–768) — `01-content_elements.crush.css:827-837`. Medido na captura
   congelada (`01-home-591.png`, rodapé 4485→4887 = 402 px CSS): a 591 o original
   imprime SÓ a coluna ENDEREÇO e a faixa de copyright mobile; as três colunas e a
   faixa desktop somem. A réplica empilhava as quatro (1 185 px) — é aí que morava
   o "+783 px por página" que a medição de ritmo atribuía a espaçamentos soltos. */
@media (max-width: 768px) {
    /* O forro de cima da seção cai para `4.375em` nesta banda (`09-style.css:10291`):
       53,59 medidos a 768 sobre a base 12,25 do rodapé — `qa/foot-tree-live-*`. */
    .site-footer {
        padding-top: 4.375em;
    }

    .footer-columns {
        grid-template-columns: 1fr;
    }

    .footer-map,
    .footer-esocial,
    .footer-social {
        display: none;
    }

    .footer-credit {
        display: none;
    }

    .footer-copyright {
        display: block;
    }

    .footer-bottom {
        align-items: center;
        text-align: center;
    }

    .footer-nav ul {
        text-align: center;
    }

    /* Na variante mobile a faixa é uma coluna `col-12` com o texto, um
       `.bt_bb_separator bt_bb_top_spacing_normal` (`margin-top:2em`,
       `09-style.css:22090` ≈ 24,5px sobre a base 12,25px — `m=24,5px/0px` medido a 768
       em `qa/foot-leaf-live-768`) e só então o menu. O `gap` do flex precisa sair do
       caminho, senão soma aos 2em (40,5 px medidos). */
    .footer-nav {
        margin-top: 2em;
    }
}

/* ==========================================================================
   Impressão — `print.css` do tema-pai (Avantage), 11/11 páginas congeladas
   carregam a folha (`referencias/css/08-print.css`, 1 066 B, 11 regras).

   Mesma folha em todos os temas Avantage: não é estilo do site do cliente, é o
   comportamento de impressão do tema-pai, e por isso entra. Os seletores são
   traduzidos para o DOM da réplica (nós não temos `.mainHeader`, `.slick-*` nem
   `.bt_bb_button`); o que não tem equivalente aqui é declarado no fim.

   Tradução medida:
    - `.mainHeader`   → `.site-header` (fixo: impresso, repetiria em toda página)
    - `.btSidebar`    → não existe na réplica (o imass é `btNoSidebar` — medido no
                        `body` de `home.html`), nada a esconder
    - `.btSearchInner`→ idem: não há busca no original (censo de `<form>` em 10.2)
    - `.btAltLogo`    → `.site-logo` (o header já sai inteiro; listed por clareza)
    - `.btVerticalHeaderTop` → `.menu-toggle` + `.nav-overlay` (o gatilho do drawer
                        é o análogo do header vertical: controle, não conteúdo)
    - `.slick-arrow` / `.slick-dots` → `.hero-nav`, `.hero-dots`,
                        `.logo-carousel__arrow` — os controles das duas esteiras
    - `.animate`      → `[data-reveal]` (rodada 5: o reveal agora EXISTE na réplica, então a
                        regra deixou de ser dispensável). O tema-pai força
                        `display:block !important; opacity:1 !important` exatamente porque o
                        estado de repouso do builder é invisível; sem isso, o que o visitante
                        não rolou até a borda da tela sairia em branco no papel. Portada
                        literal — inclusive a ausência de `transform`, ou seja, um bloco ainda
                        não revelado imprime em `scale(1.3)` como imprimia no original.
                        O que fica fora da tela na réplica é a esteira em si (`.hero-track`,
                        `.logo-carousel__track`), e `overflow:visible` ali empilharia
                        4 slides / 29 logos em branco — o original imprime só o slide
                        ativo também, então o comportamento é o mesmo sem regra.
    - `.bt_bb_button a` → `.btn` (o pill roxo sairia como mancha escura sobre o
                        `*{background:#FFF}`; a borda de 2px preta é a do original).
                        O `span` interno da regra do tema-pai não tem equivalente:
                        censo em `frontend/` = zero `.btn` com `<span>`, então a
                        segunda regra daquelas linhas (`span{border:0}`) não é portada.
   Extras da réplica, mesma intenção das regras acima: `.btPreloader` (a camada de
   marca é `position:fixed` e sairia em toda página) e o FAB (`.imass-fab-nav` é o
   fixo; esconde-se o invólucro e a âncora junto).
   O mapa de `/contato` não aparece nesta lista porque no original também não: a
   `08-print.css` congélada (1.066 B) nomia 11 seletores e nenhum é do mapa, então a
   cobertura continua imprimindo. O `<iframe>`, sim, é escondido aqui — é o único
   pedaço do mapa que a réplica não imprime igual ao original, e a razão é que um
   embed de terceiros em papel sai como caixa vazia em qualquer motor de impressão.
   ========================================================================== */
@media print {
    @page {
        size: 210mm 297mm;
        margin: 0;
    }

    * {
        box-sizing: border-box !important;
        background: #fff !important;
        color: #000 !important;
    }

    body {
        font-size: 15px;
        line-height: 1.8;
        page-break-inside: avoid;
    }

    a {
        text-decoration: none !important;
        color: #000 !important;
    }

    .site-header,
    .menu-toggle,
    .nav-overlay,
    .hero-nav,
    .hero-dots,
    .logo-carousel__arrow,
    .map-cover__frame,
    .btPreloader,
    .imass-fab-nav,
    .whatsapp-float {
        display: none !important;
        opacity: 0 !important;
        visibility: hidden !important;
    }

    .btn {
        background: #fff !important;
        color: #000 !important;
        box-shadow: none !important;
        border: 2px solid #000 !important;
    }

    /* `.animate{display:block!important;opacity:1!important}` do tema-pai, ao pé da letra. */
    [data-reveal] {
        display: block !important;
        opacity: 1 !important;
    }
}
