## Host-neutral runtime bindings These assignments select stable paths only; they do not install anything or grant consent: ```bash GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}" GSTACK_ROOT="$GSTACK_HOME" GSTACK_STATE_ROOT="$GSTACK_HOME" GSTACK_BIN="$GSTACK_HOME/bin" BUN_CMD="$GSTACK_BIN/bun" B="$GSTACK_BIN/browse" D="$GSTACK_BIN/gstack-design" P="$GSTACK_BIN/make-pdf" ``` # $design --mode Implement --module design-html: Pretext-Native HTML Engine You generate production-quality HTML where text actually works correctly. Not CSS approximations. Computed layout via Pretext. Text reflows on resize, heights adjust to content, cards size themselves, chat bubbles shrinkwrap, editorial spreads flow around obstacles. ## DESIGN SETUP (run this check BEFORE any design mockup command) ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) D="" [ -n "$_ROOT" ] && [ -x "$GSTACK_BIN/gstack-design" ] && D="$GSTACK_BIN/gstack-design" [ -z "$D" ] && D="${GSTACK_HOME:-$HOME/.gstack}/bin/gstack-design" if [ -x "$D" ]; then echo "DESIGN_READY: $D" else echo "DESIGN_NOT_AVAILABLE" fi B="" [ -n "$_ROOT" ] && [ -x "$GSTACK_BIN/browse" ] && B="$GSTACK_BIN/browse" [ -z "$B" ] && B="${GSTACK_HOME:-$HOME/.gstack}/bin/browse" if [ -x "$B" ]; then echo "BROWSE_READY: $B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" fi ``` If `DESIGN_NOT_AVAILABLE`: skip visual mockup generation and fall back to the existing HTML wireframe approach (`DESIGN_SKETCH`). Design mockups are a progressive enhancement, not a hard requirement. If `BROWSE_NOT_AVAILABLE`: use `open file://...` instead of `$B goto` to open comparison boards. The user just needs to see the HTML file in any browser. If `DESIGN_READY`: the design binary is available for visual mockup generation. Commands: - `$D generate --brief "..." --output /path.png` — generate a single mockup - `$D variants --brief "..." --count 3 --output-dir /path/` — generate N style variants - `$D compare --images "a.png,b.png,c.png" --output /path/board.html --serve` — comparison board + HTTP server - `$D serve --html /path/board.html` — serve comparison board and collect feedback via HTTP - `$D check --image /path.png --brief "..."` — vision quality gate - `$D iterate --session /path/session.json --feedback "..." --output /path.png` — iterate **CRITICAL PATH RULE:** All design artifacts (mockups, comparison boards, approved.json) MUST be saved to `"${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/designs/`, NEVER to `.context/`, `docs/designs/`, `/tmp/`, or any project-local directory. Design artifacts are USER data, not project files. They persist across branches, conversations, and workspaces. ## UX Principles: How Users Actually Behave These principles govern how real humans interact with interfaces. They are observed behavior, not preferences. Apply them before, during, and after every design decision. ### The Three Laws of Usability 1. **Don't make me think.** Every page should be self-evident. If a user stops to think "What do I click?" or "What does this mean?", the design has failed. Self-evident > self-explanatory > requires explanation. 2. **Clicks don't matter, thinking does.** Three mindless, unambiguous clicks beat one click that requires thought. Each step should feel like an obvious choice (animal, vegetable, or mineral), not a puzzle. 3. **Omit, then omit again.** Get rid of half the words on each page, then get rid of half of what's left. Happy talk (self-congratulatory text) must die. Instructions must die. If they need reading, the design has failed. ### How Users Actually Behave - **Users scan, they don't read.** Design for scanning: visual hierarchy (prominence = importance), clearly defined areas, headings and bullet lists, highlighted key terms. We're designing billboards going by at 60 mph, not product brochures people will study. - **Users satisfice.** They pick the first reasonable option, not the best. Make the right choice the most visible choice. - **Users muddle through.** They don't figure out how things work. They wing it. If they accomplish their goal by accident, they won't seek the "right" way. Once they find something that works, no matter how badly, they stick to it. - **Users don't read instructions.** They dive in. Guidance must be brief, timely, and unavoidable, or it won't be seen. ### Billboard Design for Interfaces - **Use conventions.** Logo top-left, nav top/left, search = magnifying glass. Don't innovate on navigation to be clever. Innovate when you KNOW you have a better idea, otherwise use conventions. Even across languages and cultures, web conventions let people identify the logo, nav, search, and main content. - **Visual hierarchy is everything.** Related things are visually grouped. Nested things are visually contained. More important = more prominent. If everything shouts, nothing is heard. Start with the assumption everything is visual noise, guilty until proven innocent. - **Make clickable things obviously clickable.** No relying on hover states for discoverability, especially on mobile where hover doesn't exist. Shape, location, and formatting (color, underlining) must signal clickability without interaction. - **Eliminate noise.** Three sources: too many things shouting for attention (shouting), things not organized logically (disorganization), and too much stuff (clutter). Fix noise by removal, not addition. - **Clarity trumps consistency.** If making something significantly clearer requires making it slightly inconsistent, choose clarity every time. ### Navigation as Wayfinding Users on the web have no sense of scale, direction, or location. Navigation must always answer: What site is this? What page am I on? What are the major sections? What are my options at this level? Where am I? How can I search? Persistent navigation on every page. Breadcrumbs for deep hierarchies. Current section visually indicated. The "trunk test": cover everything except the navigation. You should still know what site this is, what page you're on, and what the major sections are. If not, the navigation has failed. ### The Goodwill Reservoir Users start with a reservoir of goodwill. Every friction point depletes it. **Deplete faster:** Hiding info users want (pricing, contact, shipping). Punishing users for not doing things your way (formatting requirements on phone numbers). Asking for unnecessary information. Putting sizzle in their way (splash screens, forced tours, interstitials). Unprofessional or sloppy appearance. **Replenish:** Know what users want to do and make it obvious. Tell them what they want to know upfront. Save them steps wherever possible. Make it easy to recover from errors. When in doubt, apologize. ### Mobile: Same Rules, Higher Stakes All the above applies on mobile, just more so. Real estate is scarce, but never sacrifice usability for space savings. Affordances must be VISIBLE: no cursor means no hover-to-discover. Touch targets must be big enough (44px minimum). Flat design can strip away useful visual information that signals interactivity. Prioritize ruthlessly: things needed in a hurry go close at hand, everything else a few taps away with an obvious path to get there. ## SETUP (run this check BEFORE any browse command) ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$GSTACK_BIN/browse" ] && B="$GSTACK_BIN/browse" [ -z "$B" ] && B="${GSTACK_HOME:-$HOME/.gstack}/bin/browse" if [ -x "$B" ]; then echo "READY: $B" else echo "NEEDS_SETUP" fi ``` If `NEEDS_SETUP`: 1. Tell the user: "The optional managed headless browser capability is missing. Do you want to preview its exact dependency-closed component plan and compressed bytes now?" Then STOP and wait. 2. Read `references/RUNTIME.md` and follow its explicit capability bootstrap. Never assume a standard-installed skill directory contains `./setup`. 3. The approved managed runtime includes its own pinned Bun at `$GSTACK_BIN/bun`; never download or install another Bun from a skill workflow. --- ## Step 0: Input Detection ```bash eval "$($GSTACK_BIN/gstack-slug 2>/dev/null)" ``` Detect what design context exists for this project. Run all four checks: ```bash setopt +o nomatch 2>/dev/null || true _CEO=$(ls -t "${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/ceo-plans/*.md 2>/dev/null | head -1) [ -n "$_CEO" ] && echo "CEO_PLAN: $_CEO" || echo "NO_CEO_PLAN" ``` ```bash setopt +o nomatch 2>/dev/null || true _APPROVED=$(ls -t "${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/designs/*/approved.json 2>/dev/null | head -1) [ -n "$_APPROVED" ] && echo "APPROVED: $_APPROVED" || echo "NO_APPROVED" ``` ```bash setopt +o nomatch 2>/dev/null || true _VARIANTS=$(ls -t "${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/designs/*/variant-*.png 2>/dev/null | head -1) [ -n "$_VARIANTS" ] && echo "VARIANTS: $_VARIANTS" || echo "NO_VARIANTS" ``` ```bash setopt +o nomatch 2>/dev/null || true _FINALIZED=$(ls -t "${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/designs/*/finalized.html 2>/dev/null | head -1) [ -n "$_FINALIZED" ] && echo "FINALIZED: $_FINALIZED" || echo "NO_FINALIZED" [ -f DESIGN.md ] && echo "DESIGN_MD: exists" || echo "NO_DESIGN_MD" ``` Now route based on what was found. Check these cases in order: ### Case A: approved.json exists (design-shotgun ran) If `APPROVED` was found, read it. Extract: approved variant PNG path, user feedback, screen name. Also read the CEO plan if one exists (it adds strategic context). Read `DESIGN.md` if it exists in the repo root. These tokens take priority for system-level values (fonts, brand colors, spacing scale). Then check for prior finalized.html. If `FINALIZED` was also found, use AskUserQuestion: > Found a prior finalized HTML from a previous session. Want to evolve it > (apply new changes on top, preserving your custom edits) or start fresh? > A) Evolve — iterate on the existing HTML > B) Start fresh — regenerate from the approved mockup If evolve: read the existing HTML. Apply changes on top during Step 3. If fresh or no finalized.html: proceed to Step 1 with the approved PNG as the visual reference. ### Case B: CEO plan and/or design variants exist, but no approved.json If `CEO_PLAN` or `VARIANTS` was found but no `APPROVED`: Read whichever context exists: - If CEO plan found: read it and summarize the product vision and design requirements. - If variant PNGs found: show them inline using the Read tool. - If DESIGN.md found: read it for design tokens and constraints. Use AskUserQuestion: > Found [CEO plan from $plan --mode Product --module plan-ceo-review | design review variants from $design --mode Critique --module plan-design-review | both] > but no approved design mockup. > A) Run $design --mode Explore --module design-shotgun — explore design variants based on the existing plan context > B) Skip mockups — I'll design the HTML directly from the plan context > C) I have a PNG — let me provide the path If A: tell the user to run $design --mode Explore --module design-shotgun, then come back to $design --mode Implement --module design-html. If B: proceed to Step 1 in "plan-driven mode." There is no approved PNG, the plan is the source of truth. Ask the user for a screen name to use for the output directory (e.g., "landing-page", "dashboard", "pricing"). If C: accept a PNG file path from the user and proceed with that as the reference. ### Case C: Nothing found (clean slate) If none of the above produced any context: Use AskUserQuestion: > No design context found for this project. How do you want to start? > A) Run $plan --mode Product --module plan-ceo-review first — think through the product strategy before designing > B) Run $design --mode Critique --module plan-design-review first — design review with visual mockups > C) Run $design --mode Explore --module design-shotgun — jump straight to visual design exploration > D) Just describe it — tell me what you want and I'll design the HTML live If A, B, or C: tell the user to run that skill, then come back to $design --mode Implement --module design-html. If D: proceed to Step 1 in "freeform mode." Ask the user for a screen name. ### Context summary After routing, output a brief context summary: - **Mode:** approved-mockup | plan-driven | freeform | evolve - **Visual reference:** path to approved PNG, or "none (plan-driven)" or "none (freeform)" - **CEO plan:** path or "none" - **Design tokens:** "DESIGN.md" or "none" - **Screen name:** from approved.json, user-provided, or inferred from CEO plan --- ## Step 1: Design Analysis 1. If `$D` is available (`DESIGN_READY`), extract a structured implementation spec: ```bash $D prompt --image --output json ``` This returns colors, typography, layout structure, and component inventory via GPT-4o vision. 2. If `$D` is not available, read the approved PNG inline using the Read tool. Describe the visual layout, colors, typography, and component structure yourself. 3. If in plan-driven or freeform mode (no approved PNG), design from context: - **Plan-driven:** read the CEO plan and/or design review notes. Extract the described UI requirements, user flows, target audience, visual feel (dark/light, dense/spacious), content structure (hero, features, pricing, etc.), and design constraints. Build an implementation spec from the plan's prose rather than a visual reference. - **Freeform:** use AskUserQuestion to gather what the user wants to build. Ask about: purpose/audience, visual feel (dark/light, playful/serious, dense/spacious), content structure (hero, features, pricing, etc.), and any reference sites they like. In both cases, describe the intended visual layout, colors, typography, and component structure as your implementation spec. Generate realistic content based on the plan or user description (never lorem ipsum). 4. Read `DESIGN.md` tokens. These override any extracted values for system-level properties (brand colors, font family, spacing scale). 5. Output an "Implementation spec" summary: colors (hex), fonts (family + weights), spacing scale, component list, layout type. --- ## Step 2: Smart Pretext API Routing Analyze the approved design and classify it into a Pretext tier. Each tier uses different Pretext APIs for optimal results: | Design type | Pretext APIs | Use case | |-------------|-------------|----------| | Simple layout (landing, marketing) | `prepare()` + `layout()` | Resize-aware heights | | Card/grid (dashboard, listing) | `prepare()` + `layout()` | Self-sizing cards | | Chat/messaging UI | `prepareWithSegments()` + `walkLineRanges()` | Tight-fit bubbles, min-width | | Content-heavy (editorial, blog) | `prepareWithSegments()` + `layoutNextLine()` | Text around obstacles | | Complex editorial | Full engine + `layoutWithLines()` | Manual line rendering | State the chosen tier and why. Reference the specific Pretext APIs that will be used. --- ## Step 2.5: Framework Detection Check if the user's project uses a frontend framework: ```bash [ -f package.json ] && cat package.json | grep -o '"react"\|"svelte"\|"vue"\|"@angular/core"\|"solid-js"\|"preact"' | head -1 || echo "NONE" ``` If a framework is detected, use AskUserQuestion: > Detected [React/Svelte/Vue] in your project. What format should the output be? > A) Vanilla HTML — self-contained preview file (recommended for first pass) > B) [React/Svelte/Vue] component — framework-native with Pretext hooks If the user chooses framework output, ask one follow-up: > A) TypeScript > B) JavaScript For vanilla HTML: proceed to Step 3 with vanilla output. For framework output: proceed to Step 3 with framework-specific patterns. If no framework detected: default to vanilla HTML, no question needed. --- ## Step 3: Generate Pretext-Native HTML ### Pretext Source Embedding For **vanilla HTML output**, check for the vendored Pretext bundle: ```bash _PRETEXT_VENDOR="" _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) : "Pretext is packaged with the selected design skill" [ -z "$_PRETEXT_VENDOR" ] && [ -f assets/design-html/vendor/pretext.js ] && _PRETEXT_VENDOR=assets/design-html/vendor/pretext.js [ -n "$_PRETEXT_VENDOR" ] && echo "VENDOR: $_PRETEXT_VENDOR" || echo "VENDOR_MISSING" ``` - If `VENDOR` found: read the file and inline it in a `` Add a comment: `` For **framework output**, add to the project's dependencies instead: ```bash # Detect package manager [ -f bun.lockb ] && echo "bun add @chenglou/pretext" || \ [ -f pnpm-lock.yaml ] && echo "pnpm add @chenglou/pretext" || \ [ -f yarn.lock ] && echo "yarn add @chenglou/pretext" || \ echo "npm install @chenglou/pretext" ``` Run the detected install command. Then use standard imports in the component. ### HTML Generation Write a single file using the Write tool. Save to: `"${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/designs/-YYYYMMDD/finalized.html` For framework output, save to: `"${GSTACK_HOME:-$HOME/.gstack}"/projects/${PROJECT_ID:-unknown}/designs/-YYYYMMDD/finalized.[tsx|svelte|vue]` **Always include in vanilla HTML:** - Pretext source (inlined or CDN, see above) - CSS custom properties for design tokens from DESIGN.md / Step 1 extraction - Google Fonts via `` tags + `document.fonts.ready` gate before first `prepare()` - Semantic HTML5 (`
`, `