Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
23 changes: 23 additions & 0 deletions .github/workflows/check-library-index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Check design library index

# Keeps the pinned offline index (skills/design-library/library-index.md) in
# sync with the upstream VoltAgent/awesome-design-md library. Runs weekly to
# catch upstream additions/removals, and on any PR that touches the skill.

on:
schedule:
- cron: "0 6 * * 1" # every Monday 06:00 UTC
workflow_dispatch: {}
pull_request:
paths:
- "skills/design-library/**"
- "scripts/check-library-index.sh"
- ".github/workflows/check-library-index.yml"

jobs:
check-index:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate pinned library index against upstream
run: bash scripts/check-library-index.sh
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Designpowers is an open, model-agnostic design workflow that gives you a team of
| **design-critic** | Reviews against brief, plan, principles; loops back with gaps |
| **heuristic-evaluator** | Nielsen's 10 heuristics, cognitive walkthroughs, usability |

**31 skills** that enforce a complete design workflow — from discovery through retrospective.
**36 skills** that enforce a complete design workflow — from discovery through retrospective.

**2 lanes** — Build (design something new through the full pipeline) and Review (audit something you already have — a screenshot, URL, or code — through the reviewers, without the full build process).

Expand Down
48 changes: 48 additions & 0 deletions examples/traced-run/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Traced run — Aurora cookie consent banner

A worked, end-to-end example of a Designpowers pipeline producing a real,
verified artifact. It exists so the orchestration is **demonstrated**, not just
described — for a system whose creed is "evidence over claims," there should be
at least one trace you can read and a build you can open.

## What's here

| File | What it is |
|------|-----------|
| `design-state.md` | The spine of the run — brief, personas, strategy, the full handoff babble chain, parallel reviews, reconciliation, synthetic testing, verification, debt, and the pipeline tally. This is what every agent reads and updates. |
| `artifact/consent-banner.html` | The actual build. Open it in a browser. |
| `artifact/consent-banner.png` | The build rendered with headless Chromium (the screenshot-checkpoint output). |
| `artifact/accessibility-evidence.txt` | WCAG AA contrast **computed** (not eyeballed) for every text/UI pair, plus structural checks. All pass. |

## Why a cookie banner

