Responsive Conversion — Web para Mobile e Padroes de Interacao

SkillAI & models

Skill de conversao de interface web para mobile e correcao de layout quebrado. Use quando componente nao ocupa 100% da largura, corta no meio da tela, quebra em telas pequenas, tem scroll horizontal indevido, modal estourando viewport, ou quando precisar definir padroes de confirmacao para acoes destrutivas (excluir, enviar, cadastrar). Trigger em: "responsivo", "mobile", "nao pega 100%", "cortando na tela", "quebrou no celular", "scroll horizontal", "viewport", "safe area", "notch", "bottom sheet", "modal no mobile", "confirmacao de exclusao", "modal de confirmar", "undo", "grid quebrado", "overflow", "converter para mobile", "adaptar layout".

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Responsive Conversion — Web para Mobile e Padroes de Interacao skill

What this skill tells your AI

The instructions your AI receives, as published by felvieira/claude-skills-fv in skills/56-responsive-conversion/SKILL.md and read by ahel’s review.

Converte interface pensada para desktop em interface que funciona de verdade em telas pequenas, e define os padroes de modal, formulario e confirmacao que a conversao expoe. Diferente da skill 02 (que decide como a interface vai parecer antes de existir), esta skill audita e conserta o que ja existe.

Governanca Global

Esta skill segue GLOBAL.md, policies/execution.md, policies/handoffs.md, policies/token-efficiency.md, policies/stack-flexibility.md, policies/evals.md e policies/visual-diff-precision.md (validar correção de layout comparando screenshot antes/depois — decompor em passes de zoom, não afirmar "corrigido" a partir de uma olhada única).

Para catalogo completo de bugs com snippet de fix por framework (Tailwind, CSS puro, styled-components), consultar docs/skill-guides/responsive-conversion.md apenas quando necessario.

Fronteira com skills vizinhas:

  • 02-ui-ux-design define ancora estetica, tokens e wireframe antes de codar — esta skill nao redefine estetica, herda a que ja existe
  • 52-ui-polish cuida do acabamento micro (border radius concentrico, alinhamento optico) depois que o layout esta correto — layout quebrado nao se resolve com polish
  • 22-accessibility-specialist e dona de WCAG completo — esta skill cobre so o subconjunto que colide com mobile (hit area, focus trap em modal, zoom de input)
  • 57-mobile-ux-foundations define, antes desta, onde o elemento deve morar pela zona do polegar, como o tema escuro se comporta, como tratar espera acima de 1s e como desenhar login/onboarding — esta skill executa o layout dentro dessas restricoes
  • 58-i18n-localization trata a quebra causada pelo conteudo (texto traduzido cresce, RTL inverte a direcao); esta skill trata a quebra causada pela largura da tela. A raiz costuma ser a mesma — container que se recusa a crescer — entao o fix de min-w-0 daqui frequentemente resolve os dois

Quando Usar

  • converter tela/app pensado para desktop em versao mobile funcional
  • corrigir componente que nao ocupa a largura esperada ou corta conteudo
  • resolver scroll horizontal indevido ou layout que "estoura" a tela
  • definir comportamento de modal, drawer ou bottom sheet em telas pequenas
  • especificar fluxo de confirmacao para acao destrutiva ou irreversivel
  • auditar formulario que fica inutilizavel em mobile

Quando Nao Usar

  • escolher paleta, tipografia ou direcao visual do zero (isso e 02-ui-ux-design)
  • ajustar detalhe de acabamento em layout que ja funciona (isso e 52-ui-polish)
  • auditoria completa de acessibilidade WCAG (isso e 22-accessibility-specialist)
  • decidir sistema de animacao e motion tokens (isso e 12-motion-design)

Entradas Esperadas

  • codigo da interface existente (componentes, paginas, CSS/Tailwind)
  • descricao do sintoma observado, se houver ("nao pega 100%", "corta no meio")
  • breakpoints e ancora estetica ja definidos (skill 02), se existirem
  • print/screenshot do bug, quando disponivel

Saidas Esperadas

  • relatorio de auditoria com sintoma → causa raiz → fix aplicado, por ocorrencia
  • codigo corrigido nos arquivos reais
  • checklist de conversao marcado
  • padroes de modal/confirmacao especificados para os fluxos destrutivos encontrados

