nexus-core-v3 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/agents/README.md +133 -0
  4. package/agents/_protocol.md +107 -0
  5. package/agents/analyst.md +138 -0
  6. package/agents/architect.md +146 -0
  7. package/agents/data-engineer.md +170 -0
  8. package/agents/dev.md +134 -0
  9. package/agents/devops.md +141 -0
  10. package/agents/nexus-master.md +147 -0
  11. package/agents/pm.md +133 -0
  12. package/agents/po.md +138 -0
  13. package/agents/qa.md +192 -0
  14. package/agents/sm.md +122 -0
  15. package/agents/squad-creator.md +121 -0
  16. package/agents/ux-design-expert.md +165 -0
  17. package/artifact-manifest.json +903 -0
  18. package/bin/nexus.mjs +37 -0
  19. package/checklists/README.md +49 -0
  20. package/checklists/architect-checklist.md +47 -0
  21. package/checklists/change-checklist.md +61 -0
  22. package/checklists/db-predeploy-checklist.md +57 -0
  23. package/checklists/design-quality-checklist.md +57 -0
  24. package/checklists/discovery-checklist.md +36 -0
  25. package/checklists/foundation-checklist.md +39 -0
  26. package/checklists/launch-checklist.md +39 -0
  27. package/checklists/pm-checklist.md +48 -0
  28. package/checklists/po-master-checklist.md +64 -0
  29. package/checklists/reality-check-checklist.md +49 -0
  30. package/checklists/story-dod-checklist.md +52 -0
  31. package/checklists/story-draft-checklist.md +36 -0
  32. package/dist/bin/dashboard.html +279 -0
  33. package/dist/bin/nexus.mjs +20008 -0
  34. package/dist/constitution.yaml +76 -0
  35. package/knowledge/README.md +57 -0
  36. package/knowledge/architecture/architectural-styles-map.md +182 -0
  37. package/knowledge/architecture/design-patterns-gof.md +192 -0
  38. package/knowledge/architecture/distributed-patterns-cheatsheet.md +201 -0
  39. package/knowledge/architecture/saas-subscription-blueprint.md +355 -0
  40. package/knowledge/architecture/system-design-tradeoffs.md +231 -0
  41. package/knowledge/architecture/t3-fullstack-typesafe-stack.md +273 -0
  42. package/knowledge/copy/landing-copy-that-converts.md +168 -0
  43. package/knowledge/data/postgres-indexing-and-tuning.md +263 -0
  44. package/knowledge/data/schema-modeling-decisions.md +273 -0
  45. package/knowledge/data/supabase-rls-patterns.md +316 -0
  46. package/knowledge/data/zero-downtime-migrations.md +308 -0
  47. package/knowledge/devops/cicd-pipeline-best-practices.md +318 -0
  48. package/knowledge/devops/production-dockerfile.md +283 -0
  49. package/knowledge/devops/twelve-factor-app.md +398 -0
  50. package/knowledge/engineering/clean-code-principles.md +429 -0
  51. package/knowledge/engineering/effective-code-review.md +204 -0
  52. package/knowledge/engineering/testing-strategy-beyond-unit.md +307 -0
  53. package/knowledge/governance/risk-matrix.md +56 -0
  54. package/knowledge/integration/mcp-server-selection-matrix.md +235 -0
  55. package/knowledge/marketing/copy-que-converte.md +43 -0
  56. package/knowledge/marketing/funil-e-jornada.md +36 -0
  57. package/knowledge/negocios/proposta-vencedora.md +38 -0
  58. package/knowledge/negocios/roi-e-unit-economics.md +46 -0
  59. package/knowledge/pipeline/1-descobrir.md +26 -0
  60. package/knowledge/pipeline/2-estrategizar.md +26 -0
  61. package/knowledge/pipeline/3-estruturar.md +27 -0
  62. package/knowledge/pipeline/4-construir.md +27 -0
  63. package/knowledge/pipeline/5-endurecer.md +28 -0
  64. package/knowledge/pipeline/6-lancar.md +27 -0
  65. package/knowledge/pipeline/7-operar.md +27 -0
  66. package/knowledge/security/lgpd-conformidade-basica.md +35 -0
  67. package/knowledge/security/owasp-secure-coding-gates.md +220 -0
  68. package/knowledge/security/owasp-top10-threat-assessment.md +287 -0
  69. package/knowledge/security/threat-modeling-stride.md +34 -0
  70. package/knowledge/web-craft/a11y-audit-checklist.md +251 -0
  71. package/knowledge/web-craft/accessible-component-patterns.md +383 -0
  72. package/knowledge/web-craft/anti-ai-look.md +114 -0
  73. package/knowledge/web-craft/design-system-from-code.md +195 -0
  74. package/knowledge/web-craft/intrinsic-css-layout.md +420 -0
  75. package/knowledge/web-craft/style-cloning.md +185 -0
  76. package/knowledge/web-craft/visual-polish-review.md +183 -0
  77. package/package.json +55 -0
  78. package/runbooks/campanha-de-conteudo.md +36 -0
  79. package/runbooks/feature-em-projeto-existente.md +37 -0
  80. package/runbooks/mvp-startup.md +38 -0
  81. package/runbooks/resposta-a-incidente.md +37 -0
  82. package/squads/exemplo-conteudo/agents/editor-chefe.md +48 -0
  83. package/squads/exemplo-conteudo/agents/pesquisador.md +44 -0
  84. package/squads/exemplo-conteudo/agents/redator.md +45 -0
  85. package/squads/exemplo-conteudo/knowledge/estilo-editorial.md +21 -0
  86. package/squads/exemplo-conteudo/squad.yaml +19 -0
  87. package/squads/exemplo-conteudo/tasks/pesquisar-fontes.md +26 -0
  88. package/squads/exemplo-conteudo/tasks/planejar-pauta.md +27 -0
  89. package/squads/exemplo-conteudo/tasks/redigir-artigo.md +26 -0
  90. package/squads/exemplo-conteudo/tasks/revisar-artigo.md +27 -0
  91. package/squads/marketing/agents/analista.md +56 -0
  92. package/squads/marketing/agents/chefe-marketing.md +65 -0
  93. package/squads/marketing/agents/conteudo.md +55 -0
  94. package/squads/marketing/agents/copy.md +55 -0
  95. package/squads/marketing/agents/growth.md +56 -0
  96. package/squads/marketing/agents/social.md +55 -0
  97. package/squads/marketing/squad.yaml +17 -0
  98. package/squads/marketing/tasks/aprovar-campanha.md +43 -0
  99. package/squads/negocios/agents/chefe-negocios.md +65 -0
  100. package/squads/negocios/agents/financas-roi.md +55 -0
  101. package/squads/negocios/agents/suporte.md +55 -0
  102. package/squads/negocios/agents/vendas-proposta.md +56 -0
  103. package/squads/negocios/squad.yaml +17 -0
  104. package/squads/negocios/tasks/aprovar-proposta.md +40 -0
  105. package/squads/security/agents/appsec-reviewer.md +59 -0
  106. package/squads/security/agents/chefe-seguranca.md +65 -0
  107. package/squads/security/agents/compliance-auditor.md +60 -0
  108. package/squads/security/agents/threat-modeler.md +60 -0
  109. package/squads/security/squad.yaml +20 -0
  110. package/squads/security/tasks/aprovar-gate-seguranca.md +42 -0
  111. package/squads/security/tasks/emitir-parecer-conformidade.md +42 -0
  112. package/tasks/README.md +72 -0
  113. package/tasks/accessibility-wcag-checklist.md +69 -0
  114. package/tasks/advanced-elicitation.md +42 -0
  115. package/tasks/analyze-performance.md +54 -0
  116. package/tasks/analyze-project-structure.md +59 -0
  117. package/tasks/apply-qa-fixes.md +57 -0
  118. package/tasks/architect-analyze-impact.md +62 -0
  119. package/tasks/archive-squad.md +52 -0
  120. package/tasks/audit-codebase.md +53 -0
  121. package/tasks/build-component.md +61 -0
  122. package/tasks/calculate-roi.md +63 -0
  123. package/tasks/ci-cd-configuration.md +51 -0
  124. package/tasks/collect-visual-evidence.md +62 -0
  125. package/tasks/compose-molecule.md +57 -0
  126. package/tasks/consolidate-patterns.md +54 -0
  127. package/tasks/create-brownfield-prd.md +54 -0
  128. package/tasks/create-competitor-analysis.md +42 -0
  129. package/tasks/create-deep-research-prompt.md +62 -0
  130. package/tasks/create-doc.md +62 -0
  131. package/tasks/create-epic.md +49 -0
  132. package/tasks/create-front-end-spec.md +56 -0
  133. package/tasks/create-migration-plan.md +57 -0
  134. package/tasks/create-next-story.md +66 -0
  135. package/tasks/create-prd.md +53 -0
  136. package/tasks/create-project-brief.md +47 -0
  137. package/tasks/create-rls-policies.md +59 -0
  138. package/tasks/create-schema.md +57 -0
  139. package/tasks/create-service.md +55 -0
  140. package/tasks/create-squad.md +100 -0
  141. package/tasks/create-suite.md +62 -0
  142. package/tasks/db-apply-migration.md +56 -0
  143. package/tasks/db-domain-modeling.md +57 -0
  144. package/tasks/db-dry-run.md +50 -0
  145. package/tasks/db-env-check.md +57 -0
  146. package/tasks/db-load-csv.md +54 -0
  147. package/tasks/db-policy-apply.md +58 -0
  148. package/tasks/db-rollback.md +51 -0
  149. package/tasks/db-run-sql.md +61 -0
  150. package/tasks/db-seed.md +52 -0
  151. package/tasks/db-smoke-test.md +51 -0
  152. package/tasks/db-snapshot.md +48 -0
  153. package/tasks/db-verify-order.md +49 -0
  154. package/tasks/deliberate.md +46 -0
  155. package/tasks/design-indexes.md +59 -0
  156. package/tasks/dev-develop-story.md +61 -0
  157. package/tasks/document-project.md +59 -0
  158. package/tasks/execute-checklist.md +57 -0
  159. package/tasks/execute-epic-plan.md +52 -0
  160. package/tasks/execute-subtask.md +51 -0
  161. package/tasks/extend-pattern.md +63 -0
  162. package/tasks/extend-squad.md +60 -0
  163. package/tasks/extract-patterns.md +64 -0
  164. package/tasks/extract-tokens.md +59 -0
  165. package/tasks/facilitate-brainstorming-session.md +42 -0
  166. package/tasks/generate-ai-frontend-prompt.md +57 -0
  167. package/tasks/generate-documentation.md +60 -0
  168. package/tasks/generate-migration-strategy.md +57 -0
  169. package/tasks/generate-shock-report.md +56 -0
  170. package/tasks/mcp-management.md +66 -0
  171. package/tasks/orchestrate.md +50 -0
  172. package/tasks/perform-market-research.md +42 -0
  173. package/tasks/plan-create-context.md +57 -0
  174. package/tasks/plan-create-implementation.md +58 -0
  175. package/tasks/po-close-story.md +60 -0
  176. package/tasks/po-manage-story-backlog.md +59 -0
  177. package/tasks/po-pull-story.md +60 -0
  178. package/tasks/po-sync-story.md +59 -0
  179. package/tasks/pr-automation.md +50 -0
  180. package/tasks/pre-push-quality-gate.md +54 -0
  181. package/tasks/push.md +53 -0
  182. package/tasks/qa-browser-console-check.md +52 -0
  183. package/tasks/qa-create-fix-request.md +58 -0
  184. package/tasks/qa-evidence-requirements.md +55 -0
  185. package/tasks/qa-false-positive-detection.md +55 -0
  186. package/tasks/qa-fix-issues.md +55 -0
  187. package/tasks/qa-gate.md +53 -0
  188. package/tasks/qa-migration-validation.md +58 -0
  189. package/tasks/qa-nfr-assess.md +45 -0
  190. package/tasks/qa-review-story.md +56 -0
  191. package/tasks/qa-risk-profile.md +45 -0
  192. package/tasks/qa-security-checklist.md +64 -0
  193. package/tasks/qa-test-design.md +47 -0
  194. package/tasks/qa-trace-requirements.md +48 -0
  195. package/tasks/release-management.md +53 -0
  196. package/tasks/repository-cleanup.md +61 -0
  197. package/tasks/route.md +44 -0
  198. package/tasks/run-tests.md +50 -0
  199. package/tasks/security-audit.md +54 -0
  200. package/tasks/setup-database.md +60 -0
  201. package/tasks/setup-design-system.md +60 -0
  202. package/tasks/shard-doc.md +60 -0
  203. package/tasks/spec-assess-complexity.md +55 -0
  204. package/tasks/spec-critique.md +64 -0
  205. package/tasks/spec-gather-requirements.md +48 -0
  206. package/tasks/spec-research-dependencies.md +42 -0
  207. package/tasks/spec-write-spec.md +50 -0
  208. package/tasks/test-as-user.md +52 -0
  209. package/tasks/ux-create-wireframe.md +54 -0
  210. package/tasks/ux-user-research.md +55 -0
  211. package/tasks/validate-next-story.md +61 -0
  212. package/tasks/validate-squad.md +55 -0
  213. package/tasks/verify-subtask.md +52 -0
  214. package/tasks/version-management.md +45 -0
  215. package/templates/README.md +47 -0
  216. package/templates/architecture-tmpl.md +115 -0
  217. package/templates/competitor-analysis-tmpl.md +87 -0
  218. package/templates/epic-tmpl.md +83 -0
  219. package/templates/front-end-spec-tmpl.md +110 -0
  220. package/templates/market-research-tmpl.md +98 -0
  221. package/templates/migration-plan-tmpl.md +92 -0
  222. package/templates/prd-tmpl.md +95 -0
  223. package/templates/project-brief-tmpl.md +100 -0
  224. package/templates/qa-verdict-tmpl.md +73 -0
  225. package/templates/rls-policies-tmpl.md +93 -0
  226. package/templates/schema-design-tmpl.md +107 -0
  227. package/templates/spec-tmpl.md +88 -0
  228. package/templates/squad/agent-dna-tmpl.md +72 -0
  229. package/templates/squad/chief-dna-tmpl.md +98 -0
  230. package/templates/squad/squad-task-tmpl.md +50 -0
  231. package/templates/squad/squad-yaml-tmpl.md +47 -0
  232. package/templates/story-tmpl.md +63 -0
