| name | zukai |
| description | Turn a plan, diagram, review, table, or explanation into a polished self-contained HTML page (Kami parchment design) to share in the browser. Use when asked to render, visualize, or "make this presentable/shareable", or proactively for any table with 4+ rows or 3+ columns. Outputs diagrams, slide decks, implementation plans, diff/code reviews, before/after comparisons, project recaps, data tables, and research explainers. Not for plain-text or markdown answers, terminal TUIs, backend-only code, or inline chat replies. |
| license | MIT |
| metadata | {"author":"sanurb","version":"3.3.0"} |
Zukai
Skill Purpose
Compose self-contained HTML pages from <zk-*> Web Components. Good content deserves good paper: warm parchment canvas, ink-blue as the sole accent, serif carrying the hierarchy, ring and whisper shadows only, tight editorial rhythm. The runtime guarantees the floor (design tokens, the locked parchment palette, responsive layout, animation, Mermaid), so it composes documents, not dashboards.
The identity is locked and never the variable. The thing that makes a page memorable instead of interchangeable with the last one of its genre is content and composition: a cold open that states a real stake, one content-derived set-piece that demonstrates the page's core claim, and a rhythm that never repeats. That is the whole job. When in doubt, stay on parchment and put the effort into the set-piece.
Instructions
Three steps. Do them in order.
1. Read and commit
First, load the brand profile if one exists (~/.config/zukai/brand.md, legacy ~/.zukai/brand.md). It is the lowest-resolution context: standing identity, an optional accent brand_color, and voice/habit notes. The current request and this page's content always win over it; apply it silently. Full layering, precedence, and guardrails in brand-profile.md. If absent, proceed on the built-in parchment identity.
Output a one-line Design Read before composing anything. It anchors every later decision and stops the model from default-reaching for the same shape every run.
Template: "Reading this as: <page kind> for <audience>, <vibe> language, on the locked parchment palette<, accent #hex if a brand_color applies>. The one thing the reader remembers: <the single takeaway or set-piece>."
The last clause is the north star. If you cannot name it, you do not yet know what the page is for; figure that out first.
Then answer two questions silently: Who reads this? (developer → density, code, diagrams; PM → prose, big picture; reviewers → hero claim first, detail collapsible). What story does it tell? (lead with the most important insight, build evidence, resolve with next steps; a flat list is not a story). Then pin the page kind against the registry (it maps each genre to its exemplar, signature set-piece, and triggers) when one fits.
There is one palette, and it is never the variable. zukai ships a single locked identity — the Kami parchment language: warm ivory canvas (#f5f4ed), ink-blue (#1B365D) as the sole accent, Charter serif carrying the hierarchy, JetBrains Mono for code. No theme rotation, no dark mode, no second chromatic color. Memorability comes from content and composition (the cold open, the set-piece, the rhythm), never from a different skin. The only sanctioned per-document variation is the accent hue, recolored via <zk-page brand="#custom"> or a brand profile brand_color; the warm parchment surface and warm-neutral law stay in force regardless.
If the brief is genuinely ambiguous, ask exactly one clarifying question. Otherwise declare the Design Read and proceed.
Commit the free axes first. The palette and type are locked, so spend your design effort where you are still free: name the subject vernacular, the set-piece, the rhythm, and the one motion moment, then critique each against "would I produce this for any page of this genre?" and revise the defaults. This pre-commitment is what the later design review scores the page against. Full procedure in design-brief.md.
2. Compose around one set-piece
- Anchor on the matching exemplar — for its craft, not its shape. Read the closest
assets/reference-*.html (reference-slides, reference-diagram, reference-plan, reference-plan-review, reference-diff-review, reference-recap) to absorb what makes it good: its pacing and depth tiers, its restraint, its hero on bare canvas (no card around the <h1>), the seal-clean way it is built — never its topic, and never its silhouette. The exemplar calibrates the quality floor and the techniques; it is not a mold to fill. Derive this page's shape from this content, and remember two pages of one genre must not share a silhouette (§13) — cloning the exemplar's section order is exactly the templating the de-templated set-pieces.md and these references exist to prevent. Only for a genre with no exemplar, start from assets/page-skeleton.html. Leave <zk-page> bare (there is no theme attribute); set brand="#hex" only when a brand profile or the request specifies an accent. Leave the <!-- zukai:styles --> and <!-- zukai:runtime --> sentinels for the seal. Add no CDN tags.
- Cold open, on bare canvas. The first beat states a concrete stake, problem, or failure, not an abstract frame. "A server dies and every cache key reshuffles" beats "An overview of consistent hashing." See anti-patterns.md §14. The hero — eyebrow +
<h1> + lead — renders directly on <zk-page>, capped near the prose measure. Never wrap the hero in a card (<zk-card variant="hero"> is banned, anti-patterns.md §16); a box around the title fights the parchment and reads as a generic template. The card is for the set-piece and genuine data/aside blocks, not the header.
- Build the one set-piece. Exactly one content-derived centerpiece that demonstrates the core claim, ranked by demonstration power (interactive that reveals the concept > explorable > static-but-bespoke). Author it inline in this page — inline SVG/canvas plus an Alpine
x-data scope or a page-local <script>, inside one <zk-card>/<figure> host. A bespoke figure (a hash ring, a B-tree split, a packet walk) is fitted to this content; it is not a kit part. Never promote one to a new <zk-*> runtime element, however reusable it looks — that over-generalizes the specific and breaks the compose-only rule. Apply the deletion test: remove it, and if the page keeps its main explanatory payload, it was decoration — rebuild it from this page's content. Full ladder, catalogue, and gate rules in set-pieces.md.
- Compose the rest with
<zk-*> and standard HTML, keeping the rhythm varied. Component selection, depth tiers, rhythm table, and layout patterns are in composition.md. Name concepts with <zk-term> (dotted underline) and reserve <zk-hl> (wash) for the one takeaway. For <zk-diagram>, follow syntax-rules.md. If the page explains a concept and introduces terms of art, give the reader the apparatus: mark the terms with <zk-term> and add a glossary — a sticky right-hand <aside> rail of <dl> definitions alongside the prose, or an end-of-page glossary at minimum (see the research-explainer row in registry.md and set-pieces.md). Encode the concept's distinctions (ownership, state, series) with the categorical scale (--color-cat-1…8, token-only) inside the set-piece, never in prose.
- Close on a beat, not a whisper. End on a confident statement: one
<zk-hl> takeaway, the decision that matters, or a done milestone. Never fade out on a recessed card.
- Personality is built in. The paper grain, morphing TOC rail, copy-button, and press feedback already ship. Reach for opt-in treatments (
zk-figure[duotone], .zk-focal, .zk-tilt) only when one earns its place. See personality.md. Interactivity is Alpine.js only (no HTMX, no server); see interactivity.md.
3. Seal, review, and deliver
Write one .html to ~/.agent/diagrams/{descriptive-kebab-name}.html, then seal it. The seal is the quality floor (see Output): it makes slop impossible but cannot make a page good.
Then raise the ceiling: run the design review panel. The seal secures the floor; the panel catches what no gate can (a set-piece that decorates instead of demonstrates, a rhythm that is the genre template, a page mistakable for the last one). It dispatches real read-only critic subagents — design-critic, devils-advocate, copy-editor — by subagent_type, each returning a structured review-report. Scale it to stakes: SLIM (Design Critic only) for a throwaway diagram; FULL (all three, dispatched in parallel and blind to each other) for anything shared or shown. A CRITICAL finding blocks delivery until fixed or evidence-refuted (critique-response.md); apply fixes, re-seal, re-review, max two rounds. Only then open it in the browser and tell the user the path.
References (read on demand, never all at once)
| File | Read when |
|---|
| brand-profile.md | Step 1 — a user brand profile exists (~/.config/zukai/brand.md): applying its identity fields, accent brand_color, defaults, and habit notes within the guardrails. |
| design-brief.md | Step 0 — committing the free axes (subject vernacular, set-piece, rhythm, motion) and critiquing the defaults. Emits a design-brief.schema.json object. |
| registry.md | Step 1/2 — pinning the page kind and anchoring on its exemplar (command → exemplar → set-piece → triggers). |
| design-review.md | After sealing — dispatching the read-only critic subagents in agents/ and the three-tier acceptance model. |
| docs/ARCHITECTURE.md | Understanding how the harness fits (floor/ceiling/tiers, agents, hooks, contracts, CI) or docs/design/ for a settled boundary decision. |
| components.md | Selecting a <zk-*> element, an attribute, or a design token. |
| composition.md | Choosing components, depth tiers, rhythm, layout pattern (Step 2). |
| set-pieces.md | Choosing the one bespoke centerpiece — the demonstration ladder, catalogue, gate rules. |
| anti-patterns.md | Before composing, and again before delivering. |
| taste.md | A design decision needs justification, or a default override seems necessary. |
| personality.md | Adding motion, texture, or an interaction treatment. |
| interactivity.md | The page must respond to the reader (sliders, copy, tabs, persist, filters). |
| syntax-rules.md | Authoring a <zk-diagram>. |
| critique-response.md | A critique lands on a zukai page. Measure before changing; never reskin off the locked identity. |
Non-Negotiable Acceptance Criteria
The page delivers nothing unless every item is true. These are defects, not style choices.
The six hard bans (the subset a weak model must honor without reading further; mechanically checkable, enforced by the seal):
- Emphasis is
<zk-term> or <zk-hl>, never <strong>/<em>. Two channels: <zk-term> (dotted brand underline) marks a named concept — a noun phrase a reader could look up and that earns a glossary entry; <zk-hl> (the wash) is reserved for the single takeaway. Never wrap a clause, a sentence, or a rhetorical question in <zk-term> (<zk-term>is this provably right</zk-term> is a clause, not a term — it promises a glossary entry that cannot exist). Bold and italic break Charter's serif rhythm.
- Zero em-dashes and en-dashes (
—, –) in any visible text — headings, body, captions, badges, button text, diagram labels. Use a comma, colon, or period.
- Charter serif only (the theme default). Never Inter, Roboto, Arial, Segoe UI, or
system-ui mid-page. Do not declare a font-family.
- Warm neutrals only. No
#ffffff, no cool grays. Every neutral has a warm undertone (R ≥ G > B).
- Compose with
<zk-*> components. No raw <div> for layout, no Tailwind classes, no hardcoded hex, never invent new <zk-*> elements (a recurring-looking figure is still authored inline, not promoted to a component). One-off styles use var(--token) only. Carve-out: the content-derived set-piece may host raw <div>/SVG/canvas inside an Alpine x-data scope or a page-local <script> (per set-pieces.md).
- Seal before delivering. Run
scripts/inline.mjs; an unsealed page renders blank, and the seal runs the gate fail-closed (see Output).
Judgment criteria (no gate sees these; you own them):
- Design Read declared, north star named, and the page's silhouette differs from the previous output this session (variety lives in composition, not theme — there is one palette).
- Cold open: the first beat states a concrete stake, not an abstract frame (§14).
- One set-piece that demonstrates, earning its place via the deletion test; two pages of the same genre never share a silhouette (set-pieces.md).
- Genre silhouette + closing beat: opens with this kind's signature move; any comparative layout that ranks (grid, table, or list) carries hierarchy, not N equal cells/rows; ends on a beat, not a recessed fade (§13).
- Rhythm holds: no three consecutive sections share a layout family; ≥4 families on an 8-section page (§12). Squint test (sections must not look uniform) and swap test (replace the theme with a generic dark card layout — if indistinguishable, rewrite).
- Single accent, ≤5% surface area. Figures as prose (no
<zk-kpi> mid-sentence, no standalone KPI grid outside <zk-slide type="dashboard">; <zk-sparkline> only when labelled). Eyebrows ≤ ceil(sections / 3) (§9).
- Every Alpine widget that yields a value ships a copy/export affordance that confirms the action: the label swaps to "Copied" for ~1.2s, with an in-voice fallback on failure. A button that writes silently cannot confirm its own outcome and fails this.
- Copy self-audit: every visible string re-read for hallucinated wordplay, broken referents, fake-precise numbers; a blocking risk maps to
variant="error", not warning.
- Completeness: ship N items when asked for N. Pretty-but-incomplete is a failure.
Two or more judgment violations → rewrite before sealing. Re-read anti-patterns.md.
Three tiers decide whether a page ships (the judgment criteria above are the REVIEW tier, no longer self-attested — the panel sees them):
- MANDATORY —
verify.py --gate + render-check.mjs at seal. Mechanical, fail-closed (exit 1). The floor; non-negotiable.
- REVIEW — the design-review panel's CRITICAL / agreed-MAJOR findings. Blocks delivery until fixed or evidence-refuted. The ceiling.
- ADVISORY — isolated MINOR / OBSERVATION. Logged, ships anyway.
Output
Every run produces exactly one artifact: a single sealed, self-contained .html file at ~/.agent/diagrams/{name}.html.
Seal it (mandatory). The seal is the quality gate, executed not attested:
node <skill-dir>/scripts/inline.mjs ~/.agent/diagrams/{name}.html
(npm run seal -- <file> from the repo is equivalent.) The inliner inlines zukai.dist.css, the vendored Alpine bundle, and zukai.js, strips every external reference, then runs two gates and fails closed:
verify.py --gate (deterministic, always): scores the source against the hard bans. Below the floor, or any hard-ban category dirty (em/en dashes, <strong>/<em>, cool grays, Tailwind, external deps, placeholder strings, side-stripe borders, gradient/clipped text, glassmorphism, text glow, justified text, bounce easing, layout-property transitions, nested cards, contrast < 4.5:1) → exit 1.
render-check.mjs (headless, best-effort): loads the sealed file in a real browser and asserts it is not blank, body type resolves to Charter/serif, nothing clips past the viewport at 390/768/1440px, and no uncaught JS fired. Skips silently only where no browser is reachable.
The seal reports a binary floor verdict, not a quality grade: FLOOR: CLEARED means slop is absent, never that the page is good. Any numeric score it prints is a diagnostic, not a ceiling — treat a cleared floor as permission to run the design-review panel, which is the only thing that grades quality (CEILING: unscored until you do). A 100/100-shaped number is not a reason to skip the review.
Exit 1 means not deliverable. Read the violation text (it names the fix), repair the page, re-seal. Never hand-edit to fake a pass. Never hand-add a cdn.jsdelivr.net/.../zukai@main/... tag (the stale-build / supply-chain hazard the seal removes). The page is not done until the seal exits 0.
Residual view-time fetches (acceptable, graceful): the page fetches Charter + JetBrains Mono from Google Fonts (system-serif fallback offline); <zk-diagram> lazy-loads beautiful-mermaid@1 from esm.sh (degrades to source text offline). These are the only network calls and both degrade cleanly.
Command index
| Command | What it does |
|---|
generate-web-diagram | Diagram for any topic |
generate-visual-plan | Implementation plan with state machines and code |
generate-slides | Magazine-quality slide deck |
diff-review | Before/after architecture comparison with code review |
plan-review | Plan vs codebase with risk assessment |
project-recap | Mental model snapshot for context-switching |
fact-check | Verify a document against actual code |
share-page | Deploy an HTML page to Vercel |
Errors: Mermaid syntax → simplify, see syntax-rules.md. Overflow (>15 sections) → split or <zk-collapsible>. Missing component → compose from <zk-card> + tokens; never invent <zk-*> or reach for Tailwind. Need visual variety → it comes from composition and the set-piece, never a different theme.