Protocolo de Auditoria

Rodar nesta ordem. Cada fase alimenta a seguinte — pular fase gera fix superficial que reaparece.

Fase 1 — Inventario de viewport

Mapear onde o layout assume largura de desktop:

# Larguras fixas em px (o suspeito numero 1)
grep -rn "width: *[0-9]\{3,\}px\|w-\[[0-9]\{3,\}px\]\|min-width: *[0-9]\{3,\}px" src/ app/

# Alturas de viewport legadas (quebram com barra do browser mobile)
grep -rn "100vh\|h-screen\|min-h-screen" src/ app/

# Grids com contagem fixa de coluna
grep -rn "grid-cols-[3-9]\|grid-template-columns" src/ app/

Cada hit e um candidato — nao um bug confirmado. Confirmar na Fase 2.

Fase 2 — Reproduzir em viewport real

Nao confiar em "parece ok no devtools responsivo". Testar em 3 larguras que quebram coisas diferentes:

LarguraRepresentaO que quebra tipicamente
320pxiPhone SE / Android pequenoLargura fixa, botao com texto longo, tabela
390pxiPhone padrao atualGrid de 2 colunas apertado, modal com padding grande
768pxTablet retrato / limiarLayout que troca de sidebar para hamburger no ponto errado

Quando houver Playwright no projeto (skill 05), preferir teste automatizado de viewport a inspecao manual — o teste vira regressao.

Fase 3 — Classificar e corrigir

Usar o catalogo abaixo. Fix sem entender a causa raiz reaparece na proxima tela.

Fase 4 — Verificar sem regressao

Reconferir as 3 larguras da Fase 2 e a largura desktop original — conversao mobile que quebra o desktop nao e conversao, e troca de bug. Largura que quebrou volta pra Fase 3 pra reclassificar a causa raiz (o fix provavelmente resolveu o sintoma numa largura e criou outro numa diferente) — nao ajustar o CSS até "parecer ok" sem reclassificar.

Catalogo de Bugs — Sintoma, Causa, Fix

1. Componente nao ocupa 100% da largura

O sintoma mais comum e quase sempre a mesma causa raiz: item de flex/grid tem min-width: auto por default, entao ele se recusa a encolher abaixo do conteudo, e o container "estoura" em vez de caber.

SintomaCausaFix
Filho de flex nao encolhe, empurra layoutmin-width: auto implicito no flex itemmin-w-0 no filho (CSS: min-width: 0)
Coluna de grid estoura o containerMesma causa, em gridmin-w-0 no item ou grid-template-columns: minmax(0, 1fr)
Texto longo sem espaco empurra tudoPalavra sem quebra (URL, hash, email)break-words / overflow-wrap: anywhere
w-full nao surte efeitoPai tem largura intrinseca (w-fit, inline-block, tabela)Corrigir o pai, nao o filho
Componente com largura correta mas conteudo vazaoverflow nao definidooverflow-hidden no container so depois de confirmar que nao esconde conteudo util

Regra: min-w-0 no filho de flex/grid resolve a maioria absoluta destes casos. Aplicar antes de tentar qualquer outra coisa.

2. Altura de viewport quebrada em mobile

100vh no mobile nao e a altura visivel — browsers mobile contam a viewport sem descontar a barra de endereco, entao o conteudo fica cortado atras dela.

UnidadeComportamentoQuando usar
100vhAltura maxima (barra recolhida) — corta conteudoNunca em mobile sem fallback
100dvhAltura dinamica real, acompanha a barraDefault para tela cheia em mobile
100svhAltura minima (barra visivel)Quando o conteudo nunca pode ficar escondido
100lvhAltura maxima explicitaBackground decorativo que pode passar por baixo

Fallback para browsers antigos: declarar 100vh primeiro e 100dvh na linha seguinte — quem nao entende dvh ignora a segunda.

.tela-cheia {
  height: 100vh;
  height: 100dvh;
}

3. Safe area — notch, ilha dinamica e barra de gestos