@@ -0,0 +1,383 @@
1
+ ---
2
+ id: accessible-component-patterns
3
+ domain: web-craft
4
+ agents: [ux-design-expert, dev]
5
+ when: "ao construir um componente interativo que precisa ser acessível"
6
+ ---
7
+
8
+ # Accessible Component Patterns — widgets que funcionam no teclado e no leitor de tela
9
+
10
+ ## O problema
11
+
12
+ A maioria dos componentes interativos "acessíveis" é acessível só na aparência. Os tells de um
13
+ componente que vai falhar com um usuário de teclado ou leitor de tela:
14
+
15
+ 1. **`<div onClick>` fingindo ser botão** — sem `role`, sem foco, sem resposta a Enter/Space. O leitor
16
+ de tela anuncia "grupo" ou nada.
17
+ 2. **ARIA decorativa** — `role="button"` colado num `<div>` mas **sem** o keyboard handler. Um `role`
18
+ é uma promessa: você prometeu Enter/Space e não entregou. Pior que não ter ARIA.
19
+ 3. **`aria-expanded` que nunca muda** — o atributo é setado uma vez no HTML e nunca atualizado pelo JS.
20
+ O leitor de tela diz "expandido" com o painel fechado.
21
+ 4. **Dropdown sem foco gerenciado** — abre o menu mas o foco continua no body; setas não navegam;
22
+ Escape não fecha; foco não volta pro gatilho ao fechar.
23
+ 5. **Modal que não prende o foco** — Tab vaza pra página atrás do overlay; Escape não fecha; ao fechar
24
+ o foco se perde no topo da página.
25
+ 6. **Tabs com todas as `tab` no tab order** — Tab passa por cada aba uma a uma em vez de setas
26
+ navegarem entre abas e Tab pular pro painel (roving tabindex ausente).
27
+ 7. **Foco invisível** — `outline: none` sem substituto. Ninguém de teclado sabe onde está.
28
+ 8. **`aria-label` em tudo, redundante** — `<button aria-label="Fechar">Fechar</button>` faz o leitor
29
+ ler "Fechar Fechar". Nome acessível duplicado.
30
+
31
+ A regra-mãe deste pack, direto do APG: **"No ARIA is better than bad ARIA."** E o corolário, a primeira
32
+ regra do ARIA: **se existe um elemento HTML nativo com a semântica e o comportamento que você precisa,
33
+ use ele em vez de reaproveitar um elemento e adicionar ARIA.** HTML nativo já traz foco, teclado,
34
+ semântica e estados — de graça e testado em todo AT.
35
+
36
+ ## O conhecimento
37
+
38
+ ### A primeira regra: HTML semântico primeiro (as 5 regras do ARIA)
39
+
40
+ Antes de escrever um único `role=`, passe por este filtro. Cada linha abaixo é uma troca concreta de
41
+ "ARIA caro e frágil" por "nativo barato e robusto":
42
+
43
+ | Quero… | NÃO faça (ARIA frágil) | Faça (nativo) |
44
+ |---|---|---|
45
+ | Botão | `<div role="button" tabindex="0">` + handlers de Enter/Space | `<button>` |
46
+ | Link | `<span role="link" tabindex="0">` | `<a href>` |
47
+ | Checkbox | `<div role="checkbox" aria-checked>` | `<input type="checkbox">` |
48
+ | Toggle on/off | `<div role="switch">` cru | `<input type="checkbox" role="switch">` (nativo + role) |
49
+ | Slider | `<div role="slider">` com todo o teclado na mão | `<input type="range">` |
50
+ | Select simples | combobox ARIA completa | `<select>` |
51
+ | Grupo de rádio | `role="radiogroup"` + `role="radio"` | `<fieldset>` + `<input type="radio">` |
52
+ | Progresso | `<div role="progressbar">` | `<progress>` |
53
+ | Seção colapsável simples | disclosure ARIA na mão | `<details>` / `<summary>` |
54
+ | Diálogo | `<div role="dialog">` + focus trap manual | `<dialog>` com `.showModal()` (trap + Escape de graça) |
55
+
56
+ Princípios literais do APG que governam tudo abaixo:
57
+
58
+ - **"A role is a promise."** Ao adicionar `role="X"`, você assume o contrato inteiro daquele role:
59
+ o mapa de teclado, o gerenciamento de foco e os estados. ARIA não dá comportamento — só rótulo
60
+ semântico. O comportamento é com você.
61
+ - **"ARIA can both cloak and enhance."** `role` sobrescreve a semântica nativa (perigoso: um
62
+ `role="presentation"` num `<button>` apaga o botão). Use para *acrescentar* significado, não apagar.
63
+ - **"Testing assistive technology interoperability is essential before using code from this guide in
64
+ production."** O APG não inclui workarounds para furos de suporte. Teste em NVDA/JAWS + VoiceOver
65
+ antes de mandar pra produção.
66
+
67
+ ---
68
+
69
+ ### Disclosure (seção mostra/esconde) — o widget mais simples, comece por ele
70
+
71
+ O controle que mostra/esconde conteúdo tem `role="button"` (ou é um `<button>` nativo — prefira).
72
+
73
+ | Atributo | Onde | Valor |
74
+ |---|---|---|
75
+ | `aria-expanded` | no botão | `true` com conteúdo visível, `false` com conteúdo escondido — **atualize no JS a cada toggle** |
76
+ | `aria-controls` | no botão (opcional) | id do elemento que contém o conteúdo mostrado/escondido |
77
+
78
+ **Teclado:** `Enter` e `Space` ativam o controle e alternam a visibilidade. (Com `<button>` nativo,
79
+ isso vem de graça.)
80
+
81
+ > Para o caso simples (um cabeçalho que abre um painel), `<details>`/`<summary>` resolve sem nenhum JS
82
+ > nem ARIA. Só vá pra disclosure ARIA quando precisar de controle fino sobre animação/estado.
83
+
84
+ ---
85
+
86
+ ### Dialog (modal) — `<dialog>` nativo primeiro
87
+
88
+ **Prefira `<dialog>` + `dialog.showModal()`**: o navegador dá focus trap, Escape para fechar, o backdrop
89
+ `::backdrop` e o "inert" do resto da página. Só caia para ARIA na mão se precisar de suporte legado.
90
+
91
+ Se for ARIA na mão, o container tem `role="dialog"` (ou `role="alertdialog"` para mensagem curta e
92
+ crítica que exige resposta).
93
+
94
+ | Atributo | Valor / regra |
95
+ |---|---|
96
+ | `aria-modal` | `true` no container do dialog |
97
+ | `aria-labelledby` | aponta para o título visível do dialog |
98
+ | `aria-label` | use só se não houver título visível |
99
+ | `aria-describedby` | (opcional) aponta para o texto descritivo; **omita** se o corpo tiver estrutura semântica complexa |
100
+
101
+ **Teclado:**
102
+
103
+ | Tecla | Comportamento |
104
+ |---|---|
105
+ | `Tab` | move para o próximo tabbable; **dá a volta para o primeiro** se estiver no último |
106
+ | `Shift + Tab` | move para o tabbable anterior; dá a volta para o último se estiver no primeiro |
107
+ | `Escape` | fecha o dialog |
108
+
109
+ **Focus management (o que mais erram):**
110
+
111
+ - **Ao abrir:** o foco move para dentro do dialog — para o primeiro elemento focável, ou para um
112
+ elemento estático com `tabindex="-1"` no início do conteúdo, ou (em operação destrutiva) para a
113
+ ação menos destrutiva.
114
+ - **Focus trap:** "Tab e Shift+Tab não movem o foco para fora do dialog." Implemente o ciclo você
115
+ mesmo se não usar `<dialog>` nativo.
116
+ - **Ao fechar:** o foco volta para o elemento que abriu o dialog — a menos que ele não exista mais ou
117
+ o fluxo indique outro destino.
118
+ - Inclua um botão visível com `role="button"` que fecha (ícone X ou Cancelar).
119
+
120
+ ---
121
+
122
+ ### Tabs — roving tabindex obrigatório
123
+
124
+ | Role | Onde |
125
+ |---|---|
126
+ | `tablist` | container do conjunto de abas |
127
+ | `tab` | cada aba, dentro do `tablist` |
128
+ | `tabpanel` | cada painel de conteúdo |
129
+
130
+ | Atributo | Onde | Valor |
131
+ |---|---|---|
132
+ | `aria-selected` | em cada `tab` | `true` na aba ativa, `false` em todas as outras |
133
+ | `aria-controls` | em cada `tab` | id do `tabpanel` associado |
134
+ | `aria-labelledby` | no `tabpanel` | id da `tab` que o rotula |
135
+ | `aria-labelledby`/`aria-label` | no `tablist` | rótulo do conjunto |
136
+ | `aria-orientation` | no `tablist` | `vertical` se vertical; default é `horizontal` |
137
+ | `tabindex` | nas `tab` e no `tabpanel` | **roving**: aba ativa `0`, demais `-1`; painel sem focáveis recebe `tabindex="0"` |
138
+
139
+ **Teclado (orientação horizontal):**
140
+
141
+ | Tecla | Comportamento |
142
+ |---|---|
143
+ | `Tab` | entra/sai do tablist; foca a aba ativa, depois pula para o painel — **não** percorre aba por aba |
144
+ | `Seta direita` | próxima aba; da última volta para a primeira |
145
+ | `Seta esquerda` | aba anterior; da primeira volta para a última |
146
+ | `Seta baixo/cima` | substituem direita/esquerda quando `aria-orientation="vertical"` |
147
+ | `Home` / `End` | (opcional) primeira / última aba |
148
+ | `Space` / `Enter` | ativa a aba, **se** não houver ativação automática no foco |
149
+
150
+ **Ativação automática vs manual:** o APG recomenda **ativação automática no foco** (a aba ativa ao
151
+ receber foco) *contanto que* o painel apareça sem latência perceptível. Se trocar de painel for caro
152
+ (fetch), use ativação manual (Space/Enter) e marque a aba focada sem ativá-la.
153
+
154
+ **Roving tabindex** é o mecanismo de foco aqui: só um `tab` está no tab order (`tabindex="0"`); as
155
+ setas movem o foco e atualizam qual elemento tem o `0`.
156
+
157
+ ---
158
+
159
+ ### Menu / Menubar — roving tabindex OU aria-activedescendant
160
+
161
+ Use `role="menu"`/`role="menubar"` **só para menus de aplicação/comando** (ações). Para um menu de
162
+ navegação do site, isto é o widget errado — use `<nav>` + lista de links.
163
+
164
+ | Role | Uso |
165
+ |---|---|
166
+ | `menubar` | barra de menus horizontal (default `aria-orientation="horizontal"`) |
167
+ | `menu` | container de itens / submenu (default `vertical`) |
168
+ | `menuitem` | item de ação |
169
+ | `menuitemcheckbox` | item alternável (use `aria-checked`) |
170
+ | `menuitemradio` | item de escolha exclusiva (use `aria-checked`) |
171
+
172
+ | Atributo | Valor |
173
+ |---|---|
174
+ | `aria-haspopup` | `menu` ou `true` no item que tem submenu |
175
+ | `aria-expanded` | `false` com submenu escondido, `true` com submenu visível |
176
+ | `aria-checked` | `true` quando `menuitemcheckbox`/`menuitemradio` marcado |
177
+ | `aria-disabled` | `true` em item desabilitado (mantém focável e anunciado) |
178
+ | `aria-orientation` | `vertical` (default de `menu`) ou `horizontal` (default de `menubar`) |
179
+ | `tabindex` | roving: container `-1`; primeiro item do menubar `0`; demais `-1` |
180
+ | `aria-activedescendant` | abordagem alternativa: no container, aponta para o id do item ativo |
181
+
182
+ **Teclado:**
183
+
184
+ | Tecla | Comportamento |
185
+ |---|---|
186
+ | `Enter` | abre submenu (se houver) ou ativa o item e fecha o menu |
187
+ | `Space` | (opcional) alterna checkbox; marca radio; ativa item ou abre submenu |
188
+ | `Seta baixo` | no menubar abre submenu; no menu vai pro próximo item (volta opcional) |
189
+ | `Seta cima` | no menu vai pro item anterior (volta opcional) |
190
+ | `Seta direita` | no menubar próximo item; em submenu abre submenu irmão ou vai pro próximo item do menubar |
191
+ | `Seta esquerda` | no menubar item anterior; em submenu fecha o submenu ou volta pro menubar |
192
+ | `Home` / `End` | primeiro / último item |
193
+ | caractere | (opcional) typeahead: vai pro próximo item que começa com o caractere |
194
+ | `Escape` | fecha o menu e devolve o foco ao elemento que o abriu |
195
+
196
+ **Foco:** roving tabindex (DOM focus real no item) **ou** `aria-activedescendant` (foco fica no
197
+ container, atributo aponta pro item ativo). Escolha um e seja consistente.
198
+
199
+ ---
200
+
201
+ ### Combobox — o widget mais complexo, decida o `aria-autocomplete` certo
202
+
203
+ `role="combobox"` vai no **input**; o popup é `role="listbox"` (ou `grid`/`tree`/`dialog`).
204
+
205
+ | Atributo | Onde | Valor |
206
+ |---|---|---|
207
+ | `role="combobox"` | no input | identifica o widget |
208
+ | `aria-expanded` | no combobox | `false` com popup escondido, `true` com popup visível |
209
+ | `aria-controls` | no combobox | id do elemento popup |
210
+ | `aria-activedescendant` | no combobox | id da opção em foco dentro do popup durante navegação por teclado |
211
+ | `aria-autocomplete` | no combobox | `none`, `list` ou `both` conforme o comportamento |
212
+ | `aria-haspopup` | no combobox | `grid`/`tree`/`dialog` (implícito `listbox` no role combobox) |
213
+ | `aria-selected` | nas opções do popup | `true` na sugestão visualmente selecionada |
214
+ | `aria-labelledby`/`aria-label` | no combobox | nome acessível se não houver `<label>` |
215
+
216
+ **Teclado — no input (combobox):**
217
+
218
+ | Tecla | Comportamento |
219
+ |---|---|
220
+ | `Seta baixo` | abre o popup ou move o foco para dentro dele |
221
+ | `Seta cima` (opcional) | foca o último item focável do popup |
222
+ | `Escape` | fecha o popup; opcionalmente limpa o combobox |
223
+ | `Enter` | aceita a sugestão de autocomplete |
224
+ | caracteres imprimíveis | digitam no input editável |
225
+ | `Alt + Seta baixo` (opcional) | abre o popup sem mover o foco |
226
+ | `Alt + Seta cima` (opcional) | fecha o popup e devolve o foco ao combobox |
227
+
228
+ **Teclado — no popup listbox:**
229
+
230
+ | Tecla | Comportamento |
231
+ |---|---|
232
+ | `Enter` | aceita a opção em foco; fecha o popup |
233
+ | `Escape` | fecha o popup; foco volta ao combobox |
234
+ | `Seta baixo` / `Seta cima` | próxima / anterior opção |
235
+ | `Seta direita` / `Seta esquerda` | volta o foco ao combobox (se editável) e move o cursor |
236
+ | `Home` / `End` (opcional) | primeira / última opção |
237
+
238
+ **Foco:** o foco **fica no input** o tempo todo. A "posição" no popup é virtual via
239
+ `aria-activedescendant` (e a opção ativa ganha estilo de foco no CSS). Não mova DOM focus para as
240
+ opções. Esse é o padrão correto de combobox — diferente de uma listbox standalone.
241
+
242
+ ---
243
+
244
+ ### Listbox — single vs multi-select muda o teclado inteiro
245
+
246
+ | Role | Uso |
247
+ |---|---|
248
+ | `listbox` | container das opções |
249
+ | `option` | item selecionável |
250
+ | `group` | (opcional) agrupa opções, owned pela listbox |
251
+
252
+ | Atributo | Valor |
253
+ |---|---|
254
+ | `aria-multiselectable` | `true` para multi; `false` (default) para single |
255
+ | `aria-selected` | estado de seleção na `option` (`true`/`false`) |
256
+ | `aria-activedescendant` | foco virtual: id da opção em foco, sem mover DOM focus |
257
+ | `aria-labelledby`/`aria-label` | nome acessível da listbox |
258
+ | `aria-setsize` / `aria-posinset` | total e posição (em carregamento dinâmico) |
259
+ | `aria-orientation` | `horizontal` se horizontal; default `vertical` |
260
+ | `tabindex` | torna a listbox focável |
261
+
262
+ **Single-select:**
263
+
264
+ | Tecla | Comportamento |
265
+ |---|---|
266
+ | `Seta baixo` / `Seta cima` | move o foco; opcionalmente seleciona |
267
+ | `Home` / `End` | primeira / última opção (recomendado para 5+ itens) |
268
+ | typeahead | move para a próxima opção que começa com o(s) caractere(s) |
269
+
270
+ **Multi-select (modelo recomendado):**
271
+
272
+ | Tecla | Comportamento |
273
+ |---|---|
274
+ | `Space` | alterna a seleção da opção em foco |
275
+ | `Shift + Seta baixo/cima` | move o foco e alterna a seleção da próxima/anterior (opcional) |
276
+ | `Shift + Space` | seleciona contíguos do último selecionado até o foco (opcional) |
277
+ | `Ctrl + Shift + Home/End` | seleciona o foco e todos os anteriores/posteriores (opcional) |
278
+ | `Ctrl + A` | seleciona tudo; opcionalmente desmarca tudo se já estiver tudo selecionado (opcional) |
279
+
280
+ **Foco e seleção são coisas distintas.** O APG é explícito: "DOM focus (o active element) é
281
+ funcionalmente distinto do estado de seleção." Não confunda foco com selecionado, exceto no modelo
282
+ "selection follows focus" (geralmente single-select). Ao focar a listbox, o foco vai para a opção
283
+ selecionada (ou a primeira, se nenhuma).
284
+
285
+ ---
286
+
287
+ ### Slider — `<input type="range">` quase sempre vence
288
+
289
+ **Prefira `<input type="range">`**: dá role, teclado, valores e foco nativos. Só vá para
290
+ `role="slider"` na mão para sliders exóticos (range duplo, vertical sem suporte nativo, formato custom).
291
+
292
+ Se for ARIA na mão, o controle focável tem `role="slider"`.
293
+
294
+ | Atributo | Valor |
295
+ |---|---|
296
+ | `aria-valuenow` | valor atual (decimal) — **obrigatório, atualize no JS** |
297
+ | `aria-valuemin` | valor mínimo (decimal) |
298
+ | `aria-valuemax` | valor máximo (decimal) |
299
+ | `aria-valuetext` | (opcional) rótulo legível quando `aria-valuenow` sozinho não é claro (ex.: "R$ 1.200", "Médio") |
300
+ | `aria-orientation` | `vertical` se aplicável; default `horizontal` |
301
+ | `aria-labelledby`/`aria-label` | rótulo do slider |
302
+
303
+ **Teclado:**
304
+
305
+ | Tecla | Comportamento |
306
+ |---|---|
307
+ | `Seta direita` / `Seta cima` | aumenta o valor em um passo |
308
+ | `Seta esquerda` / `Seta baixo` | diminui o valor em um passo |
309
+ | `Home` | valor mínimo |
310
+ | `End` | valor máximo |
311
+ | `Page Up` (opcional) | aumenta em um passo maior |
312
+ | `Page Down` (opcional) | diminui em um passo maior |
313
+
314
+ ---
315
+
316
+ ### Switch — `aria-checked` binário, sem `mixed`
317
+
318
+ `role="switch"` (ou `<input type="checkbox" role="switch">`, que ainda dá o teclado nativo).
319
+
320
+ | Atributo | Valor |
321
+ |---|---|
322
+ | `aria-checked` | `true` quando ligado, `false` quando desligado — **sem `mixed`** (diferente de checkbox tri-state) |
323
+
324
+ **Teclado:** `Space` alterna o estado; `Enter` (opcional) também alterna.
325
+
326
+ > O APG mostra três implementações (div, button, input checkbox) e **não** obriga uma. Escolha o role
327
+ > que melhor casa design e semântica — mas lembre que o caminho nativo (`input`) já entrega foco e
328
+ > teclado.
329
+
330
+ ---
331
+
332
+ ### Foco visível — não negociável em nenhum widget
333
+
334
+ Todo o teclado acima é inútil se ninguém vê onde está o foco.
335
+
336
+ ```css
337
+ /* Nunca remova o foco sem substituir. ERRADO: */
338
+ :focus { outline: none; }
339
+
340
+ /* CERTO: foco visível só para teclado, com a cor da marca */
341
+ :focus-visible {
342
+ outline: 2px solid var(--brand-focus, #4f46e5);
343
+ outline-offset: 2px;
344
+ border-radius: 3px;
345
+ }
346
+ /* zere o outline default só no foco por ponteiro, mantendo :focus-visible */
347
+ :focus:not(:focus-visible) { outline: none; }
348
+ ```
349
+
350
+ `:focus-visible` mostra o anel só quando o foco veio do teclado, não do clique — resolve a tensão
351
+ entre "designer odeia o anel no clique" e "usuário de teclado precisa do anel".
352
+
353
+ ## Checklist
354
+
355
+ Antes de entregar um componente interativo, qualquer "não" é um bug:
356
+
357
+ - [ ] Existe um elemento HTML nativo que faria isso? Se sim, estou usando ele em vez de ARIA?
358
+ - [ ] Todo `role=` que adicionei vem com o **mapa de teclado completo** daquele role implementado?
359
+ - [ ] Todo estado dinâmico (`aria-expanded`, `aria-selected`, `aria-checked`, `aria-valuenow`) é
360
+ **atualizado no JS** a cada mudança — não setado uma vez no HTML?
361
+ - [ ] `Escape` fecha o que abre (menu, dialog, popup do combobox)?
362
+ - [ ] Em dialog: foco entra ao abrir, fica preso (trap), e **volta ao gatilho** ao fechar?
363
+ - [ ] Em tabs/menu/listbox: uso **roving tabindex** ou `aria-activedescendant` — não tudo no tab order?
364
+ - [ ] Em combobox: o foco **permanece no input** e a navegação é via `aria-activedescendant`?
365
+ - [ ] O foco é **visível** (`:focus-visible` com contraste), sem `outline: none` solto?
366
+ - [ ] O nome acessível **não está duplicado** (texto visível + `aria-label` iguais)?
367
+ - [ ] Testei navegando só pelo teclado **e** com um leitor de tela real (NVDA/VoiceOver)?
368
+
369
+ ## Tabela de decisão
370
+
371
+ | Preciso de… | Use isto | Foco | Estados-chave | Não esqueça |
372
+ |---|---|---|---|---|
373
+ | Mostrar/esconder seção simples | `<details>`/`<summary>` ou `<button aria-expanded>` | nativo | `aria-expanded` | atualizar `aria-expanded` no toggle |
374
+ | Janela modal | `<dialog>` + `.showModal()` | trap + retorno ao gatilho | `aria-modal`, `aria-labelledby` | foco entra ao abrir, volta ao fechar, `Escape` |
375
+ | Abas de conteúdo | `tablist`/`tab`/`tabpanel` | roving tabindex | `aria-selected`, `aria-controls` | setas navegam, Tab pula pro painel |
376
+ | Menu de comandos/ações | `menu`/`menuitem` | roving ou activedescendant | `aria-haspopup`, `aria-expanded`, `aria-checked` | `Escape` fecha e devolve foco |
377
+ | Menu de navegação do site | `<nav>` + `<a href>` | nativo | — | **não** use `role="menu"` aqui |
378
+ | Input com sugestões | `combobox` + `listbox` | foco fica no input | `aria-expanded`, `aria-activedescendant`, `aria-autocomplete` | DOM focus nunca sai do input |
379
+ | Seleção em lista (1 ou N) | `listbox`/`option` | activedescendant ou roving | `aria-selected`, `aria-multiselectable` | foco ≠ seleção em multi-select |
380
+ | Controle de valor numérico | `<input type="range">` | nativo | `value` | só vá pra `role="slider"` se nativo não der |
381
+ | Slider custom (range duplo etc.) | `role="slider"` | DOM focus no thumb | `aria-valuenow/min/max`, `aria-valuetext` | atualizar `aria-valuenow` no JS |
382
+ | Liga/desliga | `<input type="checkbox" role="switch">` | nativo | `aria-checked` (sem `mixed`) | `Space` alterna |
383
+ | Botão, link, checkbox, radio, select, progress | elemento HTML nativo | nativo | nativos | **primeira regra do ARIA: não use ARIA** |
@@ -0,0 +1,114 @@
1
+ ---
2
+ id: anti-ai-look
3
+ domain: web-craft
4
+ agents: [ux-design-expert, dev]
5
+ when: "ao desenhar ou implementar qualquer página web que precisa parecer feita por um designer, não gerada por IA"
6
+ ---
7
+
8
+ # Anti-AI-Look — páginas que não parecem feitas por IA
9
+
10
+ Páginas geradas por IA têm uma "cara" reconhecível. O objetivo deste pack é fazer o agente **reconhecer
11
+ os tells e fugir deles**, produzindo algo que parece autoral. A regra-mãe: **uma decisão de design só
12
+ existe se você consegue justificar por que ela é assim e não o default.** Default não-justificado é o
13
+ que cheira a IA.
14
+
15
+ ## Os tells (reconheça pra evitar)
16
+
17
+ Se a página tem 3+ destes, ela grita "IA":
18
+
19
+ 1. **Estética de component-library default** — shadcn/ui ou Material sem customização: mesmos cantos
20
+ arredondados em tudo, sombras `shadow-md` genéricas, botões e cards idênticos aos da doc.
21
+ 2. **Tipografia Inter (ou system) em tudo**, um ou dois pesos, sem hierarquia real — títulos só "maior
22
+ e bold", nunca um contraste de caráter.
23
+ 3. **Gradiente índigo→violeta / roxo→rosa** no hero, em botões, em "blobs" de fundo. O gradiente da IA.
24
+ 4. **Glassmorphism e blur** aplicados sem motivo, em todo card.
25
+ 5. **Tudo centralizado** — hero centralizado, texto centralizado, um eixo vertical único do topo ao fim.
26
+ 6. **Grid de 3 cards de feature** com um ícone (lucide/emoji), um título de 2 palavras e um parágrafo
27
+ genérico. Quase sempre 3, quase sempre iguais.
28
+ 7. **Espaçamento uniforme** — tudo em múltiplos de 8 sem ritmo: nenhuma seção respira diferente da
29
+ outra, nenhuma tensão entre apertado e generoso.
30
+ 8. **Ilustrações de "blob 3D" / stock genérico / gradient mesh** sem relação com a marca.
31
+ 9. **Estrutura previsível** sem surpresa: hero → faixa de logos → 3 features → depoimento → CTA. Na
32
+ ordem, sempre.
33
+ 10. **Motion uniforme**: tudo faz o mesmo `fade-up` no scroll, mesma duração, mesmo easing.
34
+ 11. **Copy vaga de "empoderamento"**: "Empower your workflow", "Unlock your potential", "Seamlessly
35
+ integrate" — sem dizer o que o produto faz.
36
+ 12. **Detalhes esquecidos**: cor de seleção de texto default, foco azul do browser, favicon genérico,
37
+ sem OG image, botões todos com o mesmo raio.
38
+
39
+ ## Os princípios do craft (como o designer faz diferente)
40
+
41
+ ### 1. Sistema tipográfico, não "uma fonte"
42
+ - Pareie uma **display face com caráter** (serifa de contraste, grotesca com personalidade, ou uma
43
+ fonte de marca) para títulos com uma **workhorse legível** para corpo. O contraste entre as duas é
44
+ metade da personalidade da página.
45
+ - Defina uma **escala modular** (ex.: razão ~1.2–1.333) em vez de tamanhos avulsos. Hierarquia vem da
46
+ escala, do peso E do tracking/leading — não só de "maior".
47
+ - Ajuste **tracking** (apertado em display grande, neutro em corpo) e **leading** (1.1–1.2 em títulos,
48
+ 1.5–1.7 em corpo). `line-height: 1.5` em título é tell de IA.
49
+ - Use no máximo 2 famílias. Caráter vem do par, não da quantidade.
50
+
51
+ ### 2. Cor derivada de uma ideia, não o gradiente default
52
+ - Comece de um **conceito de marca** (uma palavra: "editorial", "brutalista", "calmo", "premium") e
53
+ derive a paleta dela. Um **accent confiante** + neutros **com temperatura** (cinzas levemente
54
+ quentes ou frios, nunca `#808080` puro).
55
+ - **Fuja do gradiente índigo→violeta.** Se for usar gradiente, que seja sutil, de marca, e raro.
56
+ - Tenha um **dark e light de verdade** (não só inverter), e estados (hover/focus/active) pensados.
57
+
58
+ ### 3. Layout editorial, não cards empilhados
59
+ - **Quebre o grid de propósito**: sobreposição, assimetria, um elemento que sangra pra fora da coluna,
60
+ uma imagem que cruza duas seções. O olho lembra do inesperado.
61
+ - Crie **um ponto focal por tela** e uma hierarquia clara — não 3 cards de peso igual competindo.
62
+ - Use **whitespace como ferramenta de ênfase**: generoso onde importa, apertado onde agrupa. Contraste
63
+ de densidade é o que parece intencional.
64
+
65
+ ### 4. Ritmo de espaço, não múltiplos uniformes
66
+ - Tenha uma **escala de espaço** com contraste (ex.: 4, 8, 16, 32, 64, 128) e **use os extremos**. Uma
67
+ seção colada e outra arejada criam ritmo; tudo em 24px é monótono e robótico.
68
+
69
+ ### 5. Motion art-directed, com restrição
70
+ - **Stagger** (elementos entram em sequência, não todos juntos), **scroll-linked** onde faz sentido,
71
+ **easing com caráter** (não o `ease` default; uma curva custom). Duração varia por elemento.
72
+ - Menos é mais: 2–3 momentos de motion memoráveis batem 1 animação repetida em tudo.
73
+ - Respeite `prefers-reduced-motion`.
74
+
75
+ ### 6. Imagem e textura com intenção
76
+ - Foto real art-direcionada, ou ilustração de estilo consistente, ou tipografia-como-imagem. **Nunca**
77
+ blob 3D aleatório ou stock que não conversa com a marca.
78
+ - Textura sutil (grão, ruído, uma borda, um detalhe gráfico recorrente) tira o aspecto "template".
79
+
80
+ ### 7. Copy específica, com voz
81
+ - Diga **o que o produto faz e pra quem**, com concretude e ponto de vista. "Agende posts pros 7 canais
82
+ em 2 minutos" vence "Streamline your social presence".
83
+ - Microcopy com personalidade (botões, estados vazios, mensagens de erro) é assinatura barata e forte.
84
+
85
+ ### 8. Os detalhes que ninguém da IA lembra
86
+ - `::selection` com cor de marca · estados de **foco** desenhados (não o anel azul do browser) ·
87
+ **favicon** e **OG image** próprios · raios de canto **variados por propósito** · um cursor/hover
88
+ state pensado · tipografia responsiva (clamp) · 404 e estados vazios com voz.
89
+
90
+ ## Checklist "isto parece de IA?"
91
+
92
+ Antes de entregar, responda — qualquer "sim" é um tell a corrigir:
93
+
94
+ - [ ] A tipografia é Inter/system em tudo, um ou dois pesos, sem par de caráter?
95
+ - [ ] Tem gradiente índigo/violeta/roxo-rosa em algum lugar de destaque?
96
+ - [ ] O hero e a página são centralizados num eixo único?
97
+ - [ ] Tem um grid de 3 cards iguais com ícone + título curto + parágrafo genérico?
98
+ - [ ] O espaçamento é uniforme, sem seção respirando diferente da outra?
99
+ - [ ] As ilustrações são blob 3D / stock / mesh sem relação com a marca?
100
+ - [ ] A estrutura é hero→logos→features→depoimento→CTA sem nenhuma surpresa?
101
+ - [ ] Todo elemento faz o mesmo fade-up no scroll?
102
+ - [ ] A copy fala em "empower/unlock/seamless" sem dizer o que o produto faz?
103
+ - [ ] Faltou `::selection`, foco custom, favicon, OG image?
104
+
105
+ ## Antes → depois
106
+
107
+ | Tell (IA) | Craft (bespoke) |
108
+ |---|---|
109
+ | Inter 700 pra título, Inter 400 pra corpo | Display de caráter (ex.: uma grotesca com personalidade) + workhorse legível, escala modular |
110
+ | Hero centralizado com gradiente roxo e botão arredondado | Composição assimétrica, paleta de marca, tipografia grande como protagonista |
111
+ | 3 cards "⚡ Fast / 🔒 Secure / 🚀 Scalable" | 1 prova concreta com número real + layout editorial que destaca o que importa |
112
+ | Tudo `gap-8`, `py-16` | Ritmo: seção densa de prova social, seção arejada de manifesto |
113
+ | `transition: all .3s ease`, fade-up em tudo | Stagger no hero, parallax sutil numa imagem, easing custom, resto quieto |
114
+ | "Empower your workflow today" | "Publique nos 7 canais em 1 clique — e veja o que rendeu" |