mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-20 18:16:30 +03:00
620 lines
34 KiB
Plaintext
620 lines
34 KiB
Plaintext
---
|
|
import Base from '../../layouts/Base.astro';
|
|
import '../../styles/sub-pages.css';
|
|
import '../../styles/designing-kinpaku.css';
|
|
---
|
|
|
|
<Base
|
|
title="Designing with Impeccable"
|
|
description="The core loop: start, iterate, polish, maintain. How to use Impeccable end-to-end, from a blank file to shipped feature to paid-down design debt."
|
|
activeNav="designing"
|
|
canonicalPath="/designing"
|
|
bodyClass="sub-page designing-page-body designing-kinpaku kinpaku-chrome"
|
|
>
|
|
|
|
<div class="designing-page">
|
|
<section class="designing-hero">
|
|
<header class="designing-page-header">
|
|
<h1 class="designing-page-title">Designing <em>with Impeccable</em></h1>
|
|
<p class="designing-page-lede">Use Impeccable in four phases: set context, improve what exists, check before shipping, and keep the design system from drifting.</p>
|
|
</header>
|
|
|
|
<div class="designing-loop-wrap" aria-label="The four-phase loop">
|
|
<span class="designing-loop-wrap-eyebrow">The core loop</span>
|
|
<div class="designing-loop">
|
|
|
|
<a class="designing-loop-node designing-loop-node--start" href="#start">
|
|
<span class="designing-loop-name">Start</span>
|
|
<span class="designing-loop-hint">From a blank file, through a brief, to a designed feature.</span>
|
|
</a>
|
|
<a class="designing-loop-node designing-loop-node--iterate" href="#iterate">
|
|
<span class="designing-loop-name">Iterate</span>
|
|
<span class="designing-loop-hint">Refine in place. Command line or in the browser.</span>
|
|
</a>
|
|
<a class="designing-loop-node designing-loop-node--polish" href="#polish">
|
|
<span class="designing-loop-name">Polish</span>
|
|
<span class="designing-loop-hint">The pre-ship gauntlet. Audit, clarify, harden.</span>
|
|
</a>
|
|
<a class="designing-loop-node designing-loop-node--maintain" href="#maintain">
|
|
<span class="designing-loop-name">Maintain</span>
|
|
<span class="designing-loop-hint">Pay down design debt before it solidifies.</span>
|
|
</a>
|
|
<div class="designing-loop-wheel" aria-hidden="true">
|
|
<svg class="designing-loop-wheel-svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
|
|
<circle class="designing-loop-wheel-ring" cx="50" cy="50" r="46"/>
|
|
<!-- 12 tick marks at 30° increments. Cardinals (0/90/180/270) stronger. -->
|
|
<line class="designing-loop-wheel-tick designing-loop-wheel-tick--cardinal" x1="50" y1="2.5" x2="50" y2="5.5"/>
|
|
<line class="designing-loop-wheel-tick" x1="73" y1="8.7" x2="72" y2="11.4"/>
|
|
<line class="designing-loop-wheel-tick" x1="91.3" y1="27" x2="88.6" y2="28"/>
|
|
<line class="designing-loop-wheel-tick designing-loop-wheel-tick--cardinal" x1="97.5" y1="50" x2="94.5" y2="50"/>
|
|
<line class="designing-loop-wheel-tick" x1="91.3" y1="73" x2="88.6" y2="72"/>
|
|
<line class="designing-loop-wheel-tick" x1="73" y1="91.3" x2="72" y2="88.6"/>
|
|
<line class="designing-loop-wheel-tick designing-loop-wheel-tick--cardinal" x1="50" y1="97.5" x2="50" y2="94.5"/>
|
|
<line class="designing-loop-wheel-tick" x1="27" y1="91.3" x2="28" y2="88.6"/>
|
|
<line class="designing-loop-wheel-tick" x1="8.7" y1="73" x2="11.4" y2="72"/>
|
|
<line class="designing-loop-wheel-tick designing-loop-wheel-tick--cardinal" x1="2.5" y1="50" x2="5.5" y2="50"/>
|
|
<line class="designing-loop-wheel-tick" x1="8.7" y1="27" x2="11.4" y2="28"/>
|
|
<line class="designing-loop-wheel-tick" x1="27" y1="8.7" x2="28" y2="11.4"/>
|
|
<!-- Clockwise-orbiting accent dot, animates with offset-path. -->
|
|
<circle class="designing-loop-wheel-dot" cx="0" cy="0" r="2.2"/>
|
|
</svg>
|
|
<span class="designing-loop-wheel-arrow designing-loop-wheel-arrow--ne">↘</span>
|
|
<span class="designing-loop-wheel-arrow designing-loop-wheel-arrow--se">↙</span>
|
|
<span class="designing-loop-wheel-arrow designing-loop-wheel-arrow--sw">↖</span>
|
|
<span class="designing-loop-wheel-arrow designing-loop-wheel-arrow--nw">↗</span>
|
|
<div class="designing-loop-wheel-center">
|
|
<span class="designing-loop-wheel-center-label">designing</span>
|
|
<span class="designing-loop-wheel-center-mark">impeccable</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="designing-loop-track">
|
|
<nav class="designing-phasenav" aria-label="Loop phases">
|
|
<a class="designing-phasenav-link" href="#start">Start</a>
|
|
<a class="designing-phasenav-link" href="#iterate">Iterate</a>
|
|
<a class="designing-phasenav-link" href="#polish">Polish</a>
|
|
<a class="designing-phasenav-link" href="#maintain">Maintain</a>
|
|
</nav>
|
|
|
|
<section class="ks-section designing-phase" id="start">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">Start with context.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">Before asking an agent to design, give it the basics: who the interface is for, what it should feel like, what it should avoid, and whether this is a marketing surface or an app screen. <code>/impeccable init</code> saves that context first. Then use <code>/impeccable shape</code> for a brief or <code>/impeccable craft</code> for the full build.</p>
|
|
<div class="designing-phase-commands">
|
|
<a class="designing-phase-cmd" href="/docs/init">/impeccable init</a>
|
|
<a class="designing-phase-cmd" href="/docs/shape">/impeccable shape</a>
|
|
<a class="designing-phase-cmd" href="/docs/craft">/impeccable craft</a>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="designing-phase-body designing-start">
|
|
<div class="designing-start-step">
|
|
<div class="designing-start-grid">
|
|
<div class="docs-viz-file" style="margin:0">
|
|
<div class="docs-viz-file-header">
|
|
<span class="docs-viz-file-name">PRODUCT.md</span>
|
|
<span class="docs-viz-file-status">Written by init</span>
|
|
</div>
|
|
<div class="docs-viz-file-body">
|
|
<div class="docs-viz-file-row">
|
|
<span class="docs-viz-file-k">Register</span>
|
|
<span class="docs-viz-file-v">Product. Design serves the task.</span>
|
|
</div>
|
|
<div class="docs-viz-file-row">
|
|
<span class="docs-viz-file-k">Users</span>
|
|
<span class="docs-viz-file-v">SREs on call, reading fast, often in the dark.</span>
|
|
</div>
|
|
<div class="docs-viz-file-row">
|
|
<span class="docs-viz-file-k">Voice</span>
|
|
<span class="docs-viz-file-v">Calm, clinical, no hype.</span>
|
|
</div>
|
|
<div class="docs-viz-file-row">
|
|
<span class="docs-viz-file-k">Anti-references</span>
|
|
<span class="docs-viz-file-v">Purple gradients. Glassmorphism. Hype.</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="designing-start-grid-prose">
|
|
<p>Init runs a short setup interview about audience, brand/product lane, voice, and anti-references. It writes <code>PRODUCT.md</code> and, if there's code to scan, offers a <code>DESIGN.md</code>. Every later command reads both files before generating.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="designing-start-step">
|
|
<p class="designing-start-step-note">For blank-slate work, a visual reference helps more than a long prompt. <code>shape</code> can draft a brand toolkit for review, and <code>craft</code> can code toward a hi-fi mock instead of a paragraph. Neo Mirai is the full loop: generated direction, implemented page, browser iteration.</p>
|
|
|
|
<div class="designing-visualize-spread">
|
|
<figure class="designing-visualize-plate designing-visualize-plate--brand">
|
|
<a class="designing-visualize-plate-frame" href="/cases/neo-mirai" aria-label="Read the Neo Mirai case study">
|
|
<img src="/assets/openai_image_2_brand.jpg" alt="Auto-generated brand toolkit plate: identity lockups, colour palette, type specimens, icon system, and application mocks for a fictional AI design conference, rendered in warm earth tones." loading="lazy" width="1536" height="1024" />
|
|
</a>
|
|
<figcaption class="designing-visualize-plate-cap">
|
|
<span class="designing-visualize-plate-kind">Shape</span>
|
|
<p class="designing-visualize-plate-note">Brand toolkit. Identity, palette, type, icon language, applications, social tiles, UI direction. One plate, reviewable at a glance. Approved decisions get written into <code>DESIGN.md</code>.</p>
|
|
</figcaption>
|
|
</figure>
|
|
|
|
<figure class="designing-visualize-plate designing-visualize-plate--hifi">
|
|
<a class="designing-visualize-plate-frame" href="/cases/neo-mirai" aria-label="Read the Neo Mirai case study">
|
|
<img src="/assets/openai_image_2_hifi.jpg" alt="Auto-generated hi-fi landing-page mock: a long vertical editorial comp for a fictional Tokyo AI design conference, in warm earth tones with committed serif display type." loading="lazy" width="864" height="1821" />
|
|
</a>
|
|
<figcaption class="designing-visualize-plate-cap">
|
|
<span class="designing-visualize-plate-kind">Visualize</span>
|
|
<p class="designing-visualize-plate-note">Hi-fi reference. The destination, before the first line of CSS. Craft codes toward a concrete image, not an abstract brief. That is the step change.</p>
|
|
</figcaption>
|
|
</figure>
|
|
|
|
<figure class="designing-visualize-plate designing-visualize-plate--live">
|
|
<a class="designing-visualize-plate-frame" href="/neo-mirai/" aria-label="Open the Neo Mirai live site">
|
|
<img src="/assets/cases/neo-mirai/live-page.png" alt="Full-page screenshot of the implemented Neo Mirai website." loading="lazy" width="1440" height="3013" />
|
|
</a>
|
|
<figcaption class="designing-visualize-plate-cap">
|
|
<span class="designing-visualize-plate-kind">Ship</span>
|
|
<p class="designing-visualize-plate-note">Live build. The mock became semantic markup, regenerated assets, responsive fixes, nav state, speaker carousel behavior, and browser-verified polish. <a href="/neo-mirai/">Open the live site</a>.</p>
|
|
</figcaption>
|
|
</figure>
|
|
</div>
|
|
|
|
<p class="designing-visualize-foot">The first two plates were generated by <strong>OpenAI GPT Image 2</strong>. The third is the implemented Neo Mirai page. <strong>Gemini Nano Banana Pro</strong>, <strong>Imagen 4 Ultra</strong>, and <strong>Grok Imagen</strong> work the same way, via Codex, Gemini CLI, and compatible harnesses.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="ks-section designing-phase" id="iterate">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">Refine what's there.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">Once something exists, you're iterating. There are two paths: specific commands for named dimensions, or Live Mode for visual exploration.</p>
|
|
</header>
|
|
|
|
<div class="designing-phase-body">
|
|
<div class="designing-iterate-split">
|
|
<div class="designing-iterate-col">
|
|
<h3 class="designing-iterate-name">When the edit has a name.</h3>
|
|
<p class="designing-iterate-when">Type a command and let the skill encode a specific discipline. Best when you know the word: typography, layout, color, motion.</p>
|
|
<div class="designing-iterate-terminal" aria-hidden="true">
|
|
<div class="designing-iterate-terminal-line"><span class="designing-iterate-terminal-prompt">$</span><span>/impeccable polish pricing</span></div>
|
|
<div class="designing-iterate-terminal-line"><span class="designing-iterate-terminal-prompt">$</span><span>/impeccable bolder hero</span></div>
|
|
<div class="designing-iterate-terminal-line"><span class="designing-iterate-terminal-prompt">$</span><span>/impeccable typeset checkout</span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="designing-iterate-col">
|
|
<h3 class="designing-iterate-name">When the edit is easier to point at.</h3>
|
|
<p class="designing-iterate-when">Run <code>/impeccable live</code> in your AI tool and it drops this picker onto your running dev server. Point at any element, draw or type what you want, hit Go. Three production-quality variants; accept one and it writes back to source.</p>
|
|
<div class="designing-iterate-live" aria-hidden="true">
|
|
<div class="docs-viz-live-frame" style="max-width:100%">
|
|
<div class="docs-viz-live-chrome">
|
|
<span class="docs-viz-live-dot"></span>
|
|
<span class="docs-viz-live-dot"></span>
|
|
<span class="docs-viz-live-dot"></span>
|
|
<span class="docs-viz-live-url">localhost:3000</span>
|
|
</div>
|
|
<div class="docs-viz-live-stage">
|
|
<div class="docs-viz-live-target">
|
|
<span class="docs-viz-live-kicker">No. 04</span>
|
|
<h4 class="docs-viz-live-title">Letters, <em>occasionally</em>.</h4>
|
|
<button class="docs-viz-live-btn" type="button">Send me one</button>
|
|
</div>
|
|
<div class="docs-viz-live-outline"></div>
|
|
<div class="docs-viz-live-ctx">
|
|
<button class="docs-viz-live-ctx-nav" type="button">‹</button>
|
|
<span class="docs-viz-live-ctx-counter">2 / 3</span>
|
|
<button class="docs-viz-live-ctx-nav" type="button">›</button>
|
|
<span class="docs-viz-live-ctx-divider"></span>
|
|
<button class="docs-viz-live-ctx-discard" type="button">✕</button>
|
|
<button class="docs-viz-live-ctx-accept" type="button">Accept</button>
|
|
</div>
|
|
<div class="docs-viz-live-gbar">
|
|
<span class="docs-viz-live-gbar-mark">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M5 2.5 L13.5 2.5 L5.5 21.5 L5 21.5 Q2.5 21.5 2.5 19 L2.5 5 Q2.5 2.5 5 2.5 Z"/><path d="M16.5 2.5 L19 2.5 Q21.5 2.5 21.5 5 L21.5 19 Q21.5 21.5 19 21.5 L8.5 21.5 Z"/></svg>
|
|
</span>
|
|
<span class="docs-viz-live-gbar-btn is-active">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><line x1="22" y1="12" x2="18" y2="12"/><line x1="6" y1="12" x2="2" y2="12"/><line x1="12" y1="6" x2="12" y2="2"/><line x1="12" y1="22" x2="12" y2="18"/></svg>
|
|
<span>Pick</span>
|
|
</span>
|
|
<span class="docs-viz-live-gbar-btn">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 5v14"/><path d="M5 12h14"/></svg>
|
|
<span>Insert</span>
|
|
</span>
|
|
<span class="docs-viz-live-gbar-btn">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
<span>Detect</span>
|
|
</span>
|
|
<span class="docs-viz-live-gbar-btn">
|
|
<svg viewBox="0 0 24 24" fill="currentColor"><rect x="3" y="3" width="8" height="8" rx="1"/><rect x="13" y="3" width="8" height="8" rx="1"/><rect x="3" y="13" width="8" height="8" rx="1"/><rect x="13" y="13" width="8" height="8" rx="1" opacity="0.5"/></svg>
|
|
<span class="docs-viz-live-gbar-btn-mono">DESIGN.md</span>
|
|
</span>
|
|
<span class="docs-viz-live-gbar-divider"></span>
|
|
<span class="docs-viz-live-gbar-x">
|
|
<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><line x1="3" y1="3" x2="11" y2="11"/><line x1="11" y1="3" x2="3" y2="11"/></svg>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="designing-iterate-table">
|
|
<caption>When to reach for which</caption>
|
|
<tbody>
|
|
<tr>
|
|
<th scope="row">Fix something "off" that you can't name</th>
|
|
<td><a href="/live-mode">/impeccable live</a></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Apply a specific discipline: type, layout, color, motion</th>
|
|
<td><a href="/docs/typeset">/typeset</a> · <a href="/docs/layout">/layout</a> · <a href="/docs/colorize">/colorize</a> · <a href="/docs/animate">/animate</a></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Explore three directions side by side</th>
|
|
<td><a href="/live-mode">/impeccable live</a></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Ask "is this any good?"</th>
|
|
<td><a href="/docs/critique">/impeccable critique</a></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Bring a safe design to life, or tone a shouting one down</th>
|
|
<td><a href="/docs/bolder">/bolder</a> · <a href="/docs/quieter">/quieter</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="ks-section designing-phase" id="polish">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">The pre-ship gauntlet.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">Three commands before anything ships. They don't redesign, they find what's left to fix. Point them at a narrow target: one section reviewed closely beats a whole page reviewed at a glance, the way a lens sharpens as it tightens.</p>
|
|
</header>
|
|
|
|
<div class="designing-phase-body">
|
|
<div class="designing-polish">
|
|
<div class="designing-polish-band">
|
|
<span class="designing-polish-band-label">Pre-ship</span>
|
|
<div class="designing-polish-band-cmds">
|
|
<a href="/docs/audit">audit</a>
|
|
<a href="/docs/clarify">clarify</a>
|
|
<a href="/docs/harden">harden</a>
|
|
</div>
|
|
<span class="designing-polish-band-meta">03 · 04</span>
|
|
</div>
|
|
<div class="designing-polish-grid">
|
|
<div class="designing-polish-col">
|
|
<h3 class="designing-polish-name">Score it.</h3>
|
|
<p class="designing-polish-desc">Five dimensions scored 0 to 4: accessibility, performance, theming, responsive, anti-patterns. Findings tagged P0 to P3.</p>
|
|
</div>
|
|
<div class="designing-polish-col">
|
|
<h3 class="designing-polish-name">Rewrite the copy.</h3>
|
|
<p class="designing-polish-desc">Labels, error messages, empty-state prose, microcopy. Tuned to the audience from PRODUCT.md.</p>
|
|
</div>
|
|
<div class="designing-polish-col">
|
|
<h3 class="designing-polish-name">Stress-test reality.</h3>
|
|
<p class="designing-polish-desc">60-character names, German product titles, prices in the billions, 500s, offline. Production data is messy.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="ks-section designing-phase" id="maintain">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">Design debt is real. Pay it down.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">Features ship, drift happens. Two commands close the gap before it solidifies.</p>
|
|
</header>
|
|
|
|
<div class="designing-phase-body">
|
|
<div class="ks-bento designing-maintain">
|
|
<article class="ks-bento-tile ks-bento-tile--span-6">
|
|
<span class="designing-maintain-label"><a href="/docs/extract">/impeccable extract</a></span>
|
|
<div class="designing-maintain-stage">
|
|
<div class="designing-extract-viz" aria-hidden="true">
|
|
<div class="designing-extract-before">
|
|
<span class="designing-extract-btn">Subscribe</span>
|
|
<span class="designing-extract-btn">Submit</span>
|
|
<span class="designing-extract-btn">Join</span>
|
|
<span class="designing-extract-btn">Send</span>
|
|
<span class="designing-extract-btn">Go</span>
|
|
<span class="designing-extract-btn">OK</span>
|
|
</div>
|
|
<span class="designing-extract-arrow">→</span>
|
|
<span class="designing-extract-after">Button</span>
|
|
</div>
|
|
</div>
|
|
<h3 class="designing-maintain-name">Consolidate drift.</h3>
|
|
<p class="designing-maintain-desc">Find patterns used three or more times with the same intent. Propose tokens and primitives.</p>
|
|
</article>
|
|
|
|
<article class="ks-bento-tile ks-bento-tile--span-6">
|
|
<span class="designing-maintain-label"><a href="/docs/document">/impeccable document</a></span>
|
|
<div class="designing-maintain-stage">
|
|
<div class="designing-designmd-preview" aria-hidden="true">
|
|
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">01</span><span>Overview</span></div>
|
|
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">02</span><span>Colors</span></div>
|
|
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">03</span><span>Typography</span></div>
|
|
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">04</span><span>Elevation</span></div>
|
|
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">05</span><span>Components</span></div>
|
|
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">06</span><span>Do's & Don'ts</span></div>
|
|
</div>
|
|
</div>
|
|
<h3 class="designing-maintain-name">Re-capture the system.</h3>
|
|
<p class="designing-maintain-desc">Scans your tokens, components, and rendered routes, then writes a DESIGN.md in the Stitch format. The more it points at your real components and live routes, the closer Impeccable reads your design language instead of guessing at it.</p>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</div>
|
|
|
|
<section class="ks-section designing-phase designing-phase--appendix" aria-label="Where Impeccable runs">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">Mostly, you're in the skill.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">The 23 commands run inside your AI coding tool: Cursor, Claude Code, Codex, Gemini CLI, Copilot. That's where everything on this page happens. The same anti-pattern detector also runs in two places outside the chat.</p>
|
|
</header>
|
|
|
|
<div class="designing-phase-body">
|
|
<div class="ks-bento designing-surfaces">
|
|
<article class="ks-bento-tile ks-bento-tile--span-6">
|
|
<span class="designing-maintain-label">Command line</span>
|
|
<h3 class="designing-maintain-name">In CI, as a gate.</h3>
|
|
<div class="designing-surface-cmd">
|
|
<span class="designing-surface-cmd-prompt">$</span>
|
|
<span>npx impeccable detect src/</span>
|
|
</div>
|
|
<p class="designing-maintain-desc">Point it at a directory, a file, or a URL. Deterministic rules and JSON output, with an exit code that fails the build when slop slips into a pull request.</p>
|
|
</article>
|
|
<article class="ks-bento-tile ks-bento-tile--span-6">
|
|
<span class="designing-maintain-label">Chrome extension</span>
|
|
<h3 class="designing-maintain-name">On any page, live.</h3>
|
|
<div class="designing-surface-cmd designing-surface-cmd--chrome">
|
|
<span class="docs-viz-live-dot"></span>
|
|
<span class="docs-viz-live-dot"></span>
|
|
<span class="docs-viz-live-dot"></span>
|
|
<span class="designing-surface-cmd-url">a-competitor.com</span>
|
|
</div>
|
|
<p class="designing-maintain-desc">The same checks as a browser overlay, on anything live: your staging build, a competitor, a page you'll never get into an editor.</p>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="ks-section designing-phase designing-phase--appendix" aria-label="Brand or product lane">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">Brand, or product.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">Two defaults with different vocabularies. Impeccable picks the lane from your task cue and <code>PRODUCT.md</code> before every command, so <code>typeset</code>, <code>animate</code>, <code>colorize</code>, and friends adjust their output to match. You rarely need to set it by hand.</p>
|
|
</header>
|
|
|
|
<div class="designing-phase-body">
|
|
<div class="ks-bento designing-lanes">
|
|
<article class="ks-bento-tile ks-bento-tile--span-6">
|
|
<p class="designing-lane-rule"><strong>Brand.</strong> Design is the deliverable: landing pages, campaigns, editorial, portfolios. Distinctive type, committed palette, image-led heroes. The impression is the product.</p>
|
|
<div class="designing-lane-mock designing-lane-mock--brand" aria-hidden="true">
|
|
<span class="designing-lane-mock-label">Issue 04 · Dispatch</span>
|
|
<span class="designing-lane-mock-title"><span class="designing-lane-mock-accent">Shape</span> the story.</span>
|
|
</div>
|
|
</article>
|
|
<article class="ks-bento-tile ks-bento-tile--span-6">
|
|
<p class="designing-lane-rule"><strong>Product.</strong> Design serves the task: app UI, admin, dashboards, tools. Fluent density, semantic states, repeatable components. Users are here to finish something.</p>
|
|
<div class="designing-lane-mock designing-lane-mock--product" aria-hidden="true">
|
|
<div class="designing-lane-product-row">
|
|
<span class="designing-lane-product-k">Users</span>
|
|
<span class="designing-lane-product-v">12,482</span>
|
|
</div>
|
|
<div class="designing-lane-product-row">
|
|
<span class="designing-lane-product-k">Active now</span>
|
|
<span class="designing-lane-product-v">1,207</span>
|
|
</div>
|
|
<div class="designing-lane-product-row">
|
|
<span class="designing-lane-product-k">Conversion</span>
|
|
<span class="designing-lane-product-v">4.8%</span>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="ks-section designing-phase designing-phase--appendix" aria-label="What to avoid">
|
|
<header class="ks-section-head designing-phase-head">
|
|
<h2 class="designing-phase-title">What to avoid.</h2>
|
|
<p class="ks-section-sub designing-phase-sub">An anti-patterns list, for using the anti-patterns tool.</p>
|
|
</header>
|
|
|
|
<div class="designing-phase-body">
|
|
<ul class="designing-avoid">
|
|
<li>
|
|
<span class="designing-avoid-x" aria-hidden="true">×</span>
|
|
<div>
|
|
<span class="designing-avoid-title">Running both Impeccable and Anthropic's frontend-design skill</span>
|
|
<p class="designing-avoid-desc">Anthropic still promotes their skill in Claude Code, but it's been unmaintained and is now behind on recommended patterns. Run both and they collide on vocabulary, cancelling each other out. Pick one.</p>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<span class="designing-avoid-x" aria-hidden="true">×</span>
|
|
<div>
|
|
<span class="designing-avoid-title">Pinning every command</span>
|
|
<p class="designing-avoid-desc">Pinning brings back <code>/audit</code>, <code>/polish</code>, <code>/critique</code> as shortcuts. Pin everything and you've re-exploded the <code>/</code> menu the v3.0 consolidation cleaned up. Pin the two or three you reach for daily.</p>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<span class="designing-avoid-x" aria-hidden="true">×</span>
|
|
<div>
|
|
<span class="designing-avoid-title">Skipping <code>init</code></span>
|
|
<p class="designing-avoid-desc">Commands still run without PRODUCT.md and DESIGN.md. They default to generic SaaS patterns. The floor is meaningfully higher with context. Run init once; every later command benefits.</p>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<span class="designing-avoid-x" aria-hidden="true">×</span>
|
|
<div>
|
|
<span class="designing-avoid-title">Treating it like a linter</span>
|
|
<p class="designing-avoid-desc">Impeccable is an opinionated design partner, not a validator. It has a point of view. Push back with a reason and it'll work with you. Ignore the opinion without a reason and output gets worse, not better.</p>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
|
|
<nav class="designing-cta" aria-label="Where to go next">
|
|
<a class="designing-cta-card" href="/docs/init">
|
|
<h2 class="designing-cta-card-title">Start with <em>init</em></h2>
|
|
<p class="designing-cta-card-desc">Five minutes of discovery, one PRODUCT.md, one DESIGN.md, live mode ready. Every command downstream gets sharper from here.</p>
|
|
</a>
|
|
<a class="designing-cta-card" href="/tutorials">
|
|
<h2 class="designing-cta-card-title">Open a <em>tutorial</em></h2>
|
|
<p class="designing-cta-card-desc">Three short walkthroughs: getting started, Live Mode, and critique with the overlay.</p>
|
|
</a>
|
|
</nav>
|
|
</div>
|
|
|
|
<script is:inline>
|
|
// Phase scroll-spy: highlight the active loop phase in the sticky nav as
|
|
// the reader scrolls. The active section is the one occupying the band just
|
|
// under the sticky header + nav (rootMargin clears ~150px at the top).
|
|
(function initPhaseNav() {
|
|
const nav = document.querySelector('.designing-phasenav');
|
|
if (!nav || !('IntersectionObserver' in window)) return;
|
|
const links = [...nav.querySelectorAll('.designing-phasenav-link')];
|
|
const setActive = (id) => links.forEach((a) =>
|
|
a.classList.toggle('is-active', a.getAttribute('href') === '#' + id));
|
|
const sections = links
|
|
.map((a) => document.getElementById(a.getAttribute('href').slice(1)))
|
|
.filter(Boolean);
|
|
if (!sections.length) return;
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.id); });
|
|
}, { rootMargin: '-150px 0px -55% 0px', threshold: 0 });
|
|
sections.forEach((s) => observer.observe(s));
|
|
})();
|
|
|
|
// Copy buttons on rendered code blocks
|
|
document.addEventListener('click', (e) => {
|
|
const btn = e.target.closest('[data-copy]');
|
|
if (!btn) return;
|
|
const text = btn.getAttribute('data-copy');
|
|
if (!text) return;
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
btn.classList.add('is-copied');
|
|
setTimeout(() => btn.classList.remove('is-copied'), 1500);
|
|
}).catch(() => {});
|
|
});
|
|
|
|
// Mobile sidebar toggle (shown on narrow viewports, hidden on desktop).
|
|
document.addEventListener('click', (e) => {
|
|
const toggle = e.target.closest('.skills-sidebar-toggle');
|
|
if (!toggle) return;
|
|
const expanded = toggle.getAttribute('aria-expanded') === 'true';
|
|
toggle.setAttribute('aria-expanded', String(!expanded));
|
|
});
|
|
|
|
// Before/after split-compare: drag on touch, hover OR drag on mouse.
|
|
// Pointer events attach to the padded .split-comparison wrapper so
|
|
// there is a ~20px invisible buffer around the visible box. The
|
|
// divider only snaps back when the pointer leaves that outer buffer.
|
|
(function initSplitCompare() {
|
|
const wrappers = document.querySelectorAll('.split-comparison');
|
|
if (wrappers.length === 0) return;
|
|
const hasHover = matchMedia('(hover: hover)').matches;
|
|
const DEFAULT_POSITION = 50;
|
|
|
|
for (const wrapper of wrappers) {
|
|
const container = wrapper.querySelector('.split-container');
|
|
const splitAfter = wrapper.querySelector('.split-after');
|
|
const splitDivider = wrapper.querySelector('.split-divider');
|
|
if (!container || !splitAfter || !splitDivider) continue;
|
|
|
|
const tanAngle = Math.tan(10 * Math.PI / 180);
|
|
let skewOffset = 8;
|
|
const recalcSkew = () => {
|
|
const r = container.getBoundingClientRect();
|
|
if (r.width > 0 && r.height > 0) {
|
|
skewOffset = 50 * r.height * tanAngle / r.width;
|
|
}
|
|
};
|
|
recalcSkew();
|
|
window.addEventListener('resize', recalcSkew, { passive: true });
|
|
|
|
let targetX = DEFAULT_POSITION;
|
|
let currentX = DEFAULT_POSITION;
|
|
let rafId = null;
|
|
|
|
const paint = (pct) => {
|
|
const x = Math.max(-skewOffset, Math.min(100 + skewOffset, pct));
|
|
splitAfter.style.clipPath =
|
|
`polygon(${x + skewOffset}% 0%, 100% 0%, 100% 100%, ${x - skewOffset}% 100%)`;
|
|
splitDivider.style.left = `${x}%`;
|
|
};
|
|
|
|
const step = () => {
|
|
currentX += (targetX - currentX) * 0.2;
|
|
if (Math.abs(targetX - currentX) < 0.1) {
|
|
currentX = targetX;
|
|
rafId = null;
|
|
} else {
|
|
rafId = requestAnimationFrame(step);
|
|
}
|
|
paint(currentX);
|
|
};
|
|
|
|
const setTarget = (pct) => {
|
|
targetX = pct;
|
|
if (rafId === null) rafId = requestAnimationFrame(step);
|
|
};
|
|
|
|
paint(DEFAULT_POSITION);
|
|
|
|
// Percentage is always relative to the VISIBLE .split-container,
|
|
// not the padded .split-comparison wrapper. The pointer event
|
|
// target is the wrapper but the clip-path math uses the inner box.
|
|
const pctFromClientX = (clientX) => {
|
|
const rect = container.getBoundingClientRect();
|
|
return ((clientX - rect.left) / rect.width) * 100;
|
|
};
|
|
|
|
let hovering = false;
|
|
let dragging = false;
|
|
|
|
wrapper.addEventListener('pointerenter', (e) => {
|
|
if (hasHover && e.pointerType === 'mouse') {
|
|
hovering = true;
|
|
}
|
|
});
|
|
|
|
wrapper.addEventListener('pointerdown', (e) => {
|
|
dragging = true;
|
|
wrapper.setPointerCapture(e.pointerId);
|
|
setTarget(pctFromClientX(e.clientX));
|
|
});
|
|
|
|
wrapper.addEventListener('pointermove', (e) => {
|
|
if (dragging || hovering) {
|
|
setTarget(pctFromClientX(e.clientX));
|
|
}
|
|
});
|
|
|
|
const endDrag = (e) => {
|
|
if (dragging) {
|
|
dragging = false;
|
|
try { wrapper.releasePointerCapture(e.pointerId); } catch {}
|
|
}
|
|
};
|
|
|
|
wrapper.addEventListener('pointerup', endDrag);
|
|
wrapper.addEventListener('pointercancel', endDrag);
|
|
|
|
wrapper.addEventListener('pointerleave', (e) => {
|
|
endDrag(e);
|
|
if (hovering) {
|
|
hovering = false;
|
|
setTarget(DEFAULT_POSITION);
|
|
}
|
|
});
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
</Base>
|