Conteudo colado na borda em iPhone fica embaixo do notch (topo) ou da barra de gestos (base). Exige duas coisas juntas — falta uma, nao funciona:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.header-fixo  { padding-top: env(safe-area-inset-top); }
.barra-inferior { padding-bottom: env(safe-area-inset-bottom); }

/* Somar ao padding proprio em vez de substituir */
.barra-inferior { padding-bottom: calc(1rem + env(safe-area-inset-bottom)); }

Afeta: header fixo, bottom navigation, botao flutuante, bottom sheet, modal full-screen.

4. Scroll horizontal indevido

A pagina inteira desliza pro lado. Debug em ordem — o primeiro hit costuma ser o culpado:

// Cole no console: lista todo elemento mais largo que a tela
document.querySelectorAll('*').forEach(el => {
  if (el.offsetWidth > document.documentElement.offsetWidth) console.log(el);
});

Causas por frequencia: largura fixa em px maior que a tela → margem negativa sem overflow-hidden no pai → 100vw (ignora a barra de scroll, use 100%) → grid com grid-cols-N fixo → imagem sem max-width: 100% → tabela sem wrapper com scroll.

Nunca "resolver" com overflow-x: hidden no body — isso esconde o sintoma, mantem o bug e quebra position: sticky dentro da pagina.

5. Grid e posicionamento que colapsam

Padrao desktopConversao mobileComo
Grid de N colunas fixasColunas por espaco disponivelgrid-cols-[repeat(auto-fit,minmax(280px,1fr))] — sem media query
Sidebar + conteudoStack vertical ou drawerflex-col md:flex-row
Tabela de dadosCards empilhadosRepetir o dado como card < md, tabela >= md
Toolbar horizontalScroll horizontal proprio ou menu "mais"Wrapper com overflow-x-auto so na toolbar, nunca no body
Modal centralizadoBottom sheetVer secao de modais
Icone + label lado a ladoSo icone com aria-labelManter hit area de 44px mesmo sem o label

auto-fit + minmax resolve a maioria dos grids sem escrever uma media query — preferir a media query manual so quando a quebra precisa acontecer em ponto especifico do design.

6. Formulario em mobile

ProblemaFix
iOS aplica zoom ao focar inputfont-size: 16px minimo no input (nao no label)
Teclado errado (numerico, email)inputmode correto: numeric, decimal, email, tel
Autofill nao funcionaautocomplete semantico (given-name, cc-number, one-time-code)
Teclado cobre o campo focadoscroll-margin-bottom no input ou scroll manual no focus
Campos lado a lado ilegiveisEmpilhar sempre em mobile — grid-cols-1 md:grid-cols-2
Botao de submit fora do alcanceFixar no rodape com env(safe-area-inset-bottom)
Erro so no topo do formErro inline no campo e foco programatico no primeiro invalido
Erro so aparece no submitValidar no blur de cada campo — no submit, o usuario ja perdeu o contexto do que digitou (ver skill 57)
Label vira placeholder e some ao digitarLabel flutuante — placeholder sozinho quebra leitor de tela e apaga a instrucao (ver skill 57)

Modais, Drawers e Bottom Sheets

Qual usar

SituacaoDesktopMobileMotivo
Confirmar acao curtaModal centralizadoModal centralizado (pequeno)Precisa de foco total, conteudo cabe
Formulario medio/longoModal centralizadoBottom sheet ou tela cheiaModal com scroll interno em tela pequena e hostil
Navegacao secundariaSidebar / dropdownDrawer lateralPreserva contexto da tela
Selecao de opcao em listaDropdown / popoverBottom sheetAlcance do polegar
Conteudo imersivo (imagem, leitura)Modal grandeTela cheia (rota propria)Modal full-screen sem URL quebra o botao voltar

Regra de ouro: se o conteudo do modal exige scroll em mobile, provavelmente deveria ser bottom sheet ou uma rota propria — nao um modal menor.

Requisitos nao-negociaveis de todo modal

