@luanpdd/kit-mcp 1.34.0 → 1.36.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.
- package/README.md +1 -1
- package/bin/cli.js +2 -2
- package/bin/mcp.js +6 -6
- package/bin/ui.js +74 -74
- package/gates/ai-prompt-stability.md +120 -120
- package/gates/budget-description.md +68 -68
- package/gates/confidence.md +29 -29
- package/gates/dependency-check.md +33 -33
- package/gates/dept-cycle-prevention.md +179 -179
- package/gates/golden-signals-coverage.md +133 -133
- package/gates/legacy-refactor-safety.md +178 -178
- package/gates/multi-tenant-rls-coverage.md +102 -102
- package/gates/no-personal-uuid.md +72 -72
- package/gates/obs-agents-mcp-supabase.md +86 -86
- package/gates/obs-skills-frontmatter.md +76 -76
- package/gates/observability-coverage.md +151 -151
- package/gates/omm-no-regression.md +83 -83
- package/gates/postmortem-template-required.md +127 -127
- package/gates/prr-checklist-coverage.md +128 -128
- package/gates/regression.md +32 -32
- package/gates/release-pipeline-policy.md +132 -132
- package/gates/secrets-scan.md +33 -33
- package/gates/service-role-not-in-user-facing.md +113 -113
- package/gates/skill-must-include.md +71 -71
- package/gates/sync-idempotent.md +62 -62
- package/gates/verify-phase-goal.md +34 -34
- package/kit/agents/designer-ui.md +216 -216
- package/kit/agents/workflow-generator.md +537 -0
- package/kit/commands/adicionar-backlog.md +1 -1
- package/kit/commands/adicionar-fase.md +1 -1
- package/kit/commands/adicionar-tarefa.md +1 -1
- package/kit/commands/auditar-observabilidade.md +103 -103
- package/kit/commands/auditar-toil.md +129 -129
- package/kit/commands/caracterizar-prompt.md +195 -195
- package/kit/commands/criar-workflow.md +158 -0
- package/kit/commands/definir-perfil.md +1 -1
- package/kit/commands/definir-slo.md +108 -108
- package/kit/commands/fio.md +1 -1
- package/kit/commands/golden-signals.md +142 -142
- package/kit/commands/instrumentar-fase.md +200 -200
- package/kit/commands/investigar-producao.md +162 -162
- package/kit/commands/observabilidade.md +118 -118
- package/kit/commands/postmortem.md +179 -179
- package/kit/commands/prr.md +205 -205
- package/kit/commands/publicar-rapido.md +207 -207
- package/kit/commands/risk-budget.md +220 -220
- package/kit/commands/sre.md +230 -230
- package/kit/file-manifest.json +5 -2
- package/kit/framework/references/output-style.md +22 -22
- package/kit/hooks/post-apply-migration.js +199 -199
- package/kit/hooks/sidecar-tool-publisher.js +210 -210
- package/kit/skills/_shared-dados-distribuidos/glossary.md +224 -224
- package/kit/skills/_shared-legacy/glossary.md +389 -389
- package/kit/skills/_shared-multi-tenant/glossary.md +186 -186
- package/kit/skills/_shared-observability/glossary.md +396 -396
- package/kit/skills/_shared-sre/glossary.md +712 -712
- package/kit/skills/_shared-supabase/glossary.md +234 -234
- package/kit/skills/blameless-postmortems/SKILL.md +340 -340
- package/kit/skills/burn-rate-alerting/SKILL.md +258 -258
- package/kit/skills/cascading-failures/SKILL.md +311 -311
- package/kit/skills/core-analysis-loop/SKILL.md +352 -352
- package/kit/skills/distributed-tracing/SKILL.md +362 -362
- package/kit/skills/dynamic-workflow-authoring/SKILL.md +327 -0
- package/kit/skills/eliminating-toil/SKILL.md +243 -243
- package/kit/skills/event-based-slos/SKILL.md +296 -296
- package/kit/skills/four-golden-signals/SKILL.md +314 -314
- package/kit/skills/hermetic-builds/SKILL.md +323 -323
- package/kit/skills/legacy-monster-methods/SKILL.md +444 -444
- package/kit/skills/llm-as-dependency/SKILL.md +436 -436
- package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -396
- package/kit/skills/observability-driven-development/SKILL.md +315 -315
- package/kit/skills/observability-maturity-model/SKILL.md +222 -222
- package/kit/skills/opentelemetry-standard/SKILL.md +351 -351
- package/kit/skills/production-readiness-review/SKILL.md +305 -305
- package/kit/skills/release-engineering/SKILL.md +367 -367
- package/kit/skills/retry-strategies/SKILL.md +372 -372
- package/kit/skills/sre-risk-management/SKILL.md +221 -221
- package/kit/skills/structured-events/SKILL.md +265 -265
- package/kit/skills/supabase-cron-queues/SKILL.md +275 -275
- package/kit/skills/supabase-database-functions/SKILL.md +332 -332
- package/kit/skills/supabase-declarative-schema/SKILL.md +183 -183
- package/kit/skills/supabase-pgvector-rag/SKILL.md +253 -253
- package/kit/skills/supabase-postgres-style/SKILL.md +138 -138
- package/kit/skills/supabase-storage/SKILL.md +234 -234
- package/kit/skills/telemetry-pipelines/SKILL.md +259 -259
- package/kit/skills/telemetry-sampling/SKILL.md +256 -256
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
- package/kit/skills/ui-tipografia/SKILL.md +211 -211
- package/package.json +1 -1
- package/src/cli/index.js +1114 -1114
- package/src/cli/render.js +194 -194
- package/src/cli/upgrade-check.js +135 -135
- package/src/core/error-redaction.js +76 -76
- package/src/core/failures.js +153 -153
- package/src/core/gate-runner.js +205 -205
- package/src/core/gates.js +82 -82
- package/src/core/logger.js +170 -170
- package/src/core/manifest-verify.js +174 -174
- package/src/core/metrics.js +268 -268
- package/src/core/notify.js +60 -60
- package/src/core/path-safety.js +141 -141
- package/src/core/replays.js +120 -120
- package/src/core/ui.js +185 -185
- package/src/mcp-server/install.js +149 -149
- package/src/mcp-server/roots.js +124 -124
- package/src/ui/auto-spawn.js +113 -113
- package/src/ui/browser.js +78 -78
- package/src/ui/client.js +130 -130
- package/src/ui/events.js +65 -65
- package/src/ui/lockfile.js +191 -191
- package/src/ui/port.js +67 -67
- package/src/ui/server.js +547 -547
- package/src/ui/wrapper.js +129 -129
|
@@ -1,259 +1,259 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ui-ritmo-espacial
|
|
3
|
-
description: Use ao definir spacing/padding/grid — escala base 4 (4/8/16/24/32/48/64/96), alinhamento optico != matematico, breathing room no viewport edge, sem arbitrary [13px] nem padding cramped.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# UI — Ritmo Espacial
|
|
7
|
-
|
|
8
|
-
## Quando usar
|
|
9
|
-
|
|
10
|
-
LLM carrega esta skill quando:
|
|
11
|
-
|
|
12
|
-
- "Espaçamento parece estranho / cramped / inconsistente"
|
|
13
|
-
- "Alinhar elementos / grid / layout"
|
|
14
|
-
- "Padding em botão / card / dialog"
|
|
15
|
-
- "Container width / max-width"
|
|
16
|
-
- "Optical alignment" / "está 1px off"
|
|
17
|
-
- Preenchendo seção **Componentes** com spacing rules
|
|
18
|
-
|
|
19
|
-
## Regras absolutas
|
|
20
|
-
|
|
21
|
-
**REGRA #1 (escala base-4):** Spacing apenas em múltiplos de 4. Permitidos: `4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96, 128`. **Proibidos:** valores arbitrários `[13px]`, `[27px]`, `[1.7rem]`. Se você precisa de um, problema é de escala não documentada.
|
|
22
|
-
|
|
23
|
-
**REGRA #2 (3 níveis de densidade):**
|
|
24
|
-
- **Densa** (`gap-1`/`p-2`/`px-3`): tables, data grids, command palettes
|
|
25
|
-
- **Padrão** (`gap-4`/`p-4`/`px-6`): cards, forms, sections
|
|
26
|
-
- **Generosa** (`gap-8`/`p-8`/`px-12`): heroes, marketing, empty states
|
|
27
|
-
|
|
28
|
-
Misturar densa + generosa na mesma seção = ritmo quebrado.
|
|
29
|
-
|
|
30
|
-
**REGRA #3 (no edge flush):** Texto e UI sempre com padding lateral mínimo `px-4` (mobile) → `px-6` (tablet) → `px-8` (desktop). Conteúdo nunca encosta na viewport.
|
|
31
|
-
|
|
32
|
-
**REGRA #4 (container width em ch):** Containers de texto têm `max-width` em `ch` unit (50-75ch body). Container de UI em `max-w-7xl` (1280px) ou `max-w-5xl` (1024px) padrão.
|
|
33
|
-
|
|
34
|
-
**REGRA #5 (alinhamento óptico):** Ícones e glifos têm bounding box que ≠ shape óptico. Centralização matemática vê desalinhada. Compense: setas/triângulos shift -1 ou -2 px na direção oposta da ponta. Texto + ícone vertical alinha pela `cap-height`, não pela baseline.
|
|
35
|
-
|
|
36
|
-
## Escala canônica
|
|
37
|
-
|
|
38
|
-
```js
|
|
39
|
-
// tailwind.config.js — restrinja explicit, esconda o resto
|
|
40
|
-
module.exports = {
|
|
41
|
-
theme: {
|
|
42
|
-
spacing: {
|
|
43
|
-
'0': '0',
|
|
44
|
-
'px': '1px',
|
|
45
|
-
'0.5': '2px', // só para borders/dividers
|
|
46
|
-
'1': '4px',
|
|
47
|
-
'2': '8px',
|
|
48
|
-
'3': '12px',
|
|
49
|
-
'4': '16px',
|
|
50
|
-
'5': '20px',
|
|
51
|
-
'6': '24px',
|
|
52
|
-
'8': '32px',
|
|
53
|
-
'10': '40px',
|
|
54
|
-
'12': '48px',
|
|
55
|
-
'16': '64px',
|
|
56
|
-
'20': '80px',
|
|
57
|
-
'24': '96px',
|
|
58
|
-
'32': '128px',
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Não inclua `7`, `9`, `11`, `14`, etc — força escolha de uma escala vizinha em vez de "tô em dúvida, vou de meio termo".
|
|
65
|
-
|
|
66
|
-
## Patterns canônicos
|
|
67
|
-
|
|
68
|
-
### Padding interno por componente
|
|
69
|
-
|
|
70
|
-
| Componente | Padding | Notas |
|
|
71
|
-
|------------|---------|-------|
|
|
72
|
-
| Button (padrão) | `px-4 py-2` (h-10) | min 44px touch target |
|
|
73
|
-
| Button (sm) | `px-3 py-1.5` (h-9) | minimum, densidade-tight |
|
|
74
|
-
| Button (lg) | `px-6 py-3` (h-12) | CTA hero |
|
|
75
|
-
| Input | `px-3 py-2` (h-10) | espaço para focus ring outside |
|
|
76
|
-
| Card (padrão) | `p-6` | conteúdo respira |
|
|
77
|
-
| Card (denso) | `p-4` | em lista de muitos |
|
|
78
|
-
| Dialog | `p-6` (mobile) / `p-8` (desktop) | conteúdo central |
|
|
79
|
-
| Badge / Chip | `px-2 py-0.5` | exceção à base-4, ok |
|
|
80
|
-
| Section (vertical) | `py-16` (mobile) / `py-24` (desktop) | hero/marketing |
|
|
81
|
-
| Section (vertical, produto) | `py-8` / `py-12` | denso |
|
|
82
|
-
|
|
83
|
-
### Container patterns
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
// Layout shell
|
|
87
|
-
<div className="min-h-screen">
|
|
88
|
-
<header className="border-b">
|
|
89
|
-
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 h-16 flex items-center">
|
|
90
|
-
{/* nav */}
|
|
91
|
-
</div>
|
|
92
|
-
</header>
|
|
93
|
-
|
|
94
|
-
<main>
|
|
95
|
-
{/* Marketing section */}
|
|
96
|
-
<section className="mx-auto max-w-5xl px-4 sm:px-6 lg:px-8 py-16 lg:py-24">
|
|
97
|
-
<h1 className="max-w-[18ch] text-balance text-6xl">…</h1>
|
|
98
|
-
<p className="max-w-[50ch] mt-6 text-lg text-muted-foreground">…</p>
|
|
99
|
-
</section>
|
|
100
|
-
|
|
101
|
-
{/* Produto dashboard */}
|
|
102
|
-
<section className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8">
|
|
103
|
-
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">…</div>
|
|
104
|
-
</section>
|
|
105
|
-
|
|
106
|
-
{/* Prose article */}
|
|
107
|
-
<article className="mx-auto max-w-prose px-4 sm:px-6 py-12">
|
|
108
|
-
{/* max-w-prose = 65ch */}
|
|
109
|
-
</article>
|
|
110
|
-
</main>
|
|
111
|
-
</div>
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Ritmo vertical em prose
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
<article className="prose">
|
|
118
|
-
<h1 className="mb-8">…</h1> {/* h1 + spacing maior abaixo */}
|
|
119
|
-
<h2 className="mt-12 mb-4">…</h2> {/* h2 separa seções */}
|
|
120
|
-
<p className="mb-4 leading-7">…</p>{/* p body */}
|
|
121
|
-
<ul className="my-4 space-y-2">…</ul>
|
|
122
|
-
</article>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Regra: spacing acima de heading > spacing abaixo. Senão heading "flutua" no meio.
|
|
126
|
-
|
|
127
|
-
### Alinhamento óptico
|
|
128
|
-
|
|
129
|
-
```tsx
|
|
130
|
-
// Texto + ícone: align pelo center vertical, não baseline
|
|
131
|
-
<button className="inline-flex items-center gap-2">
|
|
132
|
-
<ArrowRight className="size-4 -translate-y-px" /> {/* -1px opcional para cap-height match */}
|
|
133
|
-
<span>Próximo</span>
|
|
134
|
-
</button>
|
|
135
|
-
|
|
136
|
-
// Heading + ícone decorativo: ícone alinha pelo x-height, não top
|
|
137
|
-
<h2 className="flex items-baseline gap-2">
|
|
138
|
-
<Sparkles className="size-5 translate-y-1" /> {/* push down to baseline-ish */}
|
|
139
|
-
<span>Feature</span>
|
|
140
|
-
</h2>
|
|
141
|
-
|
|
142
|
-
// Pill button: padding horizontal mais leve que vertical estaria — compense
|
|
143
|
-
<button className="rounded-full px-4 py-2"> {/* px-4 não px-3 — pill rouba H */}
|
|
144
|
-
Ação
|
|
145
|
-
</button>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Anti-patterns
|
|
149
|
-
|
|
150
|
-
### Anti-pattern 1: arbitrary values salpicados
|
|
151
|
-
|
|
152
|
-
**Errado:**
|
|
153
|
-
```tsx
|
|
154
|
-
<div className="p-[13px] mt-[27px] gap-[18px]">…</div>
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Por quê:** REGRA #1 — escala se desfaz. Outro dev vê `13px` e adiciona `15px` ao lado. Em 6 meses ninguém sabe o que é "spacing default".
|
|
158
|
-
|
|
159
|
-
**Certo:** `p-3 mt-6 gap-4` (12/24/16, todos na escala). Se realmente precisa de um valor fora, adicione ao theme em vez de inline.
|
|
160
|
-
|
|
161
|
-
### Anti-pattern 2: padding cramped em interactive
|
|
162
|
-
|
|
163
|
-
**Errado:** `<button className="px-2 py-1">Salvar</button>`
|
|
164
|
-
|
|
165
|
-
**Por quê:** Q06 — touch hit area pequena + densidade desconfortável. Botão difícil de clicar.
|
|
166
|
-
|
|
167
|
-
**Certo:** `px-4 py-2` mínimo. Botão denso `px-3 py-1.5` apenas em toolbar.
|
|
168
|
-
|
|
169
|
-
### Anti-pattern 3: section sem padding lateral em mobile
|
|
170
|
-
|
|
171
|
-
**Errado:**
|
|
172
|
-
```tsx
|
|
173
|
-
<section className="max-w-7xl mx-auto py-16">
|
|
174
|
-
<h1 className="text-4xl">Title</h1> {/* encosta na borda em mobile */}
|
|
175
|
-
</section>
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**Por quê:** REGRA #3 — texto sem ar para respirar + acessibilidade em landscape narrow.
|
|
179
|
-
|
|
180
|
-
**Certo:**
|
|
181
|
-
```tsx
|
|
182
|
-
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Anti-pattern 4: hero text sem max-width
|
|
186
|
-
|
|
187
|
-
**Errado:**
|
|
188
|
-
```tsx
|
|
189
|
-
<h1 className="text-6xl">Build amazing products with our platform today</h1>
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
**Por quê:** REGRA #4 — line-length destruído em widescreen, leitura interrompida.
|
|
193
|
-
|
|
194
|
-
**Certo:**
|
|
195
|
-
```tsx
|
|
196
|
-
<h1 className="text-6xl max-w-[18ch] text-balance leading-tight">
|
|
197
|
-
Build amazing products
|
|
198
|
-
</h1>
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Anti-pattern 5: misturar densidades sem motivo
|
|
202
|
-
|
|
203
|
-
**Errado:**
|
|
204
|
-
```tsx
|
|
205
|
-
<Card className="p-2"> {/* densa */}
|
|
206
|
-
<CardHeader className="p-8"> {/* generosa */}
|
|
207
|
-
<CardTitle>...</CardTitle>
|
|
208
|
-
</CardHeader>
|
|
209
|
-
<CardContent className="p-4"> {/* padrão */}
|
|
210
|
-
...
|
|
211
|
-
</CardContent>
|
|
212
|
-
</Card>
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Por quê:** REGRA #2 — ritmo quebrado, agente IA depois não sabe qual densidade replicar.
|
|
216
|
-
|
|
217
|
-
**Certo:** uma densidade por componente. Card denso = todo o card `p-4` máximo. Card padrão = todo o card `p-6`.
|
|
218
|
-
|
|
219
|
-
### Anti-pattern 6: alinhar centro com texto
|
|
220
|
-
|
|
221
|
-
**Errado:**
|
|
222
|
-
```tsx
|
|
223
|
-
<div className="flex items-center">
|
|
224
|
-
<Icon />
|
|
225
|
-
<h2>Heading</h2>
|
|
226
|
-
</div>
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
Pixel-perfect: ícone tem `cap-height` diferente do texto.
|
|
230
|
-
|
|
231
|
-
**Certo:**
|
|
232
|
-
```tsx
|
|
233
|
-
<div className="flex items-baseline gap-2"> {/* ou items-center + ícone -translate-y-px */}
|
|
234
|
-
<Icon className="translate-y-0.5" />
|
|
235
|
-
<h2>Heading</h2>
|
|
236
|
-
</div>
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
## Detecção
|
|
240
|
-
|
|
241
|
-
```bash
|
|
242
|
-
# Arbitrary spacing values
|
|
243
|
-
grep -rnE "(p|m|gap|space)-(x|y)?-\[[0-9]+(px|rem)\]" src --include="*.tsx" 2>/dev/null
|
|
244
|
-
|
|
245
|
-
# Edge flush
|
|
246
|
-
grep -rnE "max-w-7xl.*mx-auto.*py-" src --include="*.tsx" 2>/dev/null | grep -v "px-"
|
|
247
|
-
|
|
248
|
-
# Botão cramped
|
|
249
|
-
grep -rnE "<(button|Button)[^>]*\bp[xy]?-(1|2)\b" src --include="*.tsx" 2>/dev/null
|
|
250
|
-
|
|
251
|
-
# Hero sem max-w em ch
|
|
252
|
-
grep -rnE "text-(5xl|6xl|7xl|8xl|9xl)" src --include="*.tsx" 2>/dev/null | grep -v "max-w-\["
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
## Ver também
|
|
256
|
-
|
|
257
|
-
- [ui-anti-padroes-ia](../ui-anti-padroes-ia/SKILL.md) — Q02 (edge flush), Q06 (padding cramped)
|
|
258
|
-
- [ui-tipografia](../ui-tipografia/SKILL.md) — line-length em ch
|
|
259
|
-
- [ui-contexto-produto](../ui-contexto-produto/SKILL.md) — escala vai em DESIGN.json
|
|
1
|
+
---
|
|
2
|
+
name: ui-ritmo-espacial
|
|
3
|
+
description: Use ao definir spacing/padding/grid — escala base 4 (4/8/16/24/32/48/64/96), alinhamento optico != matematico, breathing room no viewport edge, sem arbitrary [13px] nem padding cramped.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# UI — Ritmo Espacial
|
|
7
|
+
|
|
8
|
+
## Quando usar
|
|
9
|
+
|
|
10
|
+
LLM carrega esta skill quando:
|
|
11
|
+
|
|
12
|
+
- "Espaçamento parece estranho / cramped / inconsistente"
|
|
13
|
+
- "Alinhar elementos / grid / layout"
|
|
14
|
+
- "Padding em botão / card / dialog"
|
|
15
|
+
- "Container width / max-width"
|
|
16
|
+
- "Optical alignment" / "está 1px off"
|
|
17
|
+
- Preenchendo seção **Componentes** com spacing rules
|
|
18
|
+
|
|
19
|
+
## Regras absolutas
|
|
20
|
+
|
|
21
|
+
**REGRA #1 (escala base-4):** Spacing apenas em múltiplos de 4. Permitidos: `4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96, 128`. **Proibidos:** valores arbitrários `[13px]`, `[27px]`, `[1.7rem]`. Se você precisa de um, problema é de escala não documentada.
|
|
22
|
+
|
|
23
|
+
**REGRA #2 (3 níveis de densidade):**
|
|
24
|
+
- **Densa** (`gap-1`/`p-2`/`px-3`): tables, data grids, command palettes
|
|
25
|
+
- **Padrão** (`gap-4`/`p-4`/`px-6`): cards, forms, sections
|
|
26
|
+
- **Generosa** (`gap-8`/`p-8`/`px-12`): heroes, marketing, empty states
|
|
27
|
+
|
|
28
|
+
Misturar densa + generosa na mesma seção = ritmo quebrado.
|
|
29
|
+
|
|
30
|
+
**REGRA #3 (no edge flush):** Texto e UI sempre com padding lateral mínimo `px-4` (mobile) → `px-6` (tablet) → `px-8` (desktop). Conteúdo nunca encosta na viewport.
|
|
31
|
+
|
|
32
|
+
**REGRA #4 (container width em ch):** Containers de texto têm `max-width` em `ch` unit (50-75ch body). Container de UI em `max-w-7xl` (1280px) ou `max-w-5xl` (1024px) padrão.
|
|
33
|
+
|
|
34
|
+
**REGRA #5 (alinhamento óptico):** Ícones e glifos têm bounding box que ≠ shape óptico. Centralização matemática vê desalinhada. Compense: setas/triângulos shift -1 ou -2 px na direção oposta da ponta. Texto + ícone vertical alinha pela `cap-height`, não pela baseline.
|
|
35
|
+
|
|
36
|
+
## Escala canônica
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
// tailwind.config.js — restrinja explicit, esconda o resto
|
|
40
|
+
module.exports = {
|
|
41
|
+
theme: {
|
|
42
|
+
spacing: {
|
|
43
|
+
'0': '0',
|
|
44
|
+
'px': '1px',
|
|
45
|
+
'0.5': '2px', // só para borders/dividers
|
|
46
|
+
'1': '4px',
|
|
47
|
+
'2': '8px',
|
|
48
|
+
'3': '12px',
|
|
49
|
+
'4': '16px',
|
|
50
|
+
'5': '20px',
|
|
51
|
+
'6': '24px',
|
|
52
|
+
'8': '32px',
|
|
53
|
+
'10': '40px',
|
|
54
|
+
'12': '48px',
|
|
55
|
+
'16': '64px',
|
|
56
|
+
'20': '80px',
|
|
57
|
+
'24': '96px',
|
|
58
|
+
'32': '128px',
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Não inclua `7`, `9`, `11`, `14`, etc — força escolha de uma escala vizinha em vez de "tô em dúvida, vou de meio termo".
|
|
65
|
+
|
|
66
|
+
## Patterns canônicos
|
|
67
|
+
|
|
68
|
+
### Padding interno por componente
|
|
69
|
+
|
|
70
|
+
| Componente | Padding | Notas |
|
|
71
|
+
|------------|---------|-------|
|
|
72
|
+
| Button (padrão) | `px-4 py-2` (h-10) | min 44px touch target |
|
|
73
|
+
| Button (sm) | `px-3 py-1.5` (h-9) | minimum, densidade-tight |
|
|
74
|
+
| Button (lg) | `px-6 py-3` (h-12) | CTA hero |
|
|
75
|
+
| Input | `px-3 py-2` (h-10) | espaço para focus ring outside |
|
|
76
|
+
| Card (padrão) | `p-6` | conteúdo respira |
|
|
77
|
+
| Card (denso) | `p-4` | em lista de muitos |
|
|
78
|
+
| Dialog | `p-6` (mobile) / `p-8` (desktop) | conteúdo central |
|
|
79
|
+
| Badge / Chip | `px-2 py-0.5` | exceção à base-4, ok |
|
|
80
|
+
| Section (vertical) | `py-16` (mobile) / `py-24` (desktop) | hero/marketing |
|
|
81
|
+
| Section (vertical, produto) | `py-8` / `py-12` | denso |
|
|
82
|
+
|
|
83
|
+
### Container patterns
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
// Layout shell
|
|
87
|
+
<div className="min-h-screen">
|
|
88
|
+
<header className="border-b">
|
|
89
|
+
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 h-16 flex items-center">
|
|
90
|
+
{/* nav */}
|
|
91
|
+
</div>
|
|
92
|
+
</header>
|
|
93
|
+
|
|
94
|
+
<main>
|
|
95
|
+
{/* Marketing section */}
|
|
96
|
+
<section className="mx-auto max-w-5xl px-4 sm:px-6 lg:px-8 py-16 lg:py-24">
|
|
97
|
+
<h1 className="max-w-[18ch] text-balance text-6xl">…</h1>
|
|
98
|
+
<p className="max-w-[50ch] mt-6 text-lg text-muted-foreground">…</p>
|
|
99
|
+
</section>
|
|
100
|
+
|
|
101
|
+
{/* Produto dashboard */}
|
|
102
|
+
<section className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8">
|
|
103
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">…</div>
|
|
104
|
+
</section>
|
|
105
|
+
|
|
106
|
+
{/* Prose article */}
|
|
107
|
+
<article className="mx-auto max-w-prose px-4 sm:px-6 py-12">
|
|
108
|
+
{/* max-w-prose = 65ch */}
|
|
109
|
+
</article>
|
|
110
|
+
</main>
|
|
111
|
+
</div>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Ritmo vertical em prose
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
<article className="prose">
|
|
118
|
+
<h1 className="mb-8">…</h1> {/* h1 + spacing maior abaixo */}
|
|
119
|
+
<h2 className="mt-12 mb-4">…</h2> {/* h2 separa seções */}
|
|
120
|
+
<p className="mb-4 leading-7">…</p>{/* p body */}
|
|
121
|
+
<ul className="my-4 space-y-2">…</ul>
|
|
122
|
+
</article>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Regra: spacing acima de heading > spacing abaixo. Senão heading "flutua" no meio.
|
|
126
|
+
|
|
127
|
+
### Alinhamento óptico
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
// Texto + ícone: align pelo center vertical, não baseline
|
|
131
|
+
<button className="inline-flex items-center gap-2">
|
|
132
|
+
<ArrowRight className="size-4 -translate-y-px" /> {/* -1px opcional para cap-height match */}
|
|
133
|
+
<span>Próximo</span>
|
|
134
|
+
</button>
|
|
135
|
+
|
|
136
|
+
// Heading + ícone decorativo: ícone alinha pelo x-height, não top
|
|
137
|
+
<h2 className="flex items-baseline gap-2">
|
|
138
|
+
<Sparkles className="size-5 translate-y-1" /> {/* push down to baseline-ish */}
|
|
139
|
+
<span>Feature</span>
|
|
140
|
+
</h2>
|
|
141
|
+
|
|
142
|
+
// Pill button: padding horizontal mais leve que vertical estaria — compense
|
|
143
|
+
<button className="rounded-full px-4 py-2"> {/* px-4 não px-3 — pill rouba H */}
|
|
144
|
+
Ação
|
|
145
|
+
</button>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Anti-patterns
|
|
149
|
+
|
|
150
|
+
### Anti-pattern 1: arbitrary values salpicados
|
|
151
|
+
|
|
152
|
+
**Errado:**
|
|
153
|
+
```tsx
|
|
154
|
+
<div className="p-[13px] mt-[27px] gap-[18px]">…</div>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Por quê:** REGRA #1 — escala se desfaz. Outro dev vê `13px` e adiciona `15px` ao lado. Em 6 meses ninguém sabe o que é "spacing default".
|
|
158
|
+
|
|
159
|
+
**Certo:** `p-3 mt-6 gap-4` (12/24/16, todos na escala). Se realmente precisa de um valor fora, adicione ao theme em vez de inline.
|
|
160
|
+
|
|
161
|
+
### Anti-pattern 2: padding cramped em interactive
|
|
162
|
+
|
|
163
|
+
**Errado:** `<button className="px-2 py-1">Salvar</button>`
|
|
164
|
+
|
|
165
|
+
**Por quê:** Q06 — touch hit area pequena + densidade desconfortável. Botão difícil de clicar.
|
|
166
|
+
|
|
167
|
+
**Certo:** `px-4 py-2` mínimo. Botão denso `px-3 py-1.5` apenas em toolbar.
|
|
168
|
+
|
|
169
|
+
### Anti-pattern 3: section sem padding lateral em mobile
|
|
170
|
+
|
|
171
|
+
**Errado:**
|
|
172
|
+
```tsx
|
|
173
|
+
<section className="max-w-7xl mx-auto py-16">
|
|
174
|
+
<h1 className="text-4xl">Title</h1> {/* encosta na borda em mobile */}
|
|
175
|
+
</section>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Por quê:** REGRA #3 — texto sem ar para respirar + acessibilidade em landscape narrow.
|
|
179
|
+
|
|
180
|
+
**Certo:**
|
|
181
|
+
```tsx
|
|
182
|
+
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Anti-pattern 4: hero text sem max-width
|
|
186
|
+
|
|
187
|
+
**Errado:**
|
|
188
|
+
```tsx
|
|
189
|
+
<h1 className="text-6xl">Build amazing products with our platform today</h1>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Por quê:** REGRA #4 — line-length destruído em widescreen, leitura interrompida.
|
|
193
|
+
|
|
194
|
+
**Certo:**
|
|
195
|
+
```tsx
|
|
196
|
+
<h1 className="text-6xl max-w-[18ch] text-balance leading-tight">
|
|
197
|
+
Build amazing products
|
|
198
|
+
</h1>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Anti-pattern 5: misturar densidades sem motivo
|
|
202
|
+
|
|
203
|
+
**Errado:**
|
|
204
|
+
```tsx
|
|
205
|
+
<Card className="p-2"> {/* densa */}
|
|
206
|
+
<CardHeader className="p-8"> {/* generosa */}
|
|
207
|
+
<CardTitle>...</CardTitle>
|
|
208
|
+
</CardHeader>
|
|
209
|
+
<CardContent className="p-4"> {/* padrão */}
|
|
210
|
+
...
|
|
211
|
+
</CardContent>
|
|
212
|
+
</Card>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Por quê:** REGRA #2 — ritmo quebrado, agente IA depois não sabe qual densidade replicar.
|
|
216
|
+
|
|
217
|
+
**Certo:** uma densidade por componente. Card denso = todo o card `p-4` máximo. Card padrão = todo o card `p-6`.
|
|
218
|
+
|
|
219
|
+
### Anti-pattern 6: alinhar centro com texto
|
|
220
|
+
|
|
221
|
+
**Errado:**
|
|
222
|
+
```tsx
|
|
223
|
+
<div className="flex items-center">
|
|
224
|
+
<Icon />
|
|
225
|
+
<h2>Heading</h2>
|
|
226
|
+
</div>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Pixel-perfect: ícone tem `cap-height` diferente do texto.
|
|
230
|
+
|
|
231
|
+
**Certo:**
|
|
232
|
+
```tsx
|
|
233
|
+
<div className="flex items-baseline gap-2"> {/* ou items-center + ícone -translate-y-px */}
|
|
234
|
+
<Icon className="translate-y-0.5" />
|
|
235
|
+
<h2>Heading</h2>
|
|
236
|
+
</div>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Detecção
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
# Arbitrary spacing values
|
|
243
|
+
grep -rnE "(p|m|gap|space)-(x|y)?-\[[0-9]+(px|rem)\]" src --include="*.tsx" 2>/dev/null
|
|
244
|
+
|
|
245
|
+
# Edge flush
|
|
246
|
+
grep -rnE "max-w-7xl.*mx-auto.*py-" src --include="*.tsx" 2>/dev/null | grep -v "px-"
|
|
247
|
+
|
|
248
|
+
# Botão cramped
|
|
249
|
+
grep -rnE "<(button|Button)[^>]*\bp[xy]?-(1|2)\b" src --include="*.tsx" 2>/dev/null
|
|
250
|
+
|
|
251
|
+
# Hero sem max-w em ch
|
|
252
|
+
grep -rnE "text-(5xl|6xl|7xl|8xl|9xl)" src --include="*.tsx" 2>/dev/null | grep -v "max-w-\["
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Ver também
|
|
256
|
+
|
|
257
|
+
- [ui-anti-padroes-ia](../ui-anti-padroes-ia/SKILL.md) — Q02 (edge flush), Q06 (padding cramped)
|
|
258
|
+
- [ui-tipografia](../ui-tipografia/SKILL.md) — line-length em ch
|
|
259
|
+
- [ui-contexto-produto](../ui-contexto-produto/SKILL.md) — escala vai em DESIGN.json
|