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-fvDesign engineering principles for polishing interfaces. Covers typography, surfaces, animations, and performance details.
Applies concrete design-engineering details for polished UI: spacing, typography, shadows, motion, hit areas, icons, text wrapping, and interaction states. Use when reviewing or improving frontend interfaces.
Polishes UI with micro-interactions, state transitions, and feedback design. Use when interfaces feel flat, cramped, or unfinished.