@ryuenn3123/agentic-senior-core 6.15.1 → 6.16.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/.agents/plugins/agentic-senior-core/.codex-plugin/plugin.json +1 -1
- package/.agents/plugins/agentic-senior-core/commands/asc-reference.md +1 -1
- package/.agents/plugins/agentic-senior-core/commands/asc-reference.toml +2 -3
- package/.agents/plugins/agentic-senior-core/commands/asc-test.md +2 -0
- package/.agents/plugins/agentic-senior-core/commands/asc-test.toml +3 -0
- package/.agents/plugins/agentic-senior-core/hooks/lib/known-ui-slop-patterns.json +81 -1
- package/.agents/plugins/agentic-senior-core/plugin.json +1 -1
- package/.agents/plugins/agentic-senior-core/rules/agentic-senior-core.md +3 -2
- package/.agents/plugins/agentic-senior-core/skills/asc/SKILL.md +15 -6
- package/.agents/plugins/agentic-senior-core/skills/asc/references/writing-skills.md +72 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-develop/SKILL.md +3 -4
- package/.agents/plugins/agentic-senior-core/skills/asc-reference/SKILL.md +55 -67
- package/.agents/plugins/agentic-senior-core/skills/asc-reference/references/api.md +108 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-reference/references/database.md +97 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-reference/references/infrastructure.md +102 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-reference/references/resilience.md +87 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-review/SKILL.md +20 -7
- package/.agents/plugins/agentic-senior-core/skills/asc-test/SKILL.md +104 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/e2e-playwright.md +89 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/flaky-tests.md +96 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/regression-proof.md +58 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/tdd-cycle.md +62 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/test-design.md +75 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/uat.md +62 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/SKILL.md +61 -174
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/accessibility.md +102 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/copy-i18n.md +103 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/craft/browser-surfaces.md +69 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/craft/color-surfaces.md +46 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/craft/motion.md +55 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/craft/typography.md +49 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/divergence.md +127 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/mobile-responsive.md +115 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/experience.md +27 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/operate.md +53 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/persuade.md +72 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/read.md +43 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/redesign-audit.md +71 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/reflexes.md +59 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/states-feedback.md +148 -0
- package/README.md +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugin.yaml +3 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Test-Driven Development (TDD) Cycle
|
|
2
|
+
|
|
3
|
+
TDD is an architectural discipline for writing deterministic, verifiable software. The Iron Law of TDD governs all development:
|
|
4
|
+
|
|
5
|
+
> **THE IRON LAW:** No production code shall be written without a failing test first.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. The Three Phases of TDD
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌────────────────────────────────────────────────────────┐
|
|
13
|
+
▼ │
|
|
14
|
+
┌───────────┐ ┌───────────┐ ┌────────────┐ │
|
|
15
|
+
│ 1. RED │ ───────► │ 2. GREEN │ ───────► │ 3. REFACTOR│ ─┘
|
|
16
|
+
└───────────┘ └───────────┘ └────────────┘
|
|
17
|
+
Write failing test Write minimum Clean up design
|
|
18
|
+
Verify failure mode code to pass Keep suite green
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Phase 1: RED (Observe the Failure)
|
|
22
|
+
1. Write a focused, minimal test specifying the single desired behavior.
|
|
23
|
+
2. Run the test command fresh.
|
|
24
|
+
3. **Inspect the failure reason:** The test must fail because the feature does not exist or the assertion fails.
|
|
25
|
+
- *Failure check:* If the test fails due to a syntax error, unhandled import crash, or missing fixture before the assertion runs, fix the test setup first.
|
|
26
|
+
- *Pass check:* If the test passes immediately without new code, either the behavior already exists, or the test assertion is meaningless.
|
|
27
|
+
|
|
28
|
+
### Phase 2: GREEN (Minimum Code to Pass)
|
|
29
|
+
1. Write the minimum production code required to satisfy the assertion.
|
|
30
|
+
2. Do not implement future requirements, speculative edge cases, or premature abstractions.
|
|
31
|
+
3. Run the test command fresh and confirm it passes with exit code 0.
|
|
32
|
+
|
|
33
|
+
### Phase 3: REFACTOR (Improve Structure)
|
|
34
|
+
1. Remove duplication, extract helpers, or simplify naming.
|
|
35
|
+
2. Maintain identical external behavior.
|
|
36
|
+
3. Rerun the test suite after every structural change.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. Whole-Suite Verification Gate
|
|
41
|
+
|
|
42
|
+
Passing an isolated test is insufficient. Local changes frequently break adjacent modules.
|
|
43
|
+
|
|
44
|
+
Before claiming any task or feature complete:
|
|
45
|
+
1. Run the entire test suite (`ascx npm test`, `ascx pytest`, `ascx go test ./...`, or `ascx cargo test`).
|
|
46
|
+
2. Read the exit code directly from the runner.
|
|
47
|
+
3. If any existing test fails, diagnose whether the failure is a genuine regression or a broken outdated contract. Never weaken assertions to force a green run.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 3. Rationalization Prevention Table
|
|
52
|
+
|
|
53
|
+
Developers and AI models frequently invent excuses to skip tests. Every excuse has a known failure mode:
|
|
54
|
+
|
|
55
|
+
| Rationalization | Fallacy | Operational Reality |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| *"The change is too simple to test."* | Small changes cause silent regressions. | One-line fixes produce 30% of production breakages. Write the 3-line test. |
|
|
58
|
+
| *"I'll write tests after the code works."* | Confirmation bias tests. | Tests written after implementation mirror the existing code bugs and test implementation details rather than contracts. |
|
|
59
|
+
| *"It's just UI / frontend wiring."* | Visual wiring has state logic. | Form validation, button states, and error handling are pure logic and fully testable. |
|
|
60
|
+
| *"Mocking this dependency is too hard."* | Architecture smells. | Difficulty in testing indicates tight coupling. Extract the business logic into a pure function and test that. |
|
|
61
|
+
| *"I verified it manually in the console."* | Ephemeral validation. | Manual checks disappear the moment you close the session. Automated tests protect future refactors permanently. |
|
|
62
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Test Design & Architecture
|
|
2
|
+
|
|
3
|
+
Tests are executable specifications. Poorly designed tests produce false confidence, brittle maintenance overhead, and resistance to refactoring.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Test Behavior, Not Implementation
|
|
8
|
+
|
|
9
|
+
Tests must verify external contracts and observable behavior, never internal implementation mechanics.
|
|
10
|
+
|
|
11
|
+
### 1.1 The Black-Box Principle
|
|
12
|
+
- **Test against public boundaries:** Input arguments, returned values, emitted events, persisted database state, or HTTP responses.
|
|
13
|
+
- **Never assert on internal plumbing:** Do not inspect private class variables, call counts on internal private methods, or local temporary variables.
|
|
14
|
+
- **The Refactoring Test:** If you rewrite an internal algorithm without changing inputs or outputs, your tests should remain completely green. If internal refactoring breaks tests, the tests are coupled to implementation details.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. Mocking Discipline & External Boundaries
|
|
19
|
+
|
|
20
|
+
Mocking is a technique for isolating external unmanaged systems, not an excuse to avoid running real code.
|
|
21
|
+
|
|
22
|
+
### 2.1 The Iron Rule of Mocking
|
|
23
|
+
> **Never mock the unit under test.**
|
|
24
|
+
> Mock *only* external boundaries: third-party HTTP services, payment gateways, message brokers, system clock, or operating system hardware calls.
|
|
25
|
+
|
|
26
|
+
### 2.2 Mocking Hierarchy
|
|
27
|
+
Prefer real code or robust test doubles over fragile call-count mocks:
|
|
28
|
+
|
|
29
|
+
1. **Real Implementation (Preferred):** Use the actual domain code, real validation functions, and real in-memory data structures.
|
|
30
|
+
2. **In-Memory Fakes:** A working in-memory repository or fake mailer that stores sent emails in an array. Fakes preserve semantic behavior without network overhead.
|
|
31
|
+
3. **Boundary Stubs:** Fixed responses for external third-party HTTP endpoints (e.g., Stripe API, GitHub OAuth).
|
|
32
|
+
4. **Spy/Call Mocks (Use with caution):** Asserting `expect(spy).toHaveBeenCalledWith(...)` couples tests to internal call order. Use only when the side-effect *is* the contract (e.g., verifying an audit log event was dispatched).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. Test Isolation & Hermetic State
|
|
37
|
+
|
|
38
|
+
Every test must run in complete isolation.
|
|
39
|
+
|
|
40
|
+
- **Zero Test Order Dependency:** Tests must succeed when run in isolation, sequentially, or shuffled in random order (`--randomize`).
|
|
41
|
+
- **Teardown Shared Resources:** If a test modifies an environment variable (`process.env.NODE_ENV`), writes to a database, or creates a temporary file on disk, it must restore or delete the resource in an explicit `afterEach` or `finally` block.
|
|
42
|
+
- **No Shared Mutable Fixtures:** Never mutate a shared global object across multiple tests. Use factory functions (`createUser()`) that return fresh independent instances for every test.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 4. Test Structure: The AAA Pattern
|
|
47
|
+
|
|
48
|
+
Structure every test into three distinct, visually separated phases:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
describe('TransferService', () => {
|
|
52
|
+
it('deducts balance from sender and credits receiver on successful transfer', async () => {
|
|
53
|
+
// 1. Arrange: Setup fresh state and dependencies
|
|
54
|
+
const sender = await createTestAccount({ balance: 1000 });
|
|
55
|
+
const receiver = await createTestAccount({ balance: 200 });
|
|
56
|
+
const service = new TransferService();
|
|
57
|
+
|
|
58
|
+
// 2. Act: Execute the single behavior under test
|
|
59
|
+
const result = await service.transfer({
|
|
60
|
+
fromId: sender.id,
|
|
61
|
+
toId: receiver.id,
|
|
62
|
+
amount: 300,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// 3. Assert: Verify the observable outcome
|
|
66
|
+
expect(result.status).toBe('COMPLETED');
|
|
67
|
+
expect(await getBalance(sender.id)).toBe(700);
|
|
68
|
+
expect(await getBalance(receiver.id)).toBe(500);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- **One primary action per test:** Keep the `Act` step to a single method invocation.
|
|
74
|
+
- **Specific assertions:** Avoid vague assertions like `expect(result).toBeDefined()`. Assert concrete values.
|
|
75
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# User Acceptance Testing (UAT) & Requirements Verification
|
|
2
|
+
|
|
3
|
+
User Acceptance Testing verifies that software fulfills real operational requirements from the perspective of the end user, rather than merely passing isolated unit tests.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Requirements to Acceptance Criteria (Given/When/Then)
|
|
8
|
+
|
|
9
|
+
Every user requirement or feature ticket must be broken down into concrete, testable acceptance criteria using Given/When/Then structure:
|
|
10
|
+
|
|
11
|
+
```gherkin
|
|
12
|
+
Scenario: Developer revokes an active API key
|
|
13
|
+
Given an authenticated developer with 2 active API keys
|
|
14
|
+
When the developer clicks "Revoke" on key "prod-analytics-key"
|
|
15
|
+
And confirms the revocation in the confirmation dialog
|
|
16
|
+
Then key "prod-analytics-key" is marked as inactive immediately
|
|
17
|
+
And requests using that key return HTTP 401 Unauthorized
|
|
18
|
+
And the remaining key continues to function normally
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Structured Acceptance Verification Matrix
|
|
24
|
+
|
|
25
|
+
When preparing for release or completing a feature milestone, verify all user journeys against an Acceptance Matrix:
|
|
26
|
+
|
|
27
|
+
| Requirement ID | Scenario / User Journey | Input / Action | Expected Result | Verification Method | Status |
|
|
28
|
+
|---|---|---|---|---|---|
|
|
29
|
+
| UAT-AUTH-01 | Login with valid credentials | Post valid email + password | Redirects to `/dashboard`, session cookie set | E2E Playwright test | PASS |
|
|
30
|
+
| UAT-AUTH-02 | Login with rate-limited account | 6 failed attempts within 60s | HTTP 429, displays lockout banner with timer | Integration test | PASS |
|
|
31
|
+
| UAT-BILL-01 | Upgrade from Free to Pro tier | Submit Stripe checkout session | Workspace tier reflects Pro, features unlock | Webhook integration test | PASS |
|
|
32
|
+
| UAT-DATA-01 | Export audit log with 10k rows | Click "Export CSV" | Streams CSV file within 2s, memory < 50MB | Benchmark test | PASS |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. Ephemeral Verification Artifacts (Zero Project Disk Clutter)
|
|
37
|
+
|
|
38
|
+
Verification records, testing matrices, and UAT notes belong in the agent conversation artifacts directory (`brain/<id>/`), never in the user's project workspace.
|
|
39
|
+
|
|
40
|
+
- **Strict Invariant:** Never write `UAT.md`, `test-checklist.json`, `PRD.md`, or temporary gate files to the user repository root unless explicitly instructed by the user.
|
|
41
|
+
- **Reporting:** Present UAT findings clearly in direct chat messages or structured session artifacts.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 4. The Edge Case Quad
|
|
46
|
+
|
|
47
|
+
Never sign off on acceptance testing by verifying only the primary happy path. Every scenario must be verified against four operational vectors:
|
|
48
|
+
|
|
49
|
+
1. **Happy Path:** Standard, valid user input under normal network conditions.
|
|
50
|
+
2. **Boundary Values:**
|
|
51
|
+
- 0 records (empty list / table).
|
|
52
|
+
- 1 record (single item formatting, no awkward pluralization).
|
|
53
|
+
- Maximum capacity (pagination boundary, payload size limits).
|
|
54
|
+
3. **Invalid & Malicious Input:**
|
|
55
|
+
- Empty strings, whitespace-only fields, oversized payloads.
|
|
56
|
+
- SQL / script injection vectors (`<script>`, `' OR 1=1`).
|
|
57
|
+
- Unicode, emojis, and non-ASCII characters.
|
|
58
|
+
4. **Failure & Degraded Mode:**
|
|
59
|
+
- Database connection timeout.
|
|
60
|
+
- Third-party webhook failure.
|
|
61
|
+
- Client network disconnection mid-mutation.
|
|
62
|
+
|
|
@@ -1,204 +1,91 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: asc-ui
|
|
3
3
|
description: >
|
|
4
|
-
Trigger this skill when
|
|
4
|
+
Trigger this skill when working on: UI components, UX design, layouts, microcopy, typography, design systems, modals, forms, tables, dashboards, empty states, or error UI. Also trigger when the user says: "design this page", "clean up UI", "write UI copy", "fix UI slop", "make it look professional", "too verbose", "improve the design", "broken on mobile", "bikin UI", "rapikan tampilan", "tulisan UI berlebihan", "tampilan di hp rusak", "terlalu kaku", "jangan kayak AI". Also trigger when creating or editing files matching: `*.tsx`, `*.jsx`, `*.vue`, `*.svelte`, `*.html`, `*.blade.php`, `*.css`, or UI component files.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Universal UI/UX Engineering & Anti-Slop
|
|
7
|
+
# Universal UI/UX Engineering & Anti-Slop Router
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Grounded in: Nielsen Norman Group (Microcopy & Scannability), Refactoring UI (Hierarchy & Spacing), Apple HIG & Google Material Design 3 (Action Semantics & Tone), and W3C Internationalization / Localization Best Practices.
|
|
9
|
+
Staff-grade design engineering for resilient, scannable, human-grade interfaces. Enforces the visual floor and routes deep craft guidance on demand.
|
|
12
10
|
|
|
13
11
|
---
|
|
14
12
|
|
|
15
|
-
## 1.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
### Banned Marketing Buzzwords in Functional UI
|
|
36
|
-
Never use hyperbolic adjectives in application interfaces:
|
|
37
|
-
- **Forbidden:** `seamless`, `seamlessly`, `effortless`, `effortlessly`, `empower`, `robust`, `revolutionize`, `dynamic`, `all-in-one`, `supercharge`, `elevate`, `unlock the power of`, `at your fingertips`, `cutting-edge`.
|
|
38
|
-
- Treat an admin dashboard or business tool with utilitarian dignity. Describe the system state neutrally.
|
|
13
|
+
## 1. The Quality Floor (Non-Negotiable Bans)
|
|
14
|
+
|
|
15
|
+
Every UI edit must satisfy these 15 rules without exception:
|
|
16
|
+
|
|
17
|
+
1. **Token discipline:** All colors, spacing, and typography must resolve through declared design tokens or CSS variables. Zero raw hex codes (`#6366f1`) or arbitrary inline pixel values.
|
|
18
|
+
2. **Animation safety:** Never use `transition: all`. Never animate layout dimensions (`width`, `height`, `top`, `left`). Animate only GPU properties (`transform`, `opacity`).
|
|
19
|
+
3. **Reduced motion:** Every CSS animation or transition must respect `@media (prefers-reduced-motion: reduce)`.
|
|
20
|
+
4. **Focus visibility:** Never strip focus indicators (`outline-none`) without an immediate high-contrast `:focus-visible` replacement.
|
|
21
|
+
5. **No hallucinated material:** Never invent metrics, testimonials, customer quotes, or fake partner logos.
|
|
22
|
+
6. **No eyebrows or kicker tags:** Headings carry their own weight. Never place `text-[11px] uppercase tracking-wider` micro-labels above titles.
|
|
23
|
+
7. **No AI cliché gradients:** Never use purple-to-blue/indigo gradients or text clipping (`bg-clip-text text-transparent`).
|
|
24
|
+
8. **No card-in-card nesting:** Never nest rounded bordered cards inside other rounded cards.
|
|
25
|
+
9. **Single elevation declaration:** Choose either a 1px border OR an elevation shadow, never both (ban the ghost card).
|
|
26
|
+
10. **Mobile viewport unit:** Use `min-h-dvh` or `100dvh` for full-height containers, never `100vh` or `h-screen`.
|
|
27
|
+
11. **Mobile containment:** Set `overflow-x: clip` on root shells. Never leak horizontal scrolling.
|
|
28
|
+
12. **Touch targets:** Minimum 44×44px hit target with $\ge$ 8px clearance for all interactive touch controls.
|
|
29
|
+
13. **Contrast floor:** Meet WCAG 2.2 AA (4.5:1 normal text, 3:1 large text and UI component boundaries).
|
|
30
|
+
14. **Single-language purity:** Never mix languages on one surface; ban hybrid neologisms (`di-submit`, `meng-generate`).
|
|
31
|
+
15. **Icon semantics:** Never use raw unicode or emojis as icons. Use dedicated SVG icons; mark decorative icons `aria-hidden="true"`.
|
|
32
|
+
16. **Substance over restraint:** Stripping slop is only half the job. Replace removed ornaments with real substance: strong typographic scale contrast, full-field color anchors, and authentic interface fragments. Never leave an empty, sterile wireframe void.
|
|
39
33
|
|
|
40
34
|
---
|
|
41
35
|
|
|
42
|
-
## 2.
|
|
43
|
-
|
|
44
|
-
AI frequently creates "localization slop" by mixing languages, fabricating awkward hybrid loanwords, or inserting literal dictionary translations that sound unnatural to native speakers.
|
|
45
|
-
|
|
46
|
-
### Strict Single-Language Consistency
|
|
47
|
-
- **Zero Hybrid Code-Switching:** The UI must maintain 100% language purity for its target locale. Never mix English tech slang into non-English interfaces unless it is an established international symbol (e.g., `ID`, `URL`, `API`).
|
|
48
|
-
- *Forbidden (Gado-gado/Jaksel):* *"Submit formulir Anda untuk meng-empower efisiensi dashboard."*
|
|
49
|
-
- *Correct (Indonesian):* *"Kirim formulir untuk memperbarui data ringkasan."*
|
|
50
|
-
- *Correct (English):* *"Submit the form to update dashboard data."*
|
|
51
|
-
|
|
52
|
-
### No Artificial Hybrid Neologisms
|
|
53
|
-
- Never create unidiomatic grammatical Frankenstein words by attaching native affixes to English stems:
|
|
54
|
-
- *Forbidden:* `meng-generate`, `di-submit`, `meng-approve`, `di-cancel`, `men-delete`.
|
|
55
|
-
- *Use established native terms:* `membuat / menghasilkan`, `kirim`, `setujui`, `dibatalkan`, `hapus`.
|
|
36
|
+
## 2. Pre-Flight & Material Inventory
|
|
56
37
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### Dynamic Text Expansion Budget
|
|
64
|
-
- Non-English translations (Indonesian, German, French, Spanish) are typically 20% to 40% longer than English equivalents.
|
|
65
|
-
- Containers, button labels, table headers, and badges must never have rigid fixed pixel widths (`w-[120px]`) that cause text clipping or awkward multi-line wrapping. Use flexible flex/grid layouts with sensible min-widths and text truncation (`truncate` with title tooltips) where appropriate.
|
|
38
|
+
Before declaring markup, inspect the workspace:
|
|
39
|
+
1. **Design Tokens:** Read project CSS variables, Tailwind configuration, or existing components in `components/` or `ui/`. If `DESIGN.md` exists, read it (read-only). Never create or edit persistent checkpoint files.
|
|
40
|
+
2. **Take the Material Inventory:**
|
|
41
|
+
- **Real:** Concrete numbers, existing endpoints, actual data attributes.
|
|
42
|
+
- **Pictures:** Actual screenshots and product visual assets.
|
|
43
|
+
- **Absent:** Missing quotes, missing logos, or unverified metrics—these are omitted entirely.
|
|
66
44
|
|
|
67
45
|
---
|
|
68
46
|
|
|
69
|
-
## 3.
|
|
70
|
-
|
|
71
|
-
AI default interfaces suffer from **Distributional Convergence** (regression to the statistical average of training data). Without disciplined direction, models default to either the *AI Starter Pack* (purple gradients, 3 identical cards, floating drop shadows) or the *Sterile Default* (flat, depressing white wireframes with zero character).
|
|
72
|
-
|
|
73
|
-
Follow these design engineering heuristics to construct purposeful, high-craft digital interfaces:
|
|
74
|
-
|
|
75
|
-
### The Anti-Sterile & Anti-Template Rule
|
|
76
|
-
- **Never Replace Slop with Sterile Voids:** Stripping all decoration does not equal good design. An interface must possess tactile depth, distinct typographic rhythm, and clear surface relationships.
|
|
77
|
-
- **No Second-Order Template Clones:** Never force every screen into a trendy Bento Grid or dark-mode clone. Choose layout geometry derived strictly from the **data shape** and **user task**.
|
|
78
|
-
|
|
79
|
-
### 1. Form Follows Data Shape (Layout Inference)
|
|
80
|
-
Analyze the primary data model and user goal before declaring any container markup:
|
|
81
|
-
- **Quantitative / Comparative Data (Metrics, ledgers, logs, transactions):**
|
|
82
|
-
- *Archetype:* **Dense Data Matrix**.
|
|
83
|
-
- *Pattern:* High-density tables or compact list rows with sticky headers, hairline borders (`border-b border-border/40`), zebra striping or hover highlights, and right-aligned metrics using `tabular-nums font-mono`.
|
|
84
|
-
- *Forbidden:* Packaging individual transaction records into giant cards with fluffy padding.
|
|
85
|
-
- **Relational / Hierarchical Entities (Settings, file explorers, entity management):**
|
|
86
|
-
- *Archetype:* **Master-Detail Two-Pane Canvas**.
|
|
87
|
-
- *Pattern:* Contextual fixed-width left rail (navigation/entity list) paired with a fluid, high-density right canvas for inspection and action.
|
|
88
|
-
- **Procedural / Single-Task Flows (Onboarding, checkouts, complex multi-step forms):**
|
|
89
|
-
- *Archetype:* **Focused Single-Task Stream**.
|
|
90
|
-
- *Pattern:* Centered single-column container (`max-w-xl` / `max-w-2xl`) with progressive disclosure, clear step indicators, and zero peripheral sidebar noise to prevent distraction.
|
|
91
|
-
- **Temporal / Event-Driven Records (Audit logs, status updates, activity history):**
|
|
92
|
-
- *Archetype:* **Linear Timeline Ledger**.
|
|
93
|
-
- *Pattern:* Vertical line rail with timestamp anchors, compact status chips, and contextual user badges.
|
|
94
|
-
- **High-Impact Narrative / Showcase (Landing pages, project overviews):**
|
|
95
|
-
- *Archetype:* **Asymmetric Visual Anchor**.
|
|
96
|
-
- *Pattern:* 7-column editorial narrative anchor (heavy typography + primary action) offset against a 5-column interactive preview or live metric widget.
|
|
97
|
-
|
|
98
|
-
### 2. The Single Focal Anchor Principle (Anti-Cardocalypse)
|
|
99
|
-
- **Eliminate Equal-Weight Monotony:** Never place 3 or 4 cards with identical dimensions, identical icons, and identical visual weight side by side.
|
|
100
|
-
- **Establish One Primary Focal Point:** Every screen or section must possess exactly ONE visual hero that pulls the eye first (e.g., the primary telemetry chart, the key operational metric, or the main action trigger).
|
|
101
|
-
- **Subordinate Supporting Elements:** All surrounding widgets must intentionally recede: use lower contrast text (`text-muted-foreground`), lighter borders, or muted background surfaces (`bg-muted/40`).
|
|
102
|
-
|
|
103
|
-
### 3. Tactile Surface Craft & Stepped Tones (Beyond Drop Shadows)
|
|
104
|
-
Avoid excessive fuzzy drop shadows (`shadow-lg`, `shadow-xl`) that make UI float disconnected from reality. Build physical depth via border-driven architecture and stepped surfaces:
|
|
105
|
-
- **Stepped Surface Tones (3-Tier Depth):**
|
|
106
|
-
- *Base Canvas:* Neutral floor (`bg-slate-50` in light; `bg-zinc-950` / `bg-neutral-950` in dark).
|
|
107
|
-
- *Structural Containers / Cards:* Elevated surface (`bg-white` in light; `bg-zinc-900` / `bg-neutral-900` in dark).
|
|
108
|
-
- *Inset / Subdued Wells:* Recessed areas for search bars, code blocks, or secondary filters (`bg-slate-100/70` in light; `bg-zinc-800/40` in dark).
|
|
109
|
-
- **Hairline Alpha Borders:** Separate structural surfaces with crisp 1px borders using opacity: `border-slate-200/80` (light) or `border-zinc-800` / `border-white/[0.08]` (dark).
|
|
110
|
-
- **Physical Top-Edge Inset:** For dark surfaces, provide a crisp physical sheen using an inset highlight: `shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]` instead of exterior glows.
|
|
111
|
-
|
|
112
|
-
### 4. Color Discipline & The 60-30-10 Rule
|
|
113
|
-
- **Lock the Palette to 3-5 Tokens:** Never scatter disparate colors across cards.
|
|
114
|
-
- **60% Dominant Neutral:** Canvas background and large negative space (tinted neutral like slate, zinc, or warm stone; never stark dead `#000000` or `#FFFFFF`).
|
|
115
|
-
- **30% Structural Neutral:** Card surfaces, borders, navigation bars, and dividers.
|
|
116
|
-
- **10% Purposeful Accent:** Dedicated brand accent color.
|
|
117
|
-
- **Accent Exclusivity:** The accent hue is reserved strictly for interactive triggers (Primary CTA, active tab indicator, unread dot, selected checkbox). **NEVER** use the accent color as card wallpaper, gradient fills, or decorative borders.
|
|
118
|
-
|
|
119
|
-
### 5. Micro-Typography & Scannability
|
|
120
|
-
- **Weight Contrast Before Size Jumps:** Build visual hierarchy by combining font weight (`font-bold` vs `font-normal`) and tracking (`tracking-tight` on large headings; `tracking-normal` on body) before inflating font size to absurd dimensions.
|
|
121
|
-
- **Tabular Numerals Everywhere:** Every metric, balance, percentage, timestamp, and count **MUST** use `tabular-nums` (and preferably `font-mono` where appropriate) to prevent optical horizontal jitter when values update.
|
|
122
|
-
- **Eyebrow Micro-Labels:** Anchor section headers and data clusters with compact category tags: `text-[11px] font-semibold uppercase tracking-wider text-muted-foreground`.
|
|
123
|
-
|
|
124
|
-
### 6. The Banned AI Visual Starter Pack
|
|
125
|
-
Explicitly forbid these generic AI clichés:
|
|
126
|
-
- **No Purple-to-Cyan/Indigo Gradients:** Ban unprompted glowing violet/teal hero washes.
|
|
127
|
-
- **No Gratuitous Glassmorphism:** Never slap `backdrop-blur-md bg-white/10` across functional tables and forms where it ruins text contrast.
|
|
128
|
-
- **No Bouncy/Distracting Hover Scales:** Avoid `hover:scale-105` or springy transforms on utilitarian buttons. Use snappy, mechanical micro-feedback (`transition-colors duration-150` or `active:scale-[0.98]`).
|
|
129
|
-
- **No Meaningless Generic Badges:** Eliminate fake floating pills like "AI Powered" or generic "Beta" chips scattered for decoration.
|
|
47
|
+
## 3. Surface Modes & Ambition Scaling
|
|
130
48
|
|
|
131
|
-
|
|
49
|
+
Determine visual posture from the **surface**, not the product brand:
|
|
132
50
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
### The Data State Quad
|
|
138
|
-
1. **Loading State:** Render proportional skeleton screens matching the actual layout shape (never a single generic spinner in the middle of a blank canvas).
|
|
139
|
-
2. **Empty State:**
|
|
140
|
-
- Maximum 1 direct sentence stating reality + 1 primary action button.
|
|
141
|
-
- *Good:* *"No active projects. [Create Project]"*
|
|
142
|
-
- *Forbidden:* Flowery essays (*"Your workspace is a blank canvas awaiting your creative brilliance..."*).
|
|
143
|
-
3. **Error State:**
|
|
144
|
-
- Factual description of what failed + 1 clear recovery button (`[Retry]`).
|
|
145
|
-
- *Good:* *"Unable to load invoices. [Retry]"*
|
|
146
|
-
- *Forbidden:* Apologetic colloquialisms (*"Oopsie! Something went wrong on our end..."*).
|
|
147
|
-
4. **Populated State:** High-density, cleanly structured data presentation.
|
|
148
|
-
|
|
149
|
-
### Action Mutation Feedback
|
|
150
|
-
- Every mutation button (submit, delete, update) **MUST** immediately reflect a pending state:
|
|
151
|
-
- Disable the button (`disabled`).
|
|
152
|
-
- Show an inline spinner or change text to ongoing action (`Saving...`).
|
|
153
|
-
- Display clear, localized toast or banner confirmation upon completion with actionable retry on failure.
|
|
154
|
-
- Never silently swallow mutation errors. Wrap critical route widgets in localized React/Vue Error Boundaries.
|
|
51
|
+
- **Operate (`references/modes/operate.md`):** Dashboards, settings, data tables, developer tools. Prioritizes dense scannability, master-detail rails, `tabular-nums`, and inline progressive disclosure.
|
|
52
|
+
- **Persuade (`references/modes/persuade.md`):** Landing pages, pricing tiers, conversion flows. 80-word viewport budget, asymmetric postures, single signature element, zero equal-weight 3-card grids.
|
|
53
|
+
- **Read (`references/modes/read.md`):** Documentation, changelogs, knowledge bases. 65–75ch measure (`max-w-prose`), dual-rail navigation, syntax-highlighted code blocks.
|
|
54
|
+
- **Experience (`references/modes/experience.md`):** Showcases, portfolios, interactive galleries. Receding interface chrome, full-bleed visual canvas, tactile exploration.
|
|
155
55
|
|
|
156
56
|
---
|
|
157
57
|
|
|
158
|
-
##
|
|
159
|
-
|
|
160
|
-
Mobile layout is a distinct, intentional reflow — not the desktop layout squeezed into a narrow viewport.
|
|
161
|
-
|
|
162
|
-
### Intentional Reflow Over Shrunken Desktops
|
|
163
|
-
- **Re-stack and Re-order:** When the viewport narrows, multi-column grids must collapse into a clean, single-column stack. Side-by-side card grids must never squeeze horizontally until text wraps into 2-letter lines.
|
|
164
|
-
- **Content-Driven Breakpoints:** Place breakpoints where content begins to stress or break readability, never based on a rigid list of marketing device specs (e.g., iPhone 14 width). Test by dragging viewports smoothly across the full 320px–1024px range.
|
|
165
|
-
- **Mobile Section Padding:** Desktop padding scales (96px, 128px) create absurd vertical wastelands on phones. Reduce section vertical padding to a mobile register (typically 32px–48px / `py-8` to `py-12`).
|
|
58
|
+
## 4. Scope Classification: Refine vs. Redesign
|
|
166
59
|
|
|
167
|
-
|
|
168
|
-
- **
|
|
169
|
-
- **Fluid Typography:** Avoid rigid fixed-pixel headings (`font-size: 48px`). Use fluid typography (`clamp(1.5rem, 4vw + 1rem, 2.75rem)`) or explicit responsive font classes (`text-2xl sm:text-4xl lg:text-5xl`).
|
|
170
|
-
|
|
171
|
-
### Touch Targets & Thumb-Zone Ergonomics
|
|
172
|
-
- **44x44px Minimum Touch Target:** Every interactive element (buttons, icon links, checkbox toggles, chips) must have a touch target of at least 44x44px (`min-h-[44px] min-w-[44px]`). If an icon is small (16px), pad its container (`p-3`).
|
|
173
|
-
- **Touch Clearance:** Maintain at least 8px spacing between adjacent touch targets to eliminate accidental mis-taps.
|
|
174
|
-
- **Reachability:** Place primary mobile actions (submit, filters, navigation) within comfortable thumb reach (bottom sheets, sticky action bars) rather than marooning them at the extreme top corners.
|
|
175
|
-
|
|
176
|
-
### Zero Horizontal Scroll Leaks
|
|
177
|
-
- The entire mobile page must maintain zero horizontal overflow.
|
|
178
|
-
- **Tables & Code Blocks:** Wrap wide tables and code blocks in dedicated horizontal scroll containers (`overflow-x-auto max-w-full`) with visible scroll indications, preventing them from blowing out the body width.
|
|
179
|
-
- **Long Unbroken Strings:** Protect against email addresses, hashes, or URLs overflowing cards using `break-words` or `truncate`.
|
|
60
|
+
- **Refinement:** Preserves layout structure, component APIs, DOM hierarchy, and color tokens. Polishes padding rhythm, contrast, microcopy, and state completeness.
|
|
61
|
+
- **Redesign:** Replaces the visual hierarchy, typographic pairing, and surface mode while strictly preserving data bindings, event handlers, and business logic.
|
|
180
62
|
|
|
181
63
|
---
|
|
182
64
|
|
|
183
|
-
##
|
|
65
|
+
## 5. On-Demand Reference Library
|
|
184
66
|
|
|
185
|
-
|
|
67
|
+
Load these references only when working on that specific domain:
|
|
186
68
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
69
|
+
| Topic | Reference Path |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Waivable defaults & waiver syntax | [references/reflexes.md](references/reflexes.md) |
|
|
72
|
+
| Typography, line-height & tabular numbers | [references/craft/typography.md](references/craft/typography.md) |
|
|
73
|
+
| Color tokens, 60-30-10 & elevation | [references/craft/color-surfaces.md](references/craft/color-surfaces.md) |
|
|
74
|
+
| Micro-interactions & GPU motion | [references/craft/motion.md](references/craft/motion.md) |
|
|
75
|
+
| Native surfaces (selection, caret, scrollbars) | [references/craft/browser-surfaces.md](references/craft/browser-surfaces.md) |
|
|
76
|
+
| 50% reduction, active verbs & i18n | [references/copy-i18n.md](references/copy-i18n.md) |
|
|
77
|
+
| Responsive reflow, dvh & touch targets | [references/mobile-responsive.md](references/mobile-responsive.md) |
|
|
78
|
+
| WCAG 2.2 AA contrast & keyboard operability | [references/accessibility.md](references/accessibility.md) |
|
|
79
|
+
| The Data State Quad & mutation feedback | [references/states-feedback.md](references/states-feedback.md) |
|
|
80
|
+
| Anti-convergence, 3 Waves of Tells & Mirror Test | [references/divergence.md](references/divergence.md) |
|
|
81
|
+
| Structured UI audit matrix | [references/redesign-audit.md](references/redesign-audit.md) |
|
|
192
82
|
|
|
193
|
-
|
|
194
|
-
Human eyes consistently overestimate contrast on subtle grey pairs:
|
|
195
|
-
- `#777777` on pure white (`#FFFFFF`) produces **4.48:1** (FAILS normal text AA; minimum safe pure gray is `#767676` which achieves 4.54:1).
|
|
196
|
-
- `#555555` on pure black (`#000000`) produces **2.82:1** (FAILS all text AA).
|
|
197
|
-
- When placing text over gradient backgrounds or images, add a solid scrim or compute contrast at the lightest/darkest coordinate point, not just the center.
|
|
198
|
-
|
|
199
|
-
### Keyboard Operability & Focus Rings
|
|
200
|
-
- **Zero Stripped Focus Rings:** Never write `outline: none` or `focus:outline-none` without an immediate high-contrast `:focus-visible` replacement (`focus-visible:ring-2 focus-visible:ring-offset-2`). Stripping focus breaks keyboard navigation completely.
|
|
201
|
-
- **No Mouse-Only Patterns:** Never gate critical functionality behind hover (`:hover`) without an equivalent keyboard or touch focus trigger.
|
|
202
|
-
- **Dialog Escape Hatch:** Every modal, drawer, or dropdown must close immediately upon pressing the `Escape` key and restore keyboard focus to the triggering element.
|
|
83
|
+
---
|
|
203
84
|
|
|
85
|
+
## 6. Verification & Handoff Sweep
|
|
204
86
|
|
|
87
|
+
Before completing any UI task, run this mechanical check:
|
|
88
|
+
1. **State Quad:** Loading skeleton, empty state, error with retry, and populated data are all handled.
|
|
89
|
+
2. **Pending Feedback:** Buttons disable and display feedback during ongoing mutations.
|
|
90
|
+
3. **Contrast & Focus:** Verify keyboard tab flow and high-contrast `:focus-visible` styling.
|
|
91
|
+
4. **Lint Check:** Verify changes against `hooks/lib/known-ui-slop-patterns.json`.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Accessibility Engineering & WCAG 2.2 Compliance
|
|
2
|
+
|
|
3
|
+
Accessibility is not an afterthought or an optional overlay. It is the structural floor of web engineering. Every component must be perceivable, operable, understandable, and robust.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Contrast Ratios & The Grey-on-Grey Trap
|
|
8
|
+
|
|
9
|
+
All text and critical visual indicators must meet WCAG 2.2 Level AA mathematical contrast floors.
|
|
10
|
+
|
|
11
|
+
### 1.1 Contrast Floors
|
|
12
|
+
- **Normal Body Text (< 18pt / 24px regular, < 14pt bold):** Minimum `4.5:1` contrast ratio against its background.
|
|
13
|
+
- **Large Text ($\ge$ 18pt / 24px regular, $\ge$ 14pt bold):** Minimum `3:1` contrast ratio.
|
|
14
|
+
- **UI Components & Graphical Boundaries:** Active input borders, toggle switches, and focus indicators require minimum `3:1` against adjacent background colors.
|
|
15
|
+
|
|
16
|
+
### 1.2 The Dark Mode Grey-on-Grey Trap
|
|
17
|
+
A frequent aesthetic failure is using low-contrast grey text for "subtle elegance":
|
|
18
|
+
- **Failing example:** `text-zinc-500` (`#71717a`) on `bg-zinc-900` (`#18181b`) = **3.8:1** (Fails 4.5:1 AA for body copy).
|
|
19
|
+
- **Compliant fix:** `text-zinc-400` (`#a1a1aa`) on `bg-zinc-900` = **6.2:1** (Passes AA).
|
|
20
|
+
- **Light mode equivalent:** `text-zinc-400` (`#a1a1aa`) on `bg-white` = **2.6:1** (Fails). Must use `text-zinc-600` (`#52525b`, 5.7:1) or darker for readable secondary copy.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. Focus Management & Keyboard Operability
|
|
25
|
+
|
|
26
|
+
Every capability available via pointer must be fully operable via keyboard alone.
|
|
27
|
+
|
|
28
|
+
### 2.1 The Focus-Visible Rule
|
|
29
|
+
Never remove browser focus indicators without providing an immediate high-contrast replacement:
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<!-- BANNED: Strips focus visibility entirely -->
|
|
33
|
+
<button class="outline-none">Action</button>
|
|
34
|
+
|
|
35
|
+
<!-- ENFORCED: High-contrast focus ring on keyboard interaction -->
|
|
36
|
+
<button class="focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background">
|
|
37
|
+
Action
|
|
38
|
+
</button>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2.2 Dialog Focus Traps & Escape Key Contract
|
|
42
|
+
Any modal, drawer, or sheet must obey the modal contract:
|
|
43
|
+
1. **Focus Trap:** When opened, focus moves to the first focusable element inside the modal. Keyboard `Tab` cycles strictly inside the dialog.
|
|
44
|
+
2. **Escape Key Dismissal:** Pressing `Escape` must immediately close the dialog.
|
|
45
|
+
3. **Return Focus:** Upon closing, focus must return to the element that triggered the dialog open event.
|
|
46
|
+
4. **ARIA Metadata:** Outer container must declare `role="dialog"`, `aria-modal="true"`, and `aria-labelledby="dialog-title-id"`.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 3. Accessible Form Controls
|
|
51
|
+
|
|
52
|
+
Forms must convey intent, association, and error states programmatically.
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<div class="space-y-1.5">
|
|
56
|
+
<label for="user-email" class="text-sm font-medium text-foreground">
|
|
57
|
+
Work email
|
|
58
|
+
</label>
|
|
59
|
+
<input
|
|
60
|
+
id="user-email"
|
|
61
|
+
name="email"
|
|
62
|
+
type="email"
|
|
63
|
+
aria-invalid="true"
|
|
64
|
+
aria-describedby="email-error-msg"
|
|
65
|
+
class="w-full px-3 py-2 rounded-md border border-destructive bg-background text-foreground focus-visible:ring-2 focus-visible:ring-destructive"
|
|
66
|
+
/>
|
|
67
|
+
<p id="email-error-msg" class="text-xs text-destructive flex items-center gap-1" role="alert">
|
|
68
|
+
<svg class="w-3.5 h-3.5" aria-hidden="true">...</svg>
|
|
69
|
+
<span>Enter a valid corporate email address (e.g. name@company.com).</span>
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- Every `<input>` must be explicitly linked via `for` and `id` to a `<label>`. Do not rely solely on `placeholder`.
|
|
75
|
+
- Errors must use `role="alert"` and link via `aria-describedby`.
|
|
76
|
+
- When invalid, set `aria-invalid="true"`.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 4. Icon & Image Semantics
|
|
81
|
+
|
|
82
|
+
1. **Decorative Icons:**
|
|
83
|
+
All decorative SVG icons alongside visible text must be hidden from screen readers:
|
|
84
|
+
```html
|
|
85
|
+
<button>
|
|
86
|
+
<svg aria-hidden="true" class="w-4 h-4">...</svg>
|
|
87
|
+
<span>Download receipt</span>
|
|
88
|
+
</button>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
2. **Standalone Icon Buttons:**
|
|
92
|
+
Buttons containing only an icon must supply an accessible name via `aria-label`:
|
|
93
|
+
```html
|
|
94
|
+
<button type="button" aria-label="Delete document" class="p-2">
|
|
95
|
+
<svg aria-hidden="true" class="w-4 h-4">...</svg>
|
|
96
|
+
</button>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
3. **Images:**
|
|
100
|
+
- Informative graphics, charts, and photos: descriptive `alt="Graph showing 42% revenue increase in Q3"`.
|
|
101
|
+
- Purely aesthetic background patterns or decorative dividers: empty `alt=""` so screen readers ignore them.
|
|
102
|
+
|