Falta qualquer um destes e o modal esta quebrado, independente da aparencia:

  • Focus trap — Tab circula dentro do modal, nunca vaza para a pagina atras
  • Retorno de foco — ao fechar, foco volta ao elemento que abriu
  • Escape fecha — e o mesmo caminho de fechar do botao X
  • Scroll lock no fundo — a pagina atras nao rola junto (cuidado: overflow: hidden no body perde a posicao de scroll no iOS; salvar e restaurar scrollY)
  • Role e labelrole="dialog" + aria-modal="true" + aria-labelledby apontando para o titulo
  • Clique no backdrop — fecha em modal informativo; nao fecha em modal com formulario preenchido ou confirmacao destrutiva (evita perda acidental)
  • Respeitar safe area — bottom sheet precisa de padding-bottom: env(safe-area-inset-bottom)

Preferir primitiva acessivel pronta (Radix Dialog, Headless UI, <dialog> nativo) a implementar focus trap na mao — implementacao propria erra em detalhe de teclado quase sempre.

Bottom sheet — comportamento esperado

  • Sobe da base, ocupa altura pelo conteudo (max-height: 85dvh como teto)
  • Handle visual no topo indicando que arrasta
  • Fecha por: arrastar pra baixo, tocar no backdrop, Escape, botao explicito
  • Conteudo longo rola dentro da sheet, com a sheet ancorada
  • Nunca ultrapassar 100dvh nem esconder conteudo atras da barra de gestos

Confirmacao de Acoes — Destrutivo, Envio, Cadastro

O erro mais comum e tratar tudo igual: ou confirma tudo (fricção que treina o usuario a clicar "sim" sem ler), ou nao confirma nada (perda de dado real).

Escolher o padrao pela reversibilidade

Tipo de acaoPadrao corretoNunca fazer
Reversivel e barata (arquivar, marcar lido, remover item do carrinho)Executar direto + toast com Desfazer (5-10s)Modal de confirmacao — fricção sem beneficio
Irreversivel comum (excluir registro, cancelar pedido)Modal de confirmacao com consequencia explicitaBotao destrutivo sem nenhuma confirmacao
Irreversivel catastrofica (excluir conta, apagar workspace, deletar em massa)Confirmacao com digitacao do nome do recursoModal simples de "Tem certeza?"
Envio que gera efeito externo (enviar email, publicar, cobrar cartao)Revisao antes + estado de loading bloqueante + confirmacao de sucessoPermitir duplo clique (submit duplo)
Cadastro/formulario longoAutosave de rascunho + aviso ao sair com dado nao salvoPerder tudo em navegacao acidental

Preferir Desfazer a Confirmar sempre que a acao for tecnicamente reversivel — undo respeita mais o tempo do usuario e produz menos erro que um modal que ele aprendeu a dispensar.

Anatomia do modal de confirmacao destrutiva

Titulo:     nomeia a acao e o alvo especifico
            "Excluir o projeto Vendas Q4?"
            NAO: "Tem certeza?" / "Confirmar acao"

Corpo:      consequencia concreta e verificavel
            "Os 128 registros e 3 integracoes serao removidos. Nao da pra desfazer."
            NAO: "Esta acao nao pode ser desfeita." (generico, ninguem le)

Botao 1:    verbo da acao, nao "OK" — visual destrutivo
            "Excluir projeto"
            NAO: "Sim" / "Confirmar" / "OK"

Botao 2:    saida segura, e o default do foco
            "Cancelar"

Foco:       inicia no botao seguro, nunca no destrutivo
Escape:     cancela
Backdrop:   NAO fecha (evita dispensar sem querer)

Para acao catastrofica, exigir digitacao literal do nome do recurso e manter o botao desabilitado ate bater exatamente — atrito proposital e desejavel aqui.

Estados obrigatorios de qualquer acao com efeito

Toda acao que chama API precisa dos quatro:

  1. Idle — botao habilitado com verbo claro
  2. Loading — botao desabilitado com indicacao de progresso (previne submit duplo; nao basta esconder o botao)
  3. Sucesso — confirmacao visivel do que aconteceu, com Desfazer quando aplicavel
  4. Erro — mensagem que diz o que falhou e o que fazer, preservando o dado que o usuario digitou

Nunca fechar o modal antes da resposta chegar: fechar otimista em acao destrutiva esconde o erro do usuario.

Anti-Padroes

  • overflow-x: hidden no body para "resolver" scroll horizontal — esconde o bug e quebra position: sticky
  • 100vh em tela cheia mobile sem fallback dvh
  • Media query como primeira ferramenta — testar antes min-w-0, auto-fit/minmax, flex-wrap, clamp()
  • Detectar mobile por user agent para decidir layout — usar largura de container/viewport
  • Esconder funcionalidade em mobile (hidden md:block) como solucao de layout — mover ou reorganizar, nao amputar
  • Modal full-screen sem rota propria — quebra o botao voltar do Android
  • Backdrop que fecha modal de confirmacao destrutiva ou formulario preenchido
  • Modal de confirmacao para acao trivialmente reversivel — treina o usuario a confirmar no automatico
  • "Tem certeza?" sem nomear o alvo nem a consequencia
  • Botao destrutivo como default do foco
  • Toast de erro que some sozinho em acao critica — erro precisa persistir ate o usuario agir
  • touch-action: none global para "resolver" scroll — mata gesto legitimo

Checklist de Conversao

Layout:

  • Testado em 320px, 390px e 768px, alem do desktop original
  • Zero scroll horizontal em todas as larguras
  • Filhos de flex/grid com min-w-0 onde encolhem
  • dvh em vez de vh em tela cheia (com fallback)
  • viewport-fit=cover + env(safe-area-inset-*) em elementos de borda
  • Grids usam auto-fit/minmax ou colapsam por breakpoint
  • Imagens com max-width: 100% e aspect-ratio definido
  • Tabelas viram cards ou tem wrapper com scroll proprio

Interacao:

  • Hit area minima de 44x44px em todo alvo de toque
  • Inputs com font-size >= 16px, inputmode e autocomplete corretos
  • Modal com focus trap, retorno de foco, Escape e scroll lock
  • Conteudo longo em mobile usa bottom sheet ou rota propria, nao modal com scroll
  • Toda acao com API tem os 4 estados (idle, loading, sucesso, erro)
  • Submit duplo impossivel (botao desabilita no loading)

Confirmacao:

  • Acao reversivel usa Desfazer, nao modal
  • Modal destrutivo nomeia alvo e consequencia concreta
  • Botao de acao usa o verbo, nao "OK"
  • Foco inicia no botao seguro; backdrop nao fecha
  • Acao catastrofica exige digitacao do nome do recurso
  • Formulario longo avisa antes de descartar dado nao salvo

Evidencia de Conclusao

  • relatorio sintoma → causa → fix para cada ocorrencia corrigida
  • checklist de conversao marcado, com item nao aplicavel justificado
  • verificacao nas 3 larguras mobile e na largura desktop original (sem regressao)
  • quando houver Playwright no projeto, teste de viewport cobrindo os bugs corrigidos

Handoff

Recebe de

  • 02-ui-ux-design — ancora estetica, tokens e breakpoints ja definidos
  • 04-frontend-integration — componentes implementados a auditar

Entrega para

  • 52-ui-polish — layout correto e pre-requisito do polish; despachar depois, nunca antes
  • 22-accessibility-specialist — quando a auditoria revelar problema de acessibilidade alem do subconjunto mobile
  • 05-qa-testing — para transformar os bugs corrigidos em teste de viewport (regressao)
  • 11-reviewer — relatorio e checklist para validacao final

Regra de Codigo Limpo

Comentario so quando o valor nao e obvio — min-w-0 e 100dvh merecem uma linha explicando o porque, ja que parecem arbitrarios para quem nunca caiu no bug. Classe utilitaria autoexplicativa nao precisa de comentario.

Integracao com Pipeline

  • Orquestrador (skill 09): aciona esta skill quando a task menciona mobile, responsivo ou bug de layout; tipicamente depois de 04-frontend-integration
  • UI/UX Design (skill 02): dona da direcao estetica — esta skill herda a ancora, nunca a redefine
  • UI Polish (skill 52): entra depois desta; acabamento sobre layout quebrado e desperdicio
  • Accessibility (skill 22): dona do WCAG completo; esta skill cobre so o recorte que colide com mobile
  • QA (skill 05): converte os fixes em teste automatizado de viewport
  • Context Manager (skill 08): rastreia progresso da auditoria por tela/componente

Signals

GitHub stars
23
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
responsive-conversion
Source
github.com/felvieira/claude-skills-fv