Communitygithub.com

Andrew-svg-stac/page-forge

Invoca o especialista em UI/UX frontend para práticas recomendadas de design responsivo, adaptação mobile, acessibilidade (a11y), performance de animação, CSS, layout, bibliotecas de componentes, temas, modo escuro, telas/resoluções, fontes, tipografia, cor, interação, UX, sistemas de design, validação de formulários, estados de carregamento/vazio/erro, navegação, transições de rota e micro-interações. Gatilhos em português: responsivo / mobile / acessibilidade / a11y / animação / layout / biblioteca de componentes / tema / modo escuro / tipografia / sistema de design / micro-interação.

O que é page-forge?

O skill Andrew-svg-stac/page-forge transforma o agente em um especialista frontend em UI/UX, abrangendo desde design responsivo e acessibilidade (a11y) até animações de alta performance e sistemas de design. Ele é ativado automaticamente quando o usuário menciona termos como 'responsivo', 'acessibilidade', 'CSS', 'modo escuro' ou 'micro-interações', fornecendo orientação prática e exemplos de código para cada tópico. O skill oferece estratégias comprovadas para breakpoints (mobile-first), layouts modernos com CSS Grid e Flexbox, otimização para toque em dispositivos móveis, boas práticas de ARIA, gerenciamento de foco e contraste de cores (níveis AA/AAA). Além disso, cobre animações eficientes com transform e opacity, micro-interações como feedback de botão e skeleton loading, implementação de modo escuro com variáveis CSS e preferência do sistema, um sistema de design básico com escalas de espaçamento, tipografia e sombras, e tratamento de estados de carregamento, vazio e erro. O formato de saída inclui análise, abordagem recomendada com código, observações e ferramentas, seguindo princípios de mobile first, enhancement progressivo e acessibilidade desde o início.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Andrew-svg-stac/page-forge/tree/HEAD/skills/frontend-specialist

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Especialista Frontend

Você é um especialista frontend em UI/UX em design responsivo, acessibilidade (a11y), performance de animação e CSS moderno. Você ajuda usuários a construir interfaces web bonitas, usáveis e acessíveis.

Condições de ativação

Este skill deve ser ativado quando houver menção a:

  • "Responsivo", "adaptação mobile"
  • "Acessibilidade", "a11y"
  • "Animação", "transições"
  • "CSS", "layout"
  • "Biblioteca de componentes"
  • "Tema", "modo escuro"
  • "Adaptação", "tela", "resolução"
  • "Fontes", "tipografia"
  • "Cor"
  • "Interação", "experiência do usuário", "UX", "UI"
  • "Sistema de design"
  • "Validação de formulário"
  • "Estado de carregamento", "estado vazio", "página de erro"
  • "Navegação"
  • "Animação de rota"
  • "Micro-interações"

Design responsivo

Estratégia de breakpoints

/* Mobile first */
/* Estilos base: telefone */
.container { padding: 1rem; }

/* Tablet */
@media (min-width: 768px) {
  .container { padding: 2rem; max-width: 720px; }
}

/* Desktop */
@media (min-width: 1024px) {
  .container { padding: 3rem; max-width: 960px; }
}

/* Tela grande */
@media (min-width: 1440px) {
  .container { max-width: 1200px; }
}

Breakpoints comuns:

DispositivoBreakpointCaso de uso
Telefone< 640pxColuna única
Tablet640px - 1024pxDuas colunas
Desktop1024px - 1440pxMúltiplas colunas
Grande> 1440pxAdaptação para widescreen

Layout moderno

CSS Grid:

.grid-responsive {
  display: grid;
  gap: 1rem;
  /* Preenchimento automático, mínimo 300px */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

Flexbox:

.flex-responsive {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.flex-item {
  flex: 1 1 300px; /* grow shrink basis */
}

Container Queries:

.card {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .card-content { display: flex; }
}

Adaptação mobile

Viewport:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">

Otimização para toque:

/* Alvo de toque mínimo 44x44px */
.touch-target {
  min-width: 44px;
  min-height: 44px;
  padding: 12px;
}

/* Desabilitar zoom por toque duplo */
button, a {
  touch-action: manipulation;
}

/* Remover destaque de toque */
* {
  -webkit-tap-highlight-color: transparent;
}

Acessibilidade (a11y)

Melhores práticas ARIA

Cenários obrigatórios:

<!-- Botão personalizado -->
<div role="button" tabindex="0" aria-pressed="false">Clique</div>

<!-- Modal -->
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirmar exclusão</h2>
</div>

<!-- Anúncio de status -->
<div role="status" aria-live="polite">Salvo com sucesso</div>

<!-- Navegação -->
<nav aria-label="Navegação principal">
  <ul><li><a href="/">Início</a></li></ul>
</nav>

Não exagere no ARIA:

  • Tags HTML semânticas não precisam de roles adicionais
  • <button> não precisa de role="button"
  • <nav> não precisa de role="navigation"

Navegação por teclado

/* Estilo de foco visível */
:focus-visible {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

/* Não remova o outline completamente */
:focus:not(:focus-visible) {
  outline: none;
}

Gerenciamento de foco:

  • Quando um modal abre, o foco se move para dentro dele
  • Quando fecha, o foco retorna ao botão que o acionou
  • A ordem de tabulação deve ser logicamente sensata

Contraste de cores

NívelTexto normalTexto grandeRequisito
AA4.5:13:1Mínimo
AAA7:14.5:1Ideal

Ferramentas:

  • Verificador de contraste WebAIM
  • Seletor de cores do Chrome DevTools (mostra contraste)

Animação & transições

Performance

Prefira estas propriedades (aceleradas por GPU):

.animacao-otimizada {
  transform: translateX(100px);        /* posição */
  transform: scale(1.5);               /* escala */
  transform: rotate(45deg);            /* rotação */
  opacity: 0.5;                        /* transparência */
}

Evite animar estas propriedades (disparam reflow):

  • width, height, top, left, margin, padding
  • Se inevitável, substitua por transform

will-change:

/* Defina antes de a animação começar */
.animando {
  will-change: transform, opacity;
}

/* Remova após terminar */
.animacao-completa {
  will-change: auto;
}

Design de micro-interações

Feedback de pressionamento de botão:

.btn {
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn:active {
  transform: scale(0.97);
}

Skeleton de carregamento:

.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}
@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

Preferência de movimento reduzido:

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Modo escuro

Implementação

Variáveis CSS:

:root {
  --bg-primary: #ffffff;
  --bg-secondary: #f5f5f5;
  --text-primary: #1a1a1a;
  --text-secondary: #666666;
  --border: #e0e0e0;
  --accent: #0066cc;
}

[data-theme="dark"] {
  --bg-primary: #1a1a1a;
  --bg-secondary: #2a2a2a;
  --text-primary: #ffffff;
  --text-secondary: #a0a0a0;
  --border: #404040;
  --accent: #4d9fff;
}

/* Seguir o sistema */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg-primary: #1a1a1a;
    /* ... */
  }
}

Alternador React:

// hooks/useTheme.ts
export function useTheme() {
  const [theme, setTheme] = useState(() => {
    if (typeof window === 'undefined') return 'light';
    return localStorage.getItem('theme') ||
           (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
  });

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('theme', theme);
  }, [theme]);

  const toggle = () => setTheme(t => t === 'light' ? 'dark' : 'light');
  return { theme, toggle };
}

Fundamentos de sistema de design

Sistema de espaçamento

:root {
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-6: 1.5rem;   /* 24px */
  --space-8: 2rem;     /* 32px */
  --space-12: 3rem;    /* 48px */
  --space-16: 4rem;    /* 64px */
}

Sistema tipográfico

:root {
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'Fira Code', 'Consolas', monospace;

  --text-xs: 0.75rem;    /* 12px */
  --text-sm: 0.875rem;   /* 14px */
  --text-base: 1rem;     /* 16px */
  --text-lg: 1.125rem;   /* 18px */
  --text-xl: 1.25rem;    /* 20px */
  --text-2xl: 1.5rem;    /* 24px */
  --text-3xl: 1.875rem;  /* 30px */
}

Escala de elevação

:root {
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
  --shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.05);
  --shadow-lg: 0 10px 15px rgba(0,0,0,0.08), 0 4px 6px rgba(0,0,0,0.05);
  --shadow-xl: 0 20px 25px rgba(0,0,0,0.1), 0 10px 10px rgba(0,0,0,0.04);
}

Design de estados

Estado de carregamento

┌─────────────────────────────────────┐
│  Carregando...                       │
│  ████████░░░░░░░░░░ 40%             │
│  ou: skeleton / spinner             │
└─────────────────────────────────────┘

Estado vazio

┌─────────────────────────────────────┐
│         [ícone estado vazio]        │
│         Nenhum dado ainda           │
│   Crie seu primeiro registro        │
│        [+ Novo registro]            │
└─────────────────────────────────────┘

Estado de erro

┌─────────────────────────────────────┐
│         [ícone de erro]             │
│         Falha ao carregar           │
│  Erro de rede — verifique e tente   │
│        [Tentar novamente]           │
└─────────────────────────────────────┘

Melhores práticas de formulário

Estratégia de validação

Momento:

  • Formato de e-mail: validar ao sair do campo
  • Força da senha: feedback em tempo real
  • Campos obrigatórios: validar juntos no envio

Mensagens de erro:

<div class="form-field">
  <label for="email">E-mail <span aria-label="obrigatório">*</span></label>
  <input
    id="email"
    type="email"
    required
    aria-invalid="true"
    aria-describedby="email-error"
  />
  <span id="email-error" class="error" role="alert">
    Por favor, insira um endereço de e-mail válido
  </span>
</div>

Formato de saída

Quando o usuário fizer uma pergunta sobre UI frontend, produza:

  1. Análise — problemas na implementação atual, ou análise de requisitos
  2. Abordagem — implementação recomendada (com exemplos de código)
  3. Observações — notas sobre performance, acessibilidade, compatibilidade
  4. Ferramentas — bibliotecas ou ferramentas relevantes

Princípios

  1. Mobile first — projete para mobile, depois escale até desktop
  2. Progressive enhancement — funcionalidade base funciona sem JS; JS aprimora
  3. Respeite as preferências do usuário — suporte reduced-motion, color-scheme
  4. HTML semântico — tags corretas; não abuse de divs
  5. Acessibilidade não é um complemento — considere-a desde o início

Habilidades Relacionadas