Pular para o conteúdo
Foco em camadas

Padrões de tela

Foco em camadas

A assinatura do produto. Editar não acende um campo: afunda o resto. Quando um campo recebe foco, a tela recua em degraus e o bloco em edição sobe — ninguém precisa procurar onde estava.
globals.css6 atributosEditSurface + Field herdam

A demonstração é esta página

Toque no campo “Insumo” abaixo. A moldura do card e as linhas vizinhas recuam; o bloco levanta. Os atributos são os mesmos do app — nada aqui é figura.

Insumos

O cabeçalho é data-dim-keep: fura o véu e continua legível.

Insumo

O bloco em edição é data-dim. Campo sem foco é data-field, a 0.70.

Buscar insumo…
Agulha 30Gem 5 fichasR$ 0,24/un
véu do card 40% · bloco data-dim elevado (ink-50 + --shadow-lift) · campo sem foco a 0.70 · transições de 300ms
CamadaO que aconteceComo
Fundo da tela (menu do app, rail)recuaopacidade 0.65
Superfície (card, seção da ficha)recua juntopelícula de 40% por cima
Título da tela, cabeçalho do cardfica acesofura o véu (z-index 7)
O bloco em ediçãosobeink-50 + --shadow-lift (z-index 8)
Campos do bloco sem focorecuamopacidade 0.70

O vocabulário

Seis atributos, aplicados no JSX. A regra mora em globals.css — nenhuma tela reimplementa o efeito.
AtributoOnde vaiO que faz no foco
data-dimo bloco em edição (o tapete, a linha que virou form)sobe acima das películas e ganha ink-50 + sombra
data-dim-soltojunto de data-dim, quando o form está SEMPRE abertoa elevação vira pseudo-elemento: aparece sem empurrar layout
data-fieldcada campo do formulário (já vem no Field)o campo SEM foco recua pra 0.70; o em uso fica cheio
data-dim-veilsuperfície que recua junto (seção, tabela)película de 40% por cima; card já entra por data-slot
data-dim-keepcabeçalho da superfíciefura a película e continua legível
data-dim-farfundo da tela (sidebar do app, rail)opacidade 0.65 — sem película
o mínimo pra uma tela nova herdar tudo
<Card>                                   {/* recebe a película por data-slot */}
  <CardHeader data-dim-keep>…</CardHeader>  {/* fura o véu */}
  <CardContent>
    <EditSurface>                        {/* já traz data-dim */}
      <Field name="nome" label="Insumo" /> {/* já traz data-field */}
    </EditSurface>
  </CardContent>
</Card>

Película, nunca opacidade no container

A escolha técnica que faz o padrão existir. Opacidade cria contexto de composição: o valor desce pra TUDO que está dentro e nenhum filho volta a 1.

Sim

/* película desenhada POR CIMA — irmã do conteúdo */
[data-dim-veil]::after { background: var(--veu); opacity: .4 }
[data-dim-keep] { z-index: 7 }   /* fura  */
[data-dim]      { z-index: 8 }   /* sobe  */

Quem precisa ficar aceso só sobe de camada. Nada herda nada.

Não

/* opacidade no container — desce pra tudo */
[data-dim-veil] { opacity: .6 }
[data-dim]      { opacity: 1 }   /* não volta: já é .6 do pai */

Três tentativas morreram aqui: apagou o campo em edição, o rótulo dele e os botões Salvar/Cancelar.

Armadilhas já pagas

Cada uma custou uma rodada de ida e volta — ou fechou a porta pra um lugar onde o efeito atrapalharia. Estão presas na regra global e não reaparecem sozinhas.

aO gatilho é :focus

:focus-visible não serve: o formulário entrega o foco por código ao abrir a linha (autoFocus) e o dedo no celular nunca marca focus-visible. Nos dois casos o efeito não acontecia — justamente quando ele importa.

bA película tem a cor da superfície

Branca sobre superfície branca, some. Branca sobre o cinza da faixa, vira um retângulo claro visível (apareceu como um “quadrado” em volta do rail). Onde o fundo não é surface, recue por opacidade — é o caso do data-dim-far.

cUm anel só em cena

O anel é do CAMPO. O bloco marca o lugar pela elevação, e o card devolve a borda neutra enquanto se edita. Anel dentro de anel dentro de anel é moldura, não hierarquia.

dForm sempre aberto não ganha tapete

Tapete permanente muda o desenho da tela em REPOUSO, não só no foco. Nesses blocos vai data-dim-solto: a elevação entra por ::before com inset: -0.75rem e z-index: -1, então aparece e some sem mover um pixel.

eLer não é editar

O tapete de LEITURA (o texto do documento aberto na lista) usa a mesma cor e NÃO leva data-dim: marcá-lo faria a tela recuar sem ninguém preenchendo nada.

fDiálogo já tem o seu véu

Gaveta e modal entram com scrim próprio. Empilhar o padrão ali dá dois escurecimentos brigando — e a busca de uma lista precisa mostrar a lista, não apagá-la.

Armadilha já pagaOrdem vence especificidade no minificador

A regra que desarma o tapete no data-dim-solto precisa vir DEPOIS da regra de elevação: o minificador achata [data-dim][data-dim-solto] pra um atributo só, então quem decide é a ordem no arquivo, não a especificidade.

NotaRegra solta em globals.css vence utility do Tailwind

Utilities vivem em @layer utilities; regra fora de camada pesa mais. É o que permite o card devolver a borda sem !important — e o que exige cuidado: [data-slot="card"] { position: relative } sobrescreveria um sticky de classe, se algum card usasse.

Onde vale

É contrato do sistema, não enfeite de uma tela: edição inline nova herda o padrão só de usar EditSurface e Field.
TelaO que recuaO que sobe
/ajustes/insumosmenu, rail, moldura do card, linhas vizinhasa linha que virou formulário
/ajustes/custosmenu, rail, moldura dos cardso tapete da despesa ou do equipamento; nos blocos de capacidade e impostos, o miolo dos campos
/ajustes/servicosmenu, rail, tabela e lista inteirasa linha do preço, ou o serviço aberto pra editar
/ajustes/conhecimentomenu, rail, orçamento do agente, documentos vizinhoso documento em escrita
/ajustes/horariosmenu, rail, os outros dias da gradeo dia em edição — e o miolo das regras de agendamento
/ajustes/clinicamenu, rail, seção da fichao dado que se está editando

Onde NÃO vale

Não é falta de alcance: em cada um destes o efeito atrapalharia o que a pessoa foi fazer.
LugarPor quê
Diálogos e gavetajá entram com scrim próprio — dois escurecimentos brigam
Busca e barras de filtrofocar a busca serve pra VER a lista; apagá-la é o contrário do pedido
Entrevista de custosuma pergunta por tela: já é foco total, não sobrou fundo pra recuar
Chat de teste do assistenteo campo vive em foco; apagar o histórico a cada clique seria hostil
Entrar, cadastro, 2FA, onboardinga página inteira é o formulário — não há segundo plano
Perfil, senha, segurança, privacidadeum card só na tela: o véu não teria em quem pousar
Superfície que não é surfacea película branca vira retângulo claro — foi o caso dos painéis do Assistente, fora até ganharem card

Antes de aplicar num lugar novo, a pergunta é uma só: existe um segundo plano que ATRAPALHA quem está preenchendo? Se não existe, o efeito não tem o que fazer.