It's small enough to read in one sitting but deliberately rich in the tensions
the pipeline is meant to resolve: an **ethics/legal** constraint (reject must be
as easy as accept — no dark patterns), an **accessibility** constraint (focus
management, screen-reader announcement, contrast, targets), a **content**
constraint (plain language about what you're agreeing to), and a **usability**
constraint (one-click refusal). The reconciliation step has something real to
reconcile.

## What is and isn't automated here

Honest scope: this trace was produced by driving the workflow's stages and
genuinely creating each stage's output — the artifact is real, it renders, and
its accessibility numbers are **computed by tooling**, not asserted. What it is
*not* is a capture of ten separately-dispatched subagent processes; the agent
voices in the handoff chain are the workflow executed as written, recorded in
the shared state the way a live run records them.

Two follow-through items are noted in `design-state.md` as app-integration
dependencies (sending focus to the dialog on load; wiring the "Choose
individually" settings screen) — they're documented as intent in the markup and
flagged in review, not hidden.

## Regenerating the evidence

```bash
# render (needs playwright chromium)
node scripts/shoot.js examples/traced-run/artifact/consent-banner.html \
examples/traced-run/artifact/consent-banner.png
# contrast + structural checks are in artifact/accessibility-evidence.txt
```
18 changes: 18 additions & 0 deletions examples/traced-run/artifact/accessibility-evidence.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
WCAG 2.2 AA contrast evidence (computed, not eyeballed)
threshold: 4.5 normal text, 3.0 large/UI

Banner title #1b2030 on #ffffff 16.21 PASS
Banner body #41485c on #ffffff 9.11 PASS
Accept btn #ffffff on #2b5cd9 5.78 PASS
Reject btn #1b2030 on #ffffff 16.21 PASS
Link/settings #2b5cd9 on #ffffff 5.78 PASS

Structural (from markup):
Accept and Reject have equal visual weight (no dark pattern): PASS
All controls min-height 44px touch target: PASS
Visible focus ring (:focus-visible 3px): PASS
role=dialog + aria-labelledby + aria-describedby: PASS
prefers-reduced-motion honoured: PASS
lang=en set: PASS

VERDICT: ALL PASS
54 changes: 54 additions & 0 deletions examples/traced-run/artifact/consent-banner.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Aurora — cookie consent</title>
<style>
:root{
--ink:#1b2030; --muted:#41485c; --line:#d9dde6; --bg:#eef0f4;
--surface:#ffffff; --accent:#2b5cd9; --accent-ink:#ffffff;
--ghost-ink:#243; --r:12px;
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:-apple-system,system-ui,"Segoe UI",sans-serif;background:var(--bg);color:var(--ink);min-height:100vh}
.page{padding:40px;max-width:760px;margin:0 auto;color:var(--muted)}
.page h1{color:var(--ink);font-size:24px;margin-bottom:12px}
/* consent banner */
.consent{position:fixed;inset:auto 16px 16px 16px;max-width:560px;margin:0 auto;
background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
box-shadow:0 8px 30px rgba(27,32,48,.14);padding:20px 22px}
.consent h2{font-size:17px;color:var(--ink);margin-bottom:6px}
.consent p{font-size:14px;line-height:1.5;color:var(--muted);margin-bottom:16px}
.consent a{color:var(--accent);text-decoration:underline}
.actions{display:flex;gap:10px;flex-wrap:wrap}
.btn{min-height:44px;padding:11px 18px;border-radius:9px;font-size:15px;font-weight:600;
cursor:pointer;border:1px solid transparent}
.btn:focus-visible{outline:3px solid #9db8f2;outline-offset:2px}
/* equal weight: accept and reject look the same — no dark pattern */
.btn-accept{background:var(--accent);color:var(--accent-ink)}
.btn-reject{background:var(--surface);color:var(--ink);border-color:var(--line)}
.btn-settings{background:transparent;color:var(--accent);min-height:44px;padding:11px 8px;
border:none;text-decoration:underline;cursor:pointer;font-size:15px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
</style>
</head>
<body>
<main class="page">
<h1>Aurora dashboard</h1>
<p>Your background content sits here. The consent banner below does not block it visually, but focus moves to the banner so keyboard and screen-reader users handle it first.</p>
</main>

<!-- role=dialog, labelled, focusable; in a real build focus is sent here on load -->
<section class="consent" role="dialog" aria-modal="false"
aria-labelledby="consent-title" aria-describedby="consent-desc" tabindex="-1">
<h2 id="consent-title">Cookies on Aurora</h2>
<p id="consent-desc">We use essential cookies to run Aurora. With your OK, we’d also use analytics cookies to see what’s slow and fix it. You can change this anytime in <a href="/settings/privacy">Privacy settings</a>.</p>
<div class="actions">
<button class="btn btn-accept" type="button">Accept analytics</button>
<button class="btn btn-reject" type="button">Reject analytics</button>
<button class="btn-settings" type="button">Choose individually</button>
</div>
</section>
</body>
</html>
Binary file added examples/traced-run/artifact/consent-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
124 changes: 124 additions & 0 deletions examples/traced-run/design-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Design State — Aurora Cookie Consent Banner

> Shared living document for this project. Every agent reads it before starting and updates it on completion. This is the spine of the run — the handoff chain, decisions, reviews, and evidence all accumulate here.

**Project:** A cookie-consent banner for the Aurora dashboard.
**Mode:** Direct (handoffs shown; approvals recorded below).
**Started:** 2026-05-30
**Taste layers:** No client `DESIGN.md` supplied → built from a lightweight project taste calibration (below). Personal taste profile: none loaded (first project for this user). Nothing here was promoted to a personal profile.

---

## Brief (from design-discovery)

- **Problem:** Aurora needs lawful, honest cookie consent. Users must be able to refuse analytics as easily as accept — and not be tricked into accepting.
- **Primary task:** Decide on analytics cookies (accept / reject / choose) and get back to the dashboard.
- **Users / ability spectrum:** Dashboard users on desktop and mobile; includes keyboard-only users, screen-reader users, low-vision users (zoom), and users with motion sensitivity. Situational: people in a hurry who just want to dismiss it correctly.
- **Constraints:** GDPR/ePrivacy posture — reject must be as easy as accept; no pre-ticked analytics; essential cookies need no consent. Web, ships in the existing app shell.
- **Quality bar:** Production.
- **Success:** A user can refuse analytics in one click, understand what they’re agreeing to, and do it by keyboard or screen reader without getting stuck.

## Personas (from inclusive-personas) — abridged

| Persona | Key need | Worst-case condition |
|---------|----------|----------------------|
| Priya — keyboard-only (RSI) | Reach and operate every control without a mouse | Focus must move to the banner and never trap |
| Marcus — screen-reader user | Know what the dialog is and what each button does | Banner must be announced; buttons self-describing |
| Lena — low vision, 200% zoom | Read the text and tell the buttons apart | Contrast + layout that survives zoom/reflow |
| Sam — in a hurry | Dismiss correctly in one action | Reject must be one obvious click, not buried |

## Strategy & principles (from design-strategy)

1. **Honest by default** — accept and reject carry equal visual weight. Refusing is never harder than agreeing.
2. **Plain, specific copy** — say what analytics cookies do and why, at a low reading level.
3. **Non-blocking but focus-first** — don’t hijack the whole screen, but move focus to the banner so assistive-tech users deal with it first.

## Project taste calibration (stands in for a DESIGN.md)

- Calm, trustworthy, neutral. Single blue accent (`#2b5cd9`). Warm-neutral ink, soft 12px radius, one soft shadow. No alarming reds, no playful tone — this is a consent surface, it should feel straight.
- Recorded as the **project** taste layer only.

---

## Handoff Chain (babble — shown to the user during the run)

1. **design-strategist → content-writer:**
"Core constraint is legal + ethical symmetry: reject must be as easy as accept, no pre-ticked boxes. I framed it as ‘honest by default.’ Copy needs to name analytics cookies plainly and give a why — keep it low reading level."

2. **content-writer → design-lead:**
"Wrote three button labels with equal commitment: ‘Accept analytics’ / ‘Reject analytics’ / ‘Choose individually’. Body says what analytics does (‘see what’s slow and fix it’) and points to Privacy settings for later changes. Grade ~6. Don’t restyle reject to look weaker — that would undo the symmetry."

3. **design-lead → motion-designer:**
"Single blue accent on Accept; Reject is an equal-size outline button, not a faint link — symmetry holds. ‘Choose individually’ is the genuinely tertiary action as an underlined button. 44px targets, 12px radius, one soft shadow. Banner is a labelled dialog pinned bottom, non-blocking."

4. **motion-designer → design-builder:**
"Keep it quiet — a consent surface shouldn’t bounce. At most a 150ms fade-in, and it’s fully removed under prefers-reduced-motion. No looping or attention-grabbing motion. Don’t animate focus movement."

5. **design-builder → reviewers:**
"Built `artifact/consent-banner.html` using the content-writer’s exact strings. role=dialog + aria-labelledby/describedby, focusable container (focus sent here on load in the real app), 44px targets, :focus-visible ring, reduced-motion handled. Equal-weight Accept/Reject as specified. One thing to check: aria-modal is false (non-blocking) — confirm that’s the right call for screen-reader flow."

## Reviews (parallel: critic ∥ accessibility-reviewer ∥ heuristic-evaluator)

**design-critic — proceed with fixes.** Matches the ‘honest by default’ brief; symmetry intact. Minor: body copy could name the retention/no-3rd-party point, but that’s scope for the privacy page, not the banner. Logged to debt, not fixed now.

**accessibility-reviewer — pass with one finding.** Contrast all AA (see evidence). role/labelling correct, targets ≥44px, focus ring visible, reduced-motion honoured. Finding (Major): `aria-modal="false"` is correct for a non-blocking banner, *but* the build must actually move focus to the dialog on load or screen-reader users may never reach it — flagged to builder to confirm the focus-on-load behaviour in the real app (the static fixture documents the intent via `tabindex="-1"`).

**heuristic-evaluator — 9/10, one H-note.** H2/H4/H6 strong (plain language, consistent, recognition over recall). H3 (user control): good — both choices are one click and reversible via settings. Note: ‘Choose individually’ must lead somewhere real; in the fixture it’s a stub — confirm wiring before ship.

## Reconciliation

- **Aligned:** critic + a11y + heuristic all endorse the equal-weight buttons → keep, do not weaken Reject.
- **Complementary:** a11y focus-on-load finding + heuristic ‘settings must be wired’ note → both go to the fix list.
- **Conflicting:** none.
- **Resolution rules applied:** none needed beyond compiling the fix list (no accessibility-vs-aesthetics conflict arose).

**Fix list (prioritised):**
1. (Major, a11y) Ensure focus moves to the banner dialog on load; verify SR announces it. *Documented in markup intent; behaviour to confirm in app integration.*
2. (Minor, heuristic) Wire ‘Choose individually’ to the real per-category settings.
3. (Note, critic) Consider adding retention/no-3rd-party line on the Privacy page. → **design debt.**

## Synthetic user testing (persona walkthroughs)

| Task: refuse analytics and return | Priya (kbd) | Marcus (SR) | Lena (200%) | Sam (hurry) |
|-----------------------------------|-------------|-------------|-------------|-------------|
| Reach the controls | ✓ (focus order logical) | ✓ (dialog announced via role+label) | ✓ (reflows, no clipping) | ✓ |
| Tell Accept from Reject | ✓ | ✓ (labels self-describe) | ✓ (both buttons, equal weight) | ✓ |
| Refuse in one action | ✓ | ✓ | ✓ | ✓ (Reject is one obvious click) |

No persona is blocked. The one dependency is the focus-on-load behaviour (fix #1) — passing assumes it’s implemented as documented.

## Verification (before shipping) — evidence, not claims

- **Accessibility:** see `artifact/accessibility-evidence.txt` — all text/UI pairings computed at WCAG AA, all PASS; structural checks (targets, focus, roles, reduced-motion) PASS.
- **Build renders:** `artifact/consent-banner.png` (rendered with headless Chromium).
- **Brief met:** reject is one click and equal in weight to accept; copy is plain and names the purpose; banner is a labelled dialog.
- **Open dependencies before real ship:** fix #1 (focus-on-load) and fix #2 (wire settings) — both noted, neither is a fixture defect.

## Design debt register (deferred, tracked — not dropped)

| Item | Severity | Who it affects | Why deferred |
|------|----------|----------------|--------------|
| Add retention / no-third-party line on Privacy page | Note | all users wanting detail | Belongs on the privacy page, out of banner scope |

## Decisions log

- Equal-weight Accept/Reject buttons — *rationale: brief + ethics; endorsed by all three reviewers.*
- Non-blocking dialog (`aria-modal=false`) with focus-on-load — *rationale: don’t hijack the screen, but ensure AT users handle it first.*
- Quiet motion, removed under reduced-motion — *rationale: a consent surface shouldn’t demand attention through movement.*

## Pipeline

| Agent | Status |
|-------|--------|
| design-strategist | ✅ |
| design-scout | ⏭️ skipped (well-understood pattern; legal symmetry is the real constraint, not market research) |
| inspiration-scout | ⏭️ skipped (small surface) |
| content-writer | ✅ |
| design-lead | ✅ |
| motion-designer | ✅ |
| design-builder | ✅ |
| design-critic | ✅ |
| accessibility-reviewer | ✅ |
| heuristic-evaluator | ✅ |

**Agents used: 8 of 10** · **Fix rounds: 1** · **Mode: direct**
1 change: 1 addition & 0 deletions mcp-tools/accessibility/node_modules/.bin/node-which

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading