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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# Changelog

## v0.5.0 — 2026-07-31

The **inspiration-intake release** — the skill can now *learn from the web on an ongoing basis*
instead of studying a reference once and forgetting it. Seeded from a deep intake of ten premium
design sites (the Jakub Antalik showcase set, aicss, canvasui, beautiful-ui, originkit, agentation,
transitions.dev, landingfolio).

### The ongoing loop — intake → corpus → graduate
- **A living inspiration corpus** (`reference/inspiration.md`, new) — a dated/sourced/tagged ledger
that persists a reference's distilled DNA (not screenshots) so each build compounds on the last.
On-demand, so the always-loaded router is untouched (SKILL.md stays at ~2598/2600 tokens).
- **`/prototype intake <url…>`** (new subcommand) — browse a site in full, distill its DNA, and
append a corpus entry; privacy-guarded (only the given URLs, never the user's own tabs).
- **A graduation ledger** — proven moves (recurring across ≥3 entries) promote from the corpus into
the menus the skill always reads. Discovery now reads *from* and feeds *back into* the corpus.

### What graduated from the first ten
- **AI-native UI is now a first-class genre** (`reference/ai-native-ui.md`, new) — a zero-dep, à-la-carte
vocabulary wired to the existing loading engine: a *named* thinking-state taxonomy (Working /
Searching / Solving / Listening / Composing / Shaping, not one spinner), streaming text, tool-call
states, approval cards, tool chips, task rows, agent composer, plus AI-specific anti-slop (no violet
"AI gradient").
- **Three page archetypes beyond the app-shell** (`build.md`) — *single-artifact showcase*, *live
component catalog*, and *documentation-as-landing* — plus the **playground pattern** (variant
toggles + slider → regenerated copy-paste code) and a few honest "legitimacy tells".
- **Two sharpened registers, reconciled with the anti-slop rules** — a *dev-tool near-black* ground
(`color-palettes.md`) that draws the exact line between the mastered version and the `blue-on-black`
reflex it already bans; and a *dev-tool / AI-native* type register (`type-pairings.md`) that explains
when the reflex faces (Inter/Geist) are *earned* — the real signature being mono-for-labels, not the
sans.
- **Four new micro-interactions** (`microinteractions.md`) — number pop-in / rolling counter,
spinner→check morph, dissolve-on-remove, and card-stack fan-on-hover — each motion-tier- and
reduced-motion-gated.

## v0.4.0 — 2026-07-29

### Motion tiers
Expand Down
5 changes: 3 additions & 2 deletions SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: prototype
description: Build production-feel HTML prototypes for sales demos, stakeholder reviews, and design exploration. Runs a discovery Q&A, scaffolds a zero-dep static site (HTML + Tailwind CDN + CSS variables + theme switcher + layout switcher + URL-state + feedback overlay + always-visible control bar), and runs a design-quality assessment loop. Use when the user says "prototype", "mockup", "demo", "pitch page", "sales demo", "click-through", or describes a UI they want to show someone without building the real thing. Also handles /prototype variant "<vibe>" (fork a variant) and /prototype apply-feedback <file> (apply pinned feedback JSON).
description: Build production-feel HTML prototypes for sales demos and reviews. Runs a discovery Q&A, scaffolds a zero-dep static site (HTML + Tailwind CDN + theme/layout switchers + URL-state + feedback overlay + control bar) and runs a design-quality loop. Use when the user says "prototype", "mockup", "demo", "pitch page", "sales demo", "click-through", or describes a UI they want to show someone without building the real thing. Also handles /prototype variant "<vibe>" (fork a variant) and /prototype apply-feedback <file> (apply pinned feedback JSON).
---

# /prototype
Expand All @@ -24,6 +24,7 @@ small vanilla JS files.
/prototype → full flow: discover → build → assess → ship
/prototype variant "<vibe>" → fork current prototype into variants/<slug>/
/prototype apply-feedback <file> → read feedback JSON, apply each comment, re-assess
/prototype intake <url…> → add sites to the inspiration corpus
```

## The flow at a glance
Expand Down Expand Up @@ -100,7 +101,7 @@ any screen — ask which page and how it should change (feel, layout, content, a
apply it to just that screen, re-verify, and loop until they're happy. A prototype earns its keep
by being iterated, not shipped once.

Subcommands (`variant`, `apply-feedback`) → `reference/subcommands.md`.
Subcommands (`variant`, `apply-feedback`, `intake`) → `reference/subcommands.md`.

## Non-negotiable constraints

Expand Down
97 changes: 97 additions & 0 deletions reference/ai-native-ui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# AI-native UI — components for agent & LLM interfaces

Half the inspiration corpus (`reference/inspiration.md`) is about one emerging genre: interfaces
where an **agent or model is a first-class actor** — it thinks, streams, calls tools, proposes
actions, and asks for approval. If the prototype is an AI product (chat, agent console, copilot,
LLM tool), reach for this vocabulary the way a dashboard reaches for KPI cards. All of it is
zero-dep and rides the scaffold engine you already have (`js/ui.js`: `fakeLatency`, `withLoader`,
`announce`, `data-skeleton-*`; motion tiers on `html[data-motion]`).

**Read this when** `DESIGN.md` register is an AI/agent product. **Register defaults for it:** motion
tier **calm or standard** (these are tools — cinematic motion is friction; the *one* exception is a
brand/landing page *about* an AI product, which goes expressive); icon stance **functional**; the
"signature move" is usually one of the states below done unusually well, not a decorative flourish.

## The inventory (the checklist)

Pulled from aicss.dev + beautiful-ui + orbs. Treat as an à-la-carte menu — build the ones the
product actually shows, skip the rest (respect scope).

| Component | What it is | Zero-dep mechanic |
|---|---|---|
| **Thinking / reasoning** | agent is working, before output | see state taxonomy below; optional collapsible reasoning trace |
| **Streaming text** | tokens arriving live | reveal word-groups on a timer + a blinking caret; run through `fakeLatency('stream')` |
| **Tool-call / action state** | agent runs a tool (search, read file, run cmd, gen image) | a labeled card: pending → running (spinner/shimmer) → result; `withLoader` around the fake work |
| **Approval card** | agent proposes an action, needs a yes | summary + diff/preview + Approve/Reject; optimistic-with-undo on Approve |
| **Tool chips** | compact inline status | small pill: icon + label + state dot (queued/running/done/error) |
| **Task rows / plan** | agent's to-do list, live | rows with a per-item status (○ pending · ◐ running · ✓ done); check them off on a timer |
| **Agent composer** | the input | textarea + model/mode pickers + attach + send; disabled→busy→ready; ⌘↵ to send |
| **Structured output** | tables the model emitted | the scaffold `.table` inside `.proto-table-wrap` (the 390px overflow guard); records / comparison / diff / filter are content patterns, not separate classes |
| **Citations / context cards** | sources behind an answer | inline superscript links + a source card (favicon + title + domain) |
| **Insight / recommendation card** | a suggestion with confidence | claim + a confidence chip + a sparkline or a one-number reason |

## Thinking is not one spinner — it's a named taxonomy

`orbs` names six agent states — **Working · Searching · Solving · Listening · Composing · Shaping** —
each a distinct animation in a labeled pill. That's the lesson: a generic spinner says "loading";
a *named* state ("Searching the web…", "Reading `auth.ts`…", "Composing the reply…") tells the user
what's happening and reads as a real system. Give the current step a **specific label**, not "Loading."

- **Ambient indicator** (zero-dep, no WebGL): a small pulsing dot-ring, a shimmering glyph, or a
3-dot bounce — one per state, tinted with the accent. A CSS dot-sphere or `conic-gradient` spinner
carries the same read as the WebGL orb without the dependency.
- **Reasoning trace** (optional): a collapsible "Thought for 4s ▸" that expands to a muted,
monospace list of steps. Collapsed by default. This is aicss's "Thinking + Reasoning" block.
- **A11y:** the thinking region sets `aria-busy="true"` on itself and posts each state label through
the scaffold's `announce()` (its polite live region); clear `aria-busy` and announce the result when
the answer lands. Note `announce()` only *speaks* — managing `aria-busy` is yours here (the scaffold
toggles it automatically only for `data-skeleton` containers, not a custom thinking region).

## Streaming text — the mechanic

Reveal in **word groups**, not per-character (per-char is slower to read and jankier). A caret
(`▍`) blinks at the tail while streaming, removed when done. Gate it on `data-motion`: **calm**
skips the animation and paints the full text (respect the scanning user); `prefers-reduced-motion`
always paints instantly. Drive the cadence through `fakeLatency('stream')` so the Loading Speed
control in the tweaks bar scales it (Instant paints immediately).

## Tool-call & action states — the pattern

Every tool call is a tiny three-state lifecycle: **pending → running → result|error**. Model it as a
card (or chip) that:
1. mounts in *running* with a labeled shimmer ("Searching the web…"),
2. resolves via `withLoader(fakeWork, …)` so the spinner-delay + min-visible discipline applies
(no flash on fast calls),
3. lands on a **result** (search hits, a file diff with red/green gutter, a generated-image frame)
or a **scoped error + Retry** (the `.state--error` component).

This is the AI-native application of the loading/state engine already in the scaffold — reuse it,
don't reinvent it.

## Approval & the human-in-the-loop

When the agent proposes a mutation (send email, run migration, place order), show an **approval card**:
a plain-language summary + a preview/diff + **Approve / Reject**. On Approve, use
**optimistic-with-undo** (`UI.undoToast`) rather than a blocking confirm — the action appears done
with a 5s Undo, matching the microinteractions doctrine. Destructive proposals name the consequence
in the button ("Approve & send"), never a bare "OK".

## Demo content — make the agent's world real

Never "lorem" an AI demo — the fake content is what sells it. Give the agent a **specific domain**
(beautiful-ui themes its whole demo around a coffee roaster) and write real-sounding intermediate
work: actual file paths in the diff, plausible search results with real-looking domains, a to-do
list with domain tasks ("Scaffold the component registry", "Wire up Stripe checkout"). Generic
"Task 1 / Task 2" content is the tell that this isn't a real product.

## Anti-slop for AI UIs

- **No purple/violet "AI gradient."** The lazy signifier for "this is AI" is a violet→blue glow —
it's the #1 tell (`color-palettes.md`). An AI product earns its look like any other; one accent,
tinted neutrals.
- **One spinner style, named.** Don't scatter three different loaders; pick one thinking indicator
and label its states.
- **Don't fake streaming on static text** that was never generated (a nav label, a heading) — it
reads as a gimmick. Stream only what the model would actually produce.
- **Monospace with intent.** Mono belongs on code, diffs, file paths, token counts — not the whole
UI (see `type-pairings.md`: "mono is not a costume").
35 changes: 35 additions & 0 deletions reference/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,41 @@ One HTML file per screen. Each screen:
- **Tight-leading display type needs clearance.** An oversized heading/wordmark with `line-height` below 1 (`leading-none`, `leading-[0.8]`, etc.) clips its own descenders/ascenders out of the line box — the glyphs are still there, just outside the box the layout thinks it reserved. Pair any such heading with `padding-bottom` (~0.15–0.25em of its font-size) or `margin-bottom` so a period or descender never collides with the next block. Tight leading is fine; tight leading with a flush neighbor and no clearance isn't.
- **Icons & imagery.** *Decide the icon role from the register — `DESIGN.md` names it (discovery.md Step 4) — don't leave density to chance.* **Product** register (dashboards, tools, app shells): icons are **functional** — they carry affordances (nav destinations, row/card actions, status, controls); a product screen with no action or nav icons is usually under-built. **Brand** register (landing, pitch, editorial): icons are **earned, not default** — lead with type and space, use an icon only where it removes ambiguity (a play control on an audio CTA), never decorative above headings; zero icons is a legitimate, deliberate outcome. Where you do use them: inline SVG copied from [reicon.dev](https://reicon.dev) (MIT, 2,700+, multiple weights) at **one** weight — never a big rounded icon above every heading. `brands.reicon.dev` covers real-looking logos. For photos, follow "Real imagery for photo-forward products" below — a glyph tile is a fallback, never the plan.

### Page archetypes — beyond the app-shell

Most prototypes are an app-shell (nav + screens). But three other whole-page shapes recur in the
best work (`reference/inspiration.md`) and fit specific briefs — pick the archetype in discovery, name
it in `DESIGN.md`, don't default to app-shell for everything:

- **Single-artifact showcase** (beam / metal / orbs) — the page *is* one component, shown off. Centered,
quiet OKLCH-tinted near-black, one **hero live demo**, then `Installation → Usage → Playground`.
For a pitch of a single feature, effect, or primitive. Its engine is the **playground pattern**
below. Signature belongs on the artifact, not the chrome; GitHub/X pair + "Made by —" footer.
- **Live component catalog** (aicss / transitions.dev / beautiful-ui / originkit) — a category-labeled
grid (or left-TOC list) of **real running demos**, never screenshots. Each tile: the live thing + a
**name + one-line mechanic** + a copy affordance; band label + count on the right. For a library,
design-system, or "here's everything it does" page. Keep tiles as quiet frames so the content reads.
- **Documentation-as-landing** (agentation) — a technical product typeset as a beautiful *document*:
left TOC, numbered how-to, inline code chips, an **embedded working demo** inside the prose, one
expressive flourish (a script wordmark) on an otherwise-neutral face, "Made by / Colophon" footer.
For a dev tool / API / agent product where the audience is technical and prose is the pitch.

**The playground pattern** (the showcase's engine, reusable anywhere): variant **toggles** (pill
segmented controls) + a **slider** drive a live preview *and* regenerate a copy-paste code/spec block
in real time. It's the control-bar philosophy (`Visible control bar` above) applied to one element —
wire it through `State.set()` so the shown config and the emitted snippet never drift, and put a
copy-as-label-swap button (`UI.copyButton`) on the snippet.

**Legitimacy tells** (cheap, and they read as "a real team shipped this"): an `npm install …` line
with a copy button in the hero; a small **Pro** badge on premium items; a GitHub/X icon pair
top-right; a "Made by — / Colophon" footer; an inline "new stuff, in your inbox" capture. Use a few,
honestly — they're texture, not a checklist to spam.

**AI / agent products → `reference/ai-native-ui.md`.** If the prototype has an agent or model as an
actor (chat, copilot, agent console), that file is the component vocabulary — thinking-state taxonomy,
streaming text, tool-call states, approval cards, task rows — all zero-dep and wired to the loading
engine. Don't invent AI UI from scratch; it has its own genre now.

### Real imagery for photo-forward products

Marketplaces, listings, and profiles can't demo credibly on placeholders — a reviewer
Expand Down
24 changes: 22 additions & 2 deletions reference/color-palettes.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ each deliberately dodges its category-reflex cliché. Preview them live in `desi
- **Dark mode ≠ inverted light**: elevate with *lighter surfaces* (`surface` < `elevated` <
`elevated-2`), not shadow; desaturate the accent; drop body weight a notch.
- **Category-reflex check**: if the palette is guessable from the domain (finance→navy/gold,
health→teal/white, crypto→neon, dev-tool→blue-on-black), rework it.
health→teal/white, crypto→neon, dev-tool→blue-on-black), rework it. (One defined exception: the
*earned* near-black — no glow, no guessable accent — in "dev-tool near-black" below.)
- **AI-editorial reflex check — passing the category-reflex check above is NOT enough.** A warm
cream/paper or warm-carbon ground + a display serif + one lone amber/terracotta/oxblood accent is
its own cross-domain "a machine made this" tell, independent of domain — a podcast site that
Expand Down Expand Up @@ -93,6 +94,22 @@ surface, not a second hue. No card chrome, oversized whitespace, one near-invisi
- **Light:** `#f8f6f1 · #fcfaf6 · #fefdfa · #26231f · #5c5750 · #8c867d · #e2ded6 · #f0ece4 · #3c2e24 · #faf7f2`
- **Dark:** `#161411 · #1f1c18 · #292520 · #ede8e0 · #b0a99f · #847e75 · #342f29 · #26221d · #e9e3d9 · #181512`

### dev-tool near-black — earned monochrome · restrained (cross-tone ground)
Not a tone row — a **ground strategy** the premium dev-tool / AI sites in `reference/inspiration.md`
share (8 of 10 are near-black). It sits one inch from the **`dev-tool→blue-on-black` reflex banned
above**, so the line matters — and the line is *not* "pure `#000` vs tinted." The banned reflex is the
guessable dev-tool cliché: an accent (classically blue or neon) *glowing* on black. The earned version
keeps the near-black but removes **both** the glow **and** the guessable accent — distinctiveness comes
from the mono-label type register and one signature moment, not from color. Use only for a genuine
developer-tool / AI brief; if you're reaching for a glow or a blue to justify it, you're back in the reflex.
- **Dark:** `#0b0b0d · #141417 · #1c1c20 · #ececf0 · #a8a8b0 · #78787f · #2a2a30 · #201f25 · #ececf0 · #0b0b0d`
— the "accent" is a **monochrome inversion** (near-white on near-black), like `quiet` — no hue at all
is the strong default here. If the brief genuinely needs one, add exactly one **desaturated** hue that
is **not blue or green** (both *are* the dev-tool cliché this dodges) — a muted clay/amber like
`#b0805a` reads as chosen — on ≤5% of the surface, never a neon, never a glow, never a gradient.
- **Light counterpart:** don't invert to gray — use any tinted-light row above (e.g. `minimal`); this
register is dark-first, so ship the dark theme as the primary.

Free-text tones: map to the nearest row or shift the hue deliberately; keep the tinting + one-accent discipline.

## Anti-slop — never ship these
Expand All @@ -102,7 +119,10 @@ default** (the #1 tell) · gray text on a colored ground (use a tint of the grou

## Contrast (verified, WCAG)

Body `ink` on `surface` clears 4.5:1 in both themes for all nine. Three honest flags:
Body `ink` on `surface` clears 4.5:1 in both themes for all nine tone rows. Four honest flags:
- **dev-tool near-black** (the cross-tone ground, not counted in the nine): its mono-inversion accent
trivially clears; if you add the optional clay/amber hue, verify it — `#b0805a`(~L0.62) on `#0b0b0d`
clears AA for a small chip/underline, but it's a fill role, not body text.
- **`ink3`** (tertiary — timestamps, placeholders, captions) is AA-*Large* only in light mode.
Never set body copy in it; use `ink2` for anything essential.
- **playful marigold / bold lime** accents are **fill** roles (button background + `accent-ink`
Expand Down
Loading
Loading