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
- Dobra de tom vizinho que precisa ler como bloco fechado: um diagrama, um FAQ, um hub, um formulário — conteúdo que é denso e que não é continuação da seção anterior.
- Quando a seção tem forma própria por dentro e a emenda com a vizinha estraga essa forma.
- Duas, no máximo três vezes na mesma página.
Quando não usar
- Em toda seção. Moldura em tudo é moldura em nada, e a página vira álbum de figurinhas.
- Entre duas seções do mesmo tom. Sem diferença de fundo a faixa não tem o que dissolver: sobra a cercadura solta. Nesse caso use só o
.frame-edgee assuma que é acabamento, não moldura. - Quando você precisa de contraste real. É outra decisão editorial — vá de
.sec-paper(§3). - Em seção com foto de fundo. A faixa é camada de
backgroundda própria seção; imagem de fundo e faixa disputam o mesmo lugar. Para dobra com mídia, o contorno tem de vir de dentro do componente de mídia. - Como divisor entre hero e primeira dobra. O hero já termina em degradê próprio; dois degradês seguidos borram a virada.
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
-
A faixa é camada de
backgroundda seção, não pseudo-elemento. Consequência boa: ela fica atrás do conteúdo sem stacking context, semz-indexe semoverflow:hidden. Consequência a saber: se o<section>já usabackground-image(foto, textura), um dos dois perde. Moldura e mídia de fundo não convivem. -
Sem
overflow:hidden, e isso importa. A origem cortava a seção para conter os pseudo-elementos.overflow:hiddennuma seção mata oposition:stickyde qualquer componente colado dentro — olistas/baralho-stickypararia de grudar sem erro nenhum no console. Aqui não há corte. Não reintroduza. -
--frame-tonee--frame-tone-rgbandam em par. O fim do gradiente tem de ser a mesma cor com alfa 0. Trocar só um faz a faixa passar por um cinza no meio do caminho — o defeito é sutil e só aparece em tela boa. -
Faixa mais alta que
--sec-gapinvade o conteúdo. O padrão (13vh) já fica abaixo do respiro da dobra. Se subir--frame-band, confira em tela baixa, ondevhé pequeno e o texto sobe. -
A cercadura refaz a conta da coluna em
inset, não herda o.wrap. Ela alinha sozinha com--pade--max— mas mede 50% da seção. Se a seção ganhar padding lateral próprio (nenhuma da biblioteca ganha), a cercadura desalinha da coluna. -
Abaixo de 640px o losango some e o vão fecha junto. São duas linhas de CSS que andam casadas: esconder só o losango deixa um buraco de 34px no meio do filete.
-
Os chanfros são gradiente a 45°, não SVG. Um SVG em
data:URI não enxergavar(), então a cor da linha ficaria cravada dentro do componente — e a cor tem de vir do escopo de tom. O preço é que a diagonal é antialiasada e, em tela 1x, lê meio ponto mais macia que o filete reto. É o preço certo. -
.frame-edgenunca ganha conteúdo. Éaria-hiddene vazio. Um dia alguém vai querer pôr o número da seção ali dentro; esse dia é o dia em que a cercadura vira conteúdo escondido de leitor de tela.
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.