From dev-team-kit-fv
Refines frontend component visual finish with fine-grained CSS/Tailwind/motion adjustments: concentric border radius, optical alignment, hover states, micro-animations, shadows, and typography.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dev-team-kit-fv:52-ui-polishThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Grandes interfaces raramente vêm de uma coisa só. É uma coleção de pequenos detalhes que se acumulam. Esta skill entra depois que Frontend (04) e/ou Motion Design (12) já produziram o componente — ela revisa e ajusta acabamento, não substitui a estrutura.
Grandes interfaces raramente vêm de uma coisa só. É uma coleção de pequenos detalhes que se acumulam. Esta skill entra depois que Frontend (04) e/ou Motion Design (12) já produziram o componente — ela revisa e ajusta acabamento, não substitui a estrutura.
Esta skill segue GLOBAL.md, policies/execution.md, policies/handoffs.md, policies/token-efficiency.md e policies/evals.md.
Para exemplos extensos de CSS/Tailwind/Motion por categoria, consultar docs/skill-guides/ui-polish.md apenas quando necessario.
Raio externo = raio interno + padding. Raios diferentes em elementos aninhados e a coisa mais comum que faz uma interface parecer errada.
outerRadius = innerRadius + padding
Se o padding for maior que 24px, tratar as camadas como superficies separadas — nao forcar concentricidade.
Quando a centralizacao geometrica parece errada, alinhar oticamente. Botoes com icone, triangulos de play e icones assimetricos (estrela, seta, caret) precisam de ajuste manual.
padding do lado do icone = padding do lado do texto - 2pxmargin-left: 2px)Para cards, containers e botoes com proposito de profundidade/elevacao, usar box-shadow em camadas transparentes em vez de border solida. Sombra se adapta a qualquer fundo; borda solida nao.
Nao aplicar em dividers (border-b, border-t, separadores de layout) — esses continuam borda.
--shadow-border:
0px 0px 0px 1px rgba(0, 0, 0, 0.06),
0px 1px 2px -1px rgba(0, 0, 0, 0.06),
0px 2px 4px 0px rgba(0, 0, 0, 0.04);
Dark mode: simplificar pra um unico ring branco (0 0 0 1px rgba(255, 255, 255, 0.08)).
CSS transitions para mudancas de estado interativas (hover, toggle, abrir/fechar) — retomam de onde pararam se o usuario mudar de intencao no meio. Keyframes ficam reservados para sequencias que rodam uma vez (loading, entrada de pagina) — reiniciam do zero se interrompidas, o que parece quebrado em elemento interativo.
Nao animar um container unico. Quebrar em blocos semanticos (titulo, descricao, botoes) e escalonar com ~100ms de delay entre eles. Para titulos, considerar quebrar em palavras individuais com ~80ms de stagger. Combinar opacity + blur + translateY.
Saida deve ser mais discreta que entrada — o foco do usuario ja foi pro proximo lugar. Usar translateY pequeno e fixo (ex: -12px), nao a altura total do elemento. Duracao de saida menor que entrada (ex: 150ms vs 300ms). Nunca remover a animacao de saida completamente (display: none direto) — motion sutil preserva contexto.
Ao trocar icone (hover, mudanca de estado), animar com opacity + scale + blur em vez de so alternar visibilidade. Valores exatos, sem desvio:
scale: 0.25 → 1 (nunca 0.5 ou 0.6)opacity: 0 → 1filter: blur(4px) → blur(0px)motion/framer-motion no package.json: transition: { type: "spring", duration: 0.3, bounce: 0 } — bounce sempre 0cubic-bezier(0.2, 0, 0, 1) — da entrada e saida sem dependencia nova-webkit-font-smoothing: antialiased + -moz-osx-font-smoothing: grayscale no root do layout (afeta so macOS, seguro aplicar universal).
font-variant-numeric: tabular-nums (Tailwind: tabular-nums) em qualquer numero que atualiza dinamicamente (contador, preco, timer, coluna de tabela) — evita layout shift. Nao usar em numeros estaticos (versao, CEP, telefone).
text-wrap: balance (Tailwind: text-balance) em headings — so funciona ate 6 linhas (Chromium) / 10 (Firefox), nao usar em paragrafo longotext-wrap: pretty (Tailwind: text-pretty) em paragrafo curto/medio, descricao, caption, item de lista — evita palavra orfa na ultima linhaOutline sutil de 1px em imagens para profundidade consistente. Regra de cor nao-negociavel: preto puro rgba(0, 0, 0, 0.1) no light mode, branco puro rgba(255, 255, 255, 0.1) no dark mode. Nunca usar near-black/near-white da paleta do projeto (slate-900, zinc-900, etc) — outline com tinta pega a cor da superficie ao redor e parece sujeira na borda da imagem.
<img className="outline outline-1 -outline-offset-1 outline-black/10 dark:outline-white/10" />
scale(0.96) sutil no click para feedback tatil. Sempre 0.96 — nunca menor que 0.95 (fica exagerado). Usar CSS transition (interrompivel). Adicionar prop static no componente de botao pra desabilitar quando o movimento for indesejado.
initial={false} em AnimatePresence evita animacao de entrada no primeiro render — funciona bem pra icon swap, toggle, tabs. Nao usar quando o componente depende do initial pra configurar a entrada da pagina (hero com stagger, loading state) — verificar sempre com refresh completo da pagina.
transition: allSempre especificar propriedades exatas: transition-property: scale, opacity. Tailwind transition-transform cobre transform, translate, scale, rotate — usar quando so anima transform; para multiplas propriedades nao-transform, usar transition-[scale,opacity,filter].
will-change com ModeracaoSo para transform, opacity, filter, clip-path — propriedades que a GPU compoe. Nunca will-change: all. Adicionar so quando notar stutter no primeiro frame (Safari se beneficia mais); nao adicionar preventivamente — cada layer de composicao custa memoria.
Elementos interativos precisam de pelo menos 40x40px (WCAG pede 44x44px) de area clicavel. Estender com pseudo-elemento se o elemento visivel for menor (ex: checkbox 20x20). Duas areas de hit nunca podem sobrepor — se colidir, encolher o pseudo-elemento até nao colidir.
| Erro | Correcao |
|---|---|
| Mesmo border radius em pai e filho | Calcular outerRadius = innerRadius + padding |
| Icone parece descentralizado | Ajustar oticamente com padding ou corrigir SVG direto |
| Borda dura entre secoes | Usar box-shadow em camadas com transparencia |
| Animacao de entrada/saida abrupta | Split, stagger, e manter saida sutil |
| Numero causa layout shift | Aplicar tabular-nums |
| Texto pesado no macOS | Aplicar antialiased no root |
| Animacao toca no page load | Adicionar initial={false} no AnimatePresence |
transition: all em elementos | Especificar propriedades exatas |
| Stutter no primeiro frame | Adicionar will-change: transform (com moderacao) |
| Hit area minuscula em controle pequeno | Estender com pseudo-elemento ate 40x40px |
Sempre apresentar mudancas como tabela markdown com colunas Before e After, agrupadas por principio (um heading por principio, uma tabela por heading). Incluir toda mudanca feita, nao um subconjunto. Se um principio foi revisado mas nada precisou mudar, omitir a tabela inteira — tabela vazia so gera ruido.
#### Border radius concentrico
| Before | After |
| --- | --- |
| `rounded-xl` no card + `rounded-xl` no botao interno (`p-2`) | `rounded-2xl` no card (`12+8`), `rounded-lg` no botao interno |
#### Scale on press
| Before | After |
| --- | --- |
| `scale(0.9)` no press | Ajustado para `scale(0.96)` — abaixo de `0.95` fica exagerado |
tabular-numstext-wrap: balance; paragrafos curtos usam text-wrap: prettyAnimatePresence usa initial={false} quando o estado default nao deve animar no loadtransition: all — sempre propriedades especificaswill-change so em transform/opacity/filter/clip-path, nunca allEsta skill NAO cria componentes novos — ajusta acabamento no MESMO codebase do Frontend/Motion. Se Motion Design ainda nao rodou e a tarefa envolve sistema de animacao amplo (nao so detalhe pontual), delegar a 12-motion-design primeiro.
ZERO comentarios explicando o que o codigo faz. Nomes de classes/variaveis autoexplicativos. Comentario so quando existe uma restricao nao-obvia (ex: por que um valor exato como bounce: 0 ou scale(0.96) foi escolhido, se nao for evidente do contexto).
npx claudepluginhub felvieira/claude-skills-fv --plugin dev-team-kit-fvApplies concrete design-engineering details to polish UI: spacing, typography, borders, shadows, motion, hit areas, icons, text wrapping, and interaction states. Use when reviewing or improving frontend interfaces.
Design engineering principles for polishing interfaces. Covers typography, surfaces, animations, and performance details.
Polishes UI with micro-interactions, state transitions, and feedback design. Use when interfaces feel flat, cramped, or unfinished.