Redesign an existing website to make it better. Built on top of impeccable.
71
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Canon is the load-bearing visual record extracted from approved prototypes. It captures the chrome HTML, the compound CSS visual language, the pinned token values, the module canonical renderings, and the free-text compositional moves that govern every other template's rendering. Canon is what makes a multi-template site visually coherent — once the home prototype is approved, its load- bearing decisions become the law that the article, listing, program, and form prototypes must respect (or deliberately deviate from with a logged reason).
This reference is consumed by $stardust prototype --prep (which
authors canon on first approval and extends it on subsequent
approvals). Migrate consumes the canon transparently — see
skills/migrate/SKILL.md and
skills/migrate/reference/template-and-module-rendering.md.
--canon-from <slug> to
override.state-machine.md § Stale flagging.From the approved prototype's body, lift verbatim:
<header> element → stardust/canon/header.html<footer> element → stardust/canon/footer.htmlstardust/canon/<region>.htmlThe extracted HTML is structural: element tags, attributes
(including data-canon, data-section, data-module), inline
class names, and any inline styles present in the prototype.
Other templates inject these files into their proposed and migrated output verbatim. The injection happens at render time; the files are never rewritten by consumers.
DESIGN.md owns primitive tokens (colors, spacing, type, radii).
Canon owns the compound CSS — the named visual language that
consumes those tokens to define .btn-primary, .btn-secondary,
.card, .link, form inputs, and any other reusable visual
treatments the approved prototype establishes. (These class names
are the PROTOTYPE's own vocabulary — the EDS delivery convention
is .button.primary/.secondary, applied at conversion time by
deploy, not by canon.)
Lift those rules from the prototype's <style> block into:
stardust/canon/canon.cssThe file is injected into every migrated page's <style> block
alongside :root. This is what guarantees a button looks like a
button on every page without DESIGN.md having to specify button
HTML.
Selection rule. Lift CSS rules that:
.btn-primary rule, not
a global button rule — global resets stay in DESIGN.md
baseline).var(--*) so the rules cascade
correctly with the token contract.LLM judgment determines reusability. A class that appears once
and is unlikely to recur (e.g., .home-hero-asymmetric-grid)
stays in the prototype's inline styles. A class that's clearly
the site's button language is lifted.
DESIGN.md tokens may be ranges or have a default-with-corridor
(e.g., sectionPadding.desktop: "48–64px"). Canon pins them
to the concrete value the approved prototype chose:
"canon": {
"pinned": {
"sectionPadding.desktop": "56px",
"sectionPadding.tablet": "44px",
"sectionPadding.mobile": "32px",
"densityTier": "balanced",
"typeScale": 1.25
}
}DESIGN.md keeps the corridor; canon names the chosen instance.
Migrate consults canon.pinned first, falls back to DESIGN.md
range otherwise.
Token paths to pin: sectionPadding.{desktop,tablet,mobile},
densityTier, typeScale (chosen modular ratio),
lineHeights.{display,body,small}, and any other token DESIGN.md
declared as a range or corridor.
For each module instance found in the approved prototype, lift its HTML structure:
stardust/canon/modules/
<module-id>.htmlThe HTML carries the module's canonical structure — slot
placeholders (data-slot="...") for content-injection, treatment
for visual-only elements, container structure. Migrate forks this
file when rendering a module instance and injects the page's slot
values into the placeholders.
DESIGN.json.extensions.modules[].canonicalRendering becomes a
{ path, sha } reference:
{
"id": "hotline-211",
"slots": [...],
"canonicalRendering": {
"path": "stardust/canon/modules/hotline-211.html",
"sha": "..."
}
}The load-bearing non-token, non-CSS decisions that govern how a page composes itself. They can't be extracted by structure- matching; the LLM authors them by reasoning about which decisions in the approved variant are system-level (affecting all pages) vs. page-specific (only the home).
"canon": {
"compositionalMoves": [
"12-column asymmetric grid with left-edge centennial spine is the layout system",
"Full-bleed photography moments allowed once per page, never twice",
"Section markers use flat-banner monumental treatment, not subtle dividers",
"Hero docks the 211 panel right of headline, above the fold"
]
}Other prototypes consume these as guidance, not strict rules. The LLM reading them during another template's render decides how they apply (or don't) for that page type.
Authoring rule. 3–7 moves per canon. Each move:
Token-pinnable values do not appear here — those go in
pinned. Compositional moves are for decisions that have no
representation in the token system.
stardust/canon/
├── header.html # canonical header chrome
├── footer.html # canonical footer chrome
├── canon.css # compound CSS (button/card/link/form language)
└── modules/
└── <module-id>.html # canonical rendering per brand moduleDESIGN.json.extensions.canon shape:
{
"sourceSlug": "home",
"approvedAt": "2026-04-28T16:40:00Z",
"files": {
"header": { "path": "stardust/canon/header.html", "sha": "..." },
"footer": { "path": "stardust/canon/footer.html", "sha": "..." },
"css": { "path": "stardust/canon/canon.css", "sha": "..." }
},
"pinned": {
"sectionPadding.desktop": "56px",
"...": "..."
},
"compositionalMoves": ["..."],
"history": [
{ "at": "2026-04-28T16:40:00Z", "from": "home", "kind": "first-approval" },
{ "at": "2026-05-02T10:15:00Z", "from": "news/post-housing-summit", "kind": "extension", "added": ["module:byline-lockup"] }
]
}Per-module entries reference their canonical rendering separately
under DESIGN.json.extensions.modules[i].canonicalRendering.
When prototype --prep approves a non-canon-author template
(article, listing, etc.), canon-extraction runs in diff mode:
When a non-canon-author template's chrome differs from canon, or its compound CSS differs, or its pinned tokens differ:
data-deviation="<reason>" on the affected
elements (per data-attributes.md § Canon and deviation
markers).migrationDecisions[] records a canon-deviation
entry with where, what, reason.This default keeps the system additive and judgment-friendly. Conflicts surface; they don't block.
The user can override the default per-conflict during the prep summary:
state-machine.md § Stale flagging. Useful when the home
approval was rough and the article's choice is what the brand
actually wants.Both are explicit user gestures during prep summary. Without an override, conflict is logged as deviation and approval proceeds.
Each canon file carries an HTML/CSS comment provenance block as its first content:
<!-- stardust:canon
writtenBy: stardust:prototype --prep
writtenAt: 2026-04-28T16:40:00Z
sourceSlug: home
sourcePrototype: stardust/prototypes/home-proposed.html
region: header # or footer, css, module:hotline-211
stardustVersion: 0.10.0
-->DESIGN.json's extensions.canon carries the consolidated record
(sourceSlug, approvedAt, file references with paths + shas, pinned
tokens, compositional moves, history). The history array gains an
entry on every canon write or extension so the lineage stays
auditable.
current/pages/<slug>.json and is injected at render time.skills/stardust/reference/state-machine.md — page lifecycle
and stale-flagging cascade for canon updates.skills/stardust/reference/data-attributes.md — data-canon
and data-deviation markers.skills/stardust/reference/artifact-map.md — file structure
and DESIGN.json shape.skills/migrate/reference/template-and-module-rendering.md —
how migrate consumes canon at render time (Path A′)..tessl-plugin
skills
audit
reference
deploy
diff
direct
extract
migrate
prepare-migration
prototype
replica
reskin
rollout
stardust
uplift
reference