finish the mode migration: brand.md/product.md become redirect stubs

Answering the obvious question the family-depth framing dodged: with
modes derived per task, files named for the old two-register taxonomy
had no architectural reason to exist. brand.md's surviving depth (lane
test + inverse test, reflex-reject lanes, color discipline, layout
moves, permissions) folds into new-work.md, where all of it belonged:
it is new-identity Persuade/Experience guidance. product.md's content
moves unchanged to operate.md, its true name. Both old files remain as
one-line redirect stubs because register: brand|product in existing
PRODUCT.md files and older links point there. All cross-references
retargeted (SKILL.md modes intro, context.mjs REGISTER hint, live.md,
typeset.md); 85 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-07-11 17:35:28 -07:00
co-authored by Claude Fable 5
parent af8b814c99
commit 051f856113
113 changed files with 1121 additions and 1485 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ Build to this floor without announcing it. The design detector (the project hook
## Registers
Name the visitor's mode before designing; the page's grammar follows from it, and most ruined pages are one mode wearing another mode's grammar. The brief and the surface decide the mode. PRODUCT.md's `register` field names the family (`brand` covers Persuade and Experience; `product` covers Operate and Read), and `reference/brand.md` / `reference/product.md` carry extended depth for the two families.
Name the visitor's mode before designing; the page's grammar follows from it, and most ruined pages are one mode wearing another mode's grammar. The brief and the surface decide the mode; PRODUCT.md's `register` field survives only as a family hint (`brand` covers Persuade and Experience, `product` covers Operate and Read). Depth beyond the paragraphs below: [reference/new-work.md](reference/new-work.md) when inventing identity, [reference/operate.md](reference/operate.md) for substantial Operate and Read work.
**Persuade** (landing pages, marketing, campaigns; design IS the product). The deliverable is an impression that stops the scroll, earns the click, converts. Spans every genre (tech, luxury, consumer); don't collapse them into one look. Briefs that imply imagery must ship real, verified imagery; a colored rectangle where a photo belongs reads as incomplete. New Persuade surfaces take their typeface procedure and reject list from [reference/new-work.md](reference/new-work.md).
+2 -41
View File
@@ -1,42 +1,3 @@
# Brand family depth (Persuade and Experience surfaces)
# Moved
When design IS the product: brand sites, landing pages, campaign pages, portfolios, long-form content, about pages. The essentials live in SKILL.md (modes, craft floor) and, for new identity work, in [new-work.md](new-work.md); this file is extended depth for substantial brand work. Rules stated in those files are not repeated here.
The register spans every genre. A tech brand, a luxury hotel, a restaurant, a band's album page, an agency portfolio. They share a stance (*communicate, not transact*) and diverge wildly in aesthetic. Don't collapse them into one look.
## The aesthetic-lane test
Before committing to moves, name the lane. A type-foundry specimen page is one lane; minimal-cool tech is another; acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial; a hiking brand with italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
### Reflex-reject aesthetic lanes
Currently saturated aesthetic families that have flooded brand surfaces. If a brief lands in one of these lanes without a register reason that *requires* it (a literal magazine, a literal terminal), it's the second-order training reflex: the trap one tier deeper than a reflex font pick. Look further.
- **Editorial-typographic.** Display serif (often italic) + small mono labels + ruled separators + monochromatic restraint. The fingerprint: three rule-separated columns, an italic serif headline, lowercase track-spaced metadata, no imagery.
(Entries land and leave this list as families saturate and fade.)
The reflex-reject lists apply to **new design choices**. When the existing brand has already committed to a font or a lane as part of its identity, identity-preservation wins.
## Color
- Name a real reference before picking a strategy; unnamed ambition becomes beige.
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- Don't converge across projects. Each brand surface differentiates from the last.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
- Asymmetric compositions are one option. Break the grid intentionally for emphasis.
- Fluid spacing with `clamp()` that breathes on larger viewports.
- For image-led briefs (hotels, restaurants, magazines, photography), full-bleed hero imagery with overlaid menu and centered headline is a canonical move; let the photograph be the design.
## Brand permissions
Brand can afford things product can't. Take them.
- Ambitious first-load motion. Reveals and typographic choreography that earn their place; one orchestrated page-load beats scattered micro-interactions, and some brands skip entrance motion entirely, which is also a voice.
- Single-purpose viewports. One dominant idea per fold, long scroll, deliberate pacing.
- Art direction per section. Different sections can have different visual worlds if the narrative demands it. Consistency of voice beats consistency of treatment.
The Persuade and Experience essentials are in SKILL.md; the depth for inventing new identity (typeface procedure, reject list and lanes, color discipline, layout moves, permissions) lives in [new-work.md](new-work.md). This stub remains because `PRODUCT.md` files with `register: brand` and older links point here.
@@ -109,7 +109,7 @@ node .opencode/skills/impeccable/scripts/live-insert.mjs --id EVENT_ID --count E
- `--position``event.insert.position` (`before` | `after`)
- Anchor flags ← `event.insert.anchor` (same mapping as wrap: id, classes, tag, text)
The scaffold has **no** `data-impeccable-variant="original"`. Variants are net-new HTML+CSS inserted at `insertLine`. Load `brand.md` or `product.md` (freeform only, no action sub-command). Write all variants in one edit, then `--reply done`.
The scaffold has **no** `data-impeccable-variant="original"`. Variants are net-new HTML+CSS inserted at `insertLine`. For Operate/Read surfaces load `operate.md`; Persuade/Experience surfaces use SKILL.md's mode guidance plus `new-work.md` when the variant invents identity (freeform only, no action sub-command). Write all variants in one edit, then `--reply done`.
For Svelte/SvelteKit targets, `live-insert.mjs` returns `previewMode: "svelte-component"` with `mode: "insert"`, `file` pointing at a temporary `node_modules/.impeccable-live/<id>/manifest.json`, `componentDir` pointing at the variant component files, and `sourceFile` pointing at the real `.svelte` route. Write each inserted variant as a real Svelte component (`v1.svelte`, `v2.svelte`, …) under `componentDir`. Insert variants must be non-empty net-new content with a single top-level root, no `data-impeccable-*` attributes, and CSS in each component's `<style>` block. Do **not** edit the route source during generation; the browser mounts the temporary component before/after the live anchor while the user cycles variants. On Accept, `live-accept.mjs` inserts the selected component markup into `sourceFile` immediately and deletes the temp session after the source write succeeds.
@@ -187,7 +187,7 @@ All three carry `fallback: "agent-driven"`. Follow **Handle fallback** below.
### 3. Load the action's reference
If `event.action` is `impeccable` (the default freeform action), use SKILL.md's shared laws plus the loaded register reference (`brand.md` or `product.md`). Do not load a sub-command reference. **Freeform is not a pass to skip parameters:** you still follow the composition budget and the freeform bias in **§7 Parameters** below. Sub-command files list MUST-have signature knobs; freeform has no such file, so sizing knobs from surface weight and primary axes is entirely on you.
If `event.action` is `impeccable` (the default freeform action), use SKILL.md's shared laws plus the loaded mode depth (`operate.md` for Operate/Read; `new-work.md` when the variant invents identity). Do not load a sub-command reference. **Freeform is not a pass to skip parameters:** you still follow the composition budget and the freeform bias in **§7 Parameters** below. Sub-command files list MUST-have signature knobs; freeform has no such file, so sizing knobs from surface weight and primary axes is entirely on you.
Any other `event.action` (`bolder`, `quieter`, `distill`, `polish`, `typeset`, `colorize`, `layout`, `adapt`, `animate`, `delight`, `overdrive`): Read `reference/<action>.md` before planning. Each sub-command encodes a specific discipline; skipping its reference produces generic output. Those files may require specific params; layer them on top of the §7 budget, not instead of it.
@@ -252,7 +252,7 @@ Instead, work from the brand:
1. Read PRODUCT.md's Brand Personality words. What physical, spatial, or material experiences would embody those words if design were not involved? (A personality described as "specific, earned, unmistakable" evokes a hand-stamped letter, a numbered print, a watchmaker's loupe. A personality described as "restless, loud, unfiltered" evokes a concert poster, a spray-painted wall, a megaphone.)
2. From those physical experiences, derive three visual directions that are genuinely different from each other AND from the current surface you're departing.
3. Avoid the **reflex-reject lanes** in [brand.md](brand.md). Don't trade one monoculture for another. If you find yourself reaching for "Swiss-grid" or "Terminal" or "Industrial-signage" by reflex, you are pattern-matching a catalog in your training data, not reading the brand. Start over from the personality words.
3. Avoid the **reflex-reject lanes** in [new-work.md](new-work.md). Don't trade one monoculture for another. If you find yourself reaching for "Swiss-grid" or "Terminal" or "Industrial-signage" by reflex, you are pattern-matching a catalog in your training data, not reading the brand. Start over from the personality words.
4. Each direction must be expressible in one concrete sentence that names a real-world referent ("a museum exhibition label system for a contemporary art gallery" not "clean and minimal"). If your sentence contains only adjectives, it's not concrete enough.
5. **While planning each direction, also name its 23 parameter knobs** (per the §7 budget table). The same principle as default mode: decide "what's tunable" during planning, not after writing the HTML. A departure-mode hero with 0 parameters is not "bold creative vision," it's a missed opportunity for the user to fine-tune the direction they pick.
@@ -24,6 +24,10 @@ Plan a compact token system in your reasoning: palette, type, layout concept in
Pick a color strategy before picking colors: Restrained (neutrals + one accent; the default when the visitor came to operate or read) / Committed (one saturated color carries 30-60% of the surface) / Full palette (3-4 named roles) / Drenched (the surface IS the color). Persuade and Experience surfaces have permission for the bolder strategies; take them when the brief allows. Dark vs. light is never a default: write one sentence of physical scene (who uses this, where, under what light, in what mood) and let it force the answer. The warm cream near-white body background is the saturated AI default; where the axis is free, pick a background that is a choice.
- Name a real reference before picking a strategy; unnamed ambition becomes beige.
- Palette IS voice: a calm brand and a restless brand should not share palette mechanics, and each new surface differentiates from the last.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Type and imagery for new Persuade and Experience surfaces
Choose faces like objects from the brand's world; these training-data defaults mean you stopped looking: Fraunces, Playfair Display, Cormorant, Lora, Crimson, Newsreader, Syne, Space Grotesk, Space Mono, IBM Plex, Inter-as-display, DM Sans, DM Serif, Outfit, Plus Jakarta Sans, Instrument Sans. (For Operate and Read surfaces the opposite holds: system stacks and workhorse UI faces are legitimate and often correct.)
@@ -34,4 +38,10 @@ Imagery-implying briefs (food, travel, place, product, fashion) must ship real,
AI-generated interfaces cluster around a few looks regardless of subject: warm cream + high-contrast serif + terracotta accent; near-black + one neon accent (acid green, cyan) + glowing edges; broadsheet-editorial hairlines + italic display serif + small tracked mono labels. All are legitimate when the brief calls for them; the brief always wins. Where the brief leaves the aesthetic free, landing in one of them means your self-check failed. Same one tier deeper: if someone could guess your aesthetic from the category alone, or from category-plus-avoidance, rework until neither answer is obvious.
**Name the aesthetic lane, then test it.** Before committing to moves, say which lane this is (a specimen page, minimal-cool tech, acid maximalism...). Then the inverse test: describe what you're about to build the way a competitor would describe theirs; if that sentence fits the modal page in the category, restart. Currently saturated lanes count as reflexes, not choices, when the brief doesn't require them; the flooded one right now is editorial-typographic (display serif, often italic, small mono labels, ruled separators, monochromatic restraint, no imagery).
## Persuade and Experience moves
Layout: asymmetric compositions and intentional grid breaks are on the table; fluid spacing with `clamp()` that breathes on larger viewports; for image-led briefs, full-bleed hero imagery with overlaid navigation is a canonical move, letting the photograph be the design. Permissions the Operate world doesn't get: ambitious first-load motion (one orchestrated page-load beats scattered micro-interactions; skipping entrance motion entirely is also a voice), single-purpose viewports (one dominant idea per fold, deliberate pacing), and art direction per section when the narrative demands it; consistency of voice beats consistency of treatment.
Before finishing, verify against SKILL.md's craft floor and run the detector; a bold page that ships mechanical defects is not done.
@@ -0,0 +1,60 @@
# Operate mode depth (and Read notes)
When design SERVES the product: app UIs, admin dashboards, settings panels, data tables, tools, authenticated surfaces, anything where the user is in a task. The essentials live in SKILL.md (modes, craft floor); this file is extended depth, written for Operate surfaces. Read surfaces (docs, guides, long-form) take SKILL.md's Read mode plus this file's typography and consistency rules; their prose measure and navigation matter more than component density.
## The product slop test
Not "would someone say AI made this." Familiarity is often a feature here. The test is: would a user fluent in the category's best tools (Linear, Figma, Notion, Raycast, Stripe come to mind) sit down and trust this interface, or pause at every subtly-off component?
Product UI's failure mode isn't flatness, it's strangeness without purpose: over-decorated buttons, mismatched form controls, gratuitous motion, display fonts where labels should be, invented affordances for standard tasks. The bar is earned familiarity. The tool should disappear into the task.
## Typography
- **One family is often right.** Product UIs don't need display/body pairing. A well-tuned sans carries headings, buttons, labels, body, data.
- **Fixed rem scale, not fluid.** Clamp-sized headings don't serve product UI. Users view at consistent DPI, and a fluid h1 that shrinks in a sidebar looks worse, not better.
- **Tighter scale ratio.** 1.1251.2 between steps is typical. More type elements here than on brand surfaces; exaggerated contrast creates noise.
- **Line length still applies for prose** (6575ch). Data and compact UI can run denser; tables at 120ch+ are fine.
## Color
Product defaults to Restrained. A single surface can earn Committed (a dashboard where one category color carries a report, an onboarding flow with a drenched welcome screen), but Restrained is the floor.
- State-rich semantic vocabulary: hover, focus, active, disabled, selected, loading, error, warning, success, info. Standardize these.
- Accent color used for primary actions, current selection, and state indicators only, not decoration.
- A second neutral layer for sidebars, toolbars, and panels (slightly cooler or warmer than the content surface).
## Layout
- Responsive behavior is structural (collapse sidebar, responsive table, breakpoint-driven columns), not fluid typography.
## Components
Every interactive component has: default, hover, focus, active, disabled, loading, error. Don't ship with half of these.
- Skeleton states for loading, not spinners in the middle of content.
- Empty states that teach the interface, not "nothing here."
- Consistent affordances across the surface. Same button shape. Same form-control vocabulary. Same icon style.
## Motion
- 150250 ms on most transitions. Users are in flow; don't make them wait for choreography.
- Motion conveys state, not decoration. State change, feedback, loading, reveal: nothing else.
- No orchestrated page-load sequences. Product loads into a task; users don't want to watch it load.
## Product bans (on top of the shared absolute bans)
- Decorative motion that doesn't convey state.
- Inconsistent component vocabulary across screens. If the "save" button looks different in two places, one is wrong.
- Display fonts in UI labels, buttons, data.
- Reinventing standard affordances for flavor (custom scrollbars, weird form controls, non-standard modals).
- Heavy color or full-saturation accents on inactive states.
- Modal as first thought. Modals are usually laziness. Exhaust inline / progressive alternatives first.
## Product permissions
Product can afford things brand surfaces can't.
- System fonts and familiar sans defaults (Inter, SF Pro, system-ui stacks).
- Standard navigation patterns: top bar + side nav, breadcrumbs, tabs, command palettes.
- Density. Tables with many rows, panels with many labels, dense information when users need it.
- Consistency over surprise. The same visual vocabulary screen to screen is a virtue; delight is saved for moments, not pages.
@@ -1,60 +1,3 @@
# Product family depth (Operate and Read surfaces)
# Moved
When design SERVES the product: app UIs, admin dashboards, settings panels, data tables, tools, authenticated surfaces, anything where the user is in a task. The essentials live in SKILL.md (modes, craft floor); this file is extended depth, written for Operate surfaces. Read surfaces (docs, guides, long-form) take SKILL.md's Read mode plus this file's typography and consistency rules; their prose measure and navigation matter more than component density.
## The product slop test
Not "would someone say AI made this." Familiarity is often a feature here. The test is: would a user fluent in the category's best tools (Linear, Figma, Notion, Raycast, Stripe come to mind) sit down and trust this interface, or pause at every subtly-off component?
Product UI's failure mode isn't flatness, it's strangeness without purpose: over-decorated buttons, mismatched form controls, gratuitous motion, display fonts where labels should be, invented affordances for standard tasks. The bar is earned familiarity. The tool should disappear into the task.
## Typography
- **One family is often right.** Product UIs don't need display/body pairing. A well-tuned sans carries headings, buttons, labels, body, data.
- **Fixed rem scale, not fluid.** Clamp-sized headings don't serve product UI. Users view at consistent DPI, and a fluid h1 that shrinks in a sidebar looks worse, not better.
- **Tighter scale ratio.** 1.1251.2 between steps is typical. More type elements here than on brand surfaces; exaggerated contrast creates noise.
- **Line length still applies for prose** (6575ch). Data and compact UI can run denser; tables at 120ch+ are fine.
## Color
Product defaults to Restrained. A single surface can earn Committed (a dashboard where one category color carries a report, an onboarding flow with a drenched welcome screen), but Restrained is the floor.
- State-rich semantic vocabulary: hover, focus, active, disabled, selected, loading, error, warning, success, info. Standardize these.
- Accent color used for primary actions, current selection, and state indicators only, not decoration.
- A second neutral layer for sidebars, toolbars, and panels (slightly cooler or warmer than the content surface).
## Layout
- Responsive behavior is structural (collapse sidebar, responsive table, breakpoint-driven columns), not fluid typography.
## Components
Every interactive component has: default, hover, focus, active, disabled, loading, error. Don't ship with half of these.
- Skeleton states for loading, not spinners in the middle of content.
- Empty states that teach the interface, not "nothing here."
- Consistent affordances across the surface. Same button shape. Same form-control vocabulary. Same icon style.
## Motion
- 150250 ms on most transitions. Users are in flow; don't make them wait for choreography.
- Motion conveys state, not decoration. State change, feedback, loading, reveal: nothing else.
- No orchestrated page-load sequences. Product loads into a task; users don't want to watch it load.
## Product bans (on top of the shared absolute bans)
- Decorative motion that doesn't convey state.
- Inconsistent component vocabulary across screens. If the "save" button looks different in two places, one is wrong.
- Display fonts in UI labels, buttons, data.
- Reinventing standard affordances for flavor (custom scrollbars, weird form controls, non-standard modals).
- Heavy color or full-saturation accents on inactive states.
- Modal as first thought. Modals are usually laziness. Exhaust inline / progressive alternatives first.
## Product permissions
Product can afford things brand surfaces can't.
- System fonts and familiar sans defaults (Inter, SF Pro, system-ui stacks).
- Standard navigation patterns: top bar + side nav, breadcrumbs, tabs, command palettes.
- Density. Tables with many rows, panels with many labels, dense information when users need it.
- Consistency over surprise. The same visual vocabulary screen to screen is a virtue; delight is saved for moments, not pages.
Operate and Read depth lives in [operate.md](operate.md). The mode essentials are in SKILL.md. This stub remains because `PRODUCT.md` files with `register: product` and older links point here.
@@ -185,7 +185,7 @@ Use `ch` units for character-based measure (`max-width: 65ch`). Line-height scal
#### Font Selection & Pairing
The tactical selection procedure and the reflex-reject list live in [reference/brand.md](brand.md) under **Font selection procedure** and **Reflex-reject list** (loaded for brand-register tasks). The rest of this section covers the adjacent knowledge: anti-reflex corrections, system font use, and pairing rules.
The tactical selection procedure and the reflex-reject list live in [new-work.md](new-work.md) (loaded for new identity work). The rest of this section covers the adjacent knowledge: anti-reflex corrections, system font use, and pairing rules.
##### Anti-reflexes worth defending against
@@ -940,7 +940,7 @@ async function cli() {
);
}
if (register) {
parts.push(`REGISTER: \`${register}\` (family hint: brand = Persuade/Experience surfaces, product = Operate/Read). Derive the visitor's mode per SKILL.md; \`reference/${register}.md\` has extended depth for substantial work.`);
parts.push(`REGISTER: \`${register}\` (family hint: brand = Persuade/Experience surfaces, product = Operate/Read). Derive the visitor's mode per SKILL.md.`);
}
const platform = extractPlatform(ctx.product);
const nativeRefs =