← Biblioteca componentes/efeitos/moldura-secao/ficha.md Abrir previewmarkupestilo
efeitos/moldura-secao

Moldura de seção

⚪ externo complexidade baixa prefixo frame- moldura quebra transicao-de-secao tom-vizinho gradiente cercadura css-puro sem-js decoracao sem javascript

Uma dobra de tom vizinho — .sec-deep entre duas .sec-dark — com as bordas dissolvidas. Duas faixas de gradiente, no topo e na base, pintam o tom das seções de fora e vão a zero para dentro: onde deveria haver uma emenda entre dois pretos parecidos, não há nada. Por cima, uma cercadura chanfrada marca onde a dobra começa e onde termina — dois chanfros de 30px mergulhando para os cantos, dois filetes e um losango de 6px no meio.

O componente não é a seção: é a junção. Ele não sabe nem quer saber o que está dentro.


Por que ele existe — §3 do contrato

O CLAUDE.md §3 fecha uma porta:

Fundos escuros adjacentes têm de ser quase idênticos (#0a0a0a / #131313). Salto forte de tom entre seções suja a página.

A regra está certa e cria um problema imediato: se a diferença entre a dobra e as vizinhas é quase imperceptível, como fazer a dobra ler como bloco à parte? As duas saídas óbvias são proibidas ou feias — subir o contraste desobedece à regra, e traçar uma linha reta na borda transforma a página em tabela.

Esta é a terceira saída, e a resposta canônica da biblioteca a essa regra: mantenha a diferença de tom minúscula, apague as duas emendas com um degradê que devolve o tom de fora, e marque o início e o fim com um acabamento fino. A dobra passa a ser emoldurada em vez de cortada. O olho registra "outro bloco" sem registrar "outra cor".

Quando o que você precisa é contraste de verdade, o §3 já responde por outro caminho: uma .sec-paper inteira como respiro — e aí o componente é o efeitos/quebra-papel-rasgado.


Quando usar

Quando não usar


Padrão editorial

Este componente não tem slot de texto — o que ele pede é arranjo de tons, e é isso que a tabela governa:

Slot Regra
Seção emoldurada Escopo de tom vizinho ao das seções de fora: .sec-deep (--dark-2) entre .sec-dark (--dark). Nunca um terceiro tom inventado.
Vizinha de cima Tem de terminar exatamente no tom que a faixa pinta (--frame-tone). Se ela for .sec-deep, troque o par de tom.
Vizinha de baixo Idem. A moldura fica torta se as duas vizinhas tiverem tons diferentes — nesse caso, use .frame--top ou .frame--bottom e emoldure um lado só.
Conteúdo interno Livre, e sempre dentro do .wrap. Título de seção, olho e apoio entram pelas primitivas do core, como em qualquer dobra.
Cercadura Sempre vazia. É decoração com aria-hidden — nem texto, nem ícone, nem número.
Quantidade 2 a 3 dobras emolduradas por página. A quarta anula o efeito de destaque das três primeiras.

Geometria

Medida Valor Por quê
Altura da faixa clamp(80px,13vh,180px) Some antes de encostar no conteúdo: sempre abaixo de --sec-gap (clamp(110px,14vh,160px)).
Chanfro 30px É também a altura da tira da cercadura. Abaixo de 20px o chanfro vira degrau; acima de 40px vira moldura de quadro.
Filete 1px, em --rule-2 Linha divisória forte do escopo. Em .sec-deep é #404040 — visível e sem brilhar.
Losango 6px, em --accent-2 O único ponto de cor da peça. É acento secundário de propósito: acento primário aqui compete com o botão da seção.
Vão do losango 17px de cada lado 14px de respiro + metade do losango. Some abaixo de 640px.

Como usar

<link rel="stylesheet" href="componentes/efeitos/moldura-secao/estilo.css">

Sem script. São duas peças, e a segunda é opcional:

<section class="sec-deep sec-pad frame">
  <div class="frame-edge frame-edge--top" aria-hidden="true"></div>
  <div class="frame-edge frame-edge--bottom" aria-hidden="true"></div>
  <div class="wrap">…</div>
</section>

Só a classe .frame já entrega a dissolução — os dois <div> acrescentam o acabamento chanfrado. As vizinhas continuam sendo as seções que você já tem; nada é colado nelas.

Ganchos

Gancho Papel
.frame na seção. As duas faixas de gradiente
.frame--top / .frame--bottom dissolve só uma das bordas
.frame-edge + --top / --bottom a cercadura. <div> vazio, aria-hidden, um por borda
--frame-band altura das duas faixas (--frame-band-top / --frame-band-bot para uma só)
--frame-tone / --frame-tone-rgb o tom da vizinha, em par: cor e canal RGB da mesma cor
--frame-cap lado do chanfro, no .frame-edge
--frame-gap meio vão em volta do losango
--frame-dm lado do losango (0 esconde)

Variações

Variação Como
Só uma borda .frame--top ou .frame--bottom
Sem cercadura apague os dois <div>
Cercadura sem faixa .frame-edge numa seção sem .frame
Vizinhas em outro tom style="--frame-tone:var(--dark-2);--frame-tone-rgb:19,19,19"
Faixa mais curta --frame-band:90px
Sem losango --frame-dm:0;--frame-gap:0 — o filete vira inteiriço

As cores não têm knob, e é de propósito: o filete lê --rule-2 e o losango lê --accent-2, os dois vindos do escopo de tom. É o que faz a mesma cercadura funcionar numa .sec-deep e numa .sec-paper sem uma linha de ajuste.


Gotchas


Histórico

Projeto Onde Data Diferenças
Liberta Wealth site/assets/css/style.css (.framed, .edge) usadas por #planejamento e #duvidas 2026-08 Origem. Faixas em ::before/::after com overflow:hidden e z-index no .wrap; cercadura em 7 nós por borda, com dois SVG inline; classes sem prefixo (.framed, .edge, .cap, .dm) e um seletor de elemento (.edge i); losango em --tan.

Status externo, e por quê. A regra só existe na composição site/ da Liberta Wealth, cuja ida a produção não está confirmada — na versão confirmada (github-repo/, o design system v5 que a biblioteca varreu) nem .framed nem .edge existem. Sem quilometragem de produção, §11 é claro: entra como externo. Não é origem de terceiro — foi construído em casa —, então não há autoria nem licença externa a creditar; o que falta é uso real. Rodando num site, vira estavel e esta tabela ganha a linha do projeto.

Normalizações aplicadas na extração:

Na origem Aqui Por quê
.framed, .edge, .cap, .dm .frame, .frame-edge, modificadores --top/--bottom §6.1: um prefixo, sempre. .edge e .cap colidem com qualquer projeto que junte dois componentes
.edge i{…} camada de background §6.3: zero seletor de elemento dentro de componente
.framed > .wrap{position:relative;z-index:2} não existe mais §4: o componente não encosta na primitiva do grid. Sem pseudo-elemento por cima, não há o que empurrar para baixo
.framed{overflow:hidden} não existe mais Corte na seção quebra position:sticky de componentes colados dentro
.edge .wrap como régua inset com a conta de --pad/--max Mesma razão: a coluna é do .wrap, e o componente não a reaproveita como estrutura
Faixas em ::before/::after camadas de background-image Fundo é fundo. Libera os dois pseudo-elementos da seção para quem colar outro componente no mesmo <section>
2 SVG inline por borda, com currentColor gradientes a 45° data: URI não lê var(); a cor tem de vir do escopo de tom
--tan cravado no losango --accent-2 §3: componente lê token, não cor de projeto
14 nós decorativos por seção 2 <div> vazios Markup decorativo repetido é ruído para quem cola o snippet
Altura da faixa e do chanfro cravadas --frame-band, --frame-cap, --frame-gap, --frame-dm Ajuste sem reescrever regra

A decisão de arquitetura: pseudo-elemento onde cabe, markup onde acabou

A origem repetia 14 nós de decoração por seção (dois .edge, cada um com .wrap, dois SVG, dois filetes e o losango). A pergunta na extração era se dava para zerar isso.

Deu, para a metade que importa. As faixas — o efeito essencial, a resposta ao §3 — não têm markup nenhum: são duas camadas de background da própria seção. Quem quiser só a dissolução escreve uma classe e acabou.

Não deu para a cercadura, e o motivo é estrutural: ela tem 5 marcas por borda (dois chanfros, dois filetes, um losango) e pseudo-elemento não tem pseudo-elemento. Os dois pseudos da seção já seriam poucos para as duas bordas; e o losango, sendo forma girada, não existe em camada de background sem virar quatro triângulos de gradiente. Zerar o markup custaria oito camadas por borda com listas de background-size e background-position casadas na unha — ilegível, frágil, e impossível de ajustar sem recontar posições.

O saldo: 1 nó vazio por borda, sem filhos, contra 7. O <div> vazio com aria-hidden é mais barato de manter e de entender do que a alternativa "elegante", e tem um bônus que a versão sem markup não teria: a cercadura passa a ser peça independente — dá para usar a faixa sem ela, ela sem a faixa, ou só numa das bordas.

Divergências conhecidas vs. produção: nenhuma verificável — a composição de origem não está publicada. O desenho (30px de chanfro, 6px de losango, clamp(80px,13vh,180px) de faixa) é o da origem, medida por medida.