diff options
Diffstat (limited to 'frontend-design/references')
| -rw-r--r-- | frontend-design/references/accessibility.md | 109 | ||||
| -rw-r--r-- | frontend-design/references/design-review.md | 93 | ||||
| -rw-r--r-- | frontend-design/references/rationale-template.md | 133 | ||||
| -rw-r--r-- | frontend-design/references/responsive.md | 90 | ||||
| -rw-r--r-- | frontend-design/references/workflow.md | 86 |
5 files changed, 511 insertions, 0 deletions
diff --git a/frontend-design/references/accessibility.md b/frontend-design/references/accessibility.md new file mode 100644 index 0000000..2b0ca66 --- /dev/null +++ b/frontend-design/references/accessibility.md @@ -0,0 +1,109 @@ +# Accessibility + +Default target: WCAG 2.1 AA. For government, healthcare, finance, or other regulated contexts: AAA on specific criteria (verify with the user). Don't wait for a retrofit — apply during build. + +## Color Contrast + +**WCAG AA thresholds:** +- Normal text (< 18pt / < 14pt bold): **4.5:1** minimum +- Large text (≥ 18pt or ≥ 14pt bold): **3:1** minimum +- UI components and graphics (borders, icons, focus indicators): **3:1** minimum against adjacent colors +- Decorative or disabled elements are exempt — but a "disabled" button the user might still try to click is NOT decorative + +**Practical:** +- Use a checker during palette lock-in (WebAIM Contrast Checker, or `npx check-color-contrast`) +- Light text on saturated backgrounds (e.g., white on red-500) often fails — check, don't assume +- Gradient backgrounds mean text contrast varies across the gradient — check against the *worst-case* point under the text +- Ambient/atmospheric effects (dust, grain overlays, gradient meshes) can push borderline contrast below the line — verify after the effect is applied + +## Keyboard + +**Every interactive element reachable via keyboard alone.** Test by putting away the mouse and Tab / Shift-Tab / Enter / Space / arrow keys through the interface. + +- Focus order follows visual order (not DOM order if CSS reorders) +- `Tab` moves between controls; `Enter` / `Space` activates buttons and links; `Esc` dismisses modals/menus; arrow keys navigate within composite widgets (menus, radio groups, sliders) +- Custom controls (non-native buttons, non-native select): implement full keyboard behavior, not just `onClick` +- Skip-to-content link at the top of every page — invisible until focused + +**Focus visibility:** +- The default browser focus ring is ugly but functional. Don't delete it without a replacement. +- Custom focus styles need ≥ 3:1 contrast against the adjacent background +- `:focus-visible` (not `:focus`) for keyboard-only focus rings — lets mouse clicks stay clean without losing keyboard clarity + +## Semantic HTML + +Prefer native elements over `<div role="button" tabIndex="0" onClick={...}>`. Native buttons, links, form controls, and landmarks come with keyboard behavior, focus management, and screen reader semantics for free. + +**Landmarks:** +- `<header>`, `<nav>`, `<main>`, `<aside>`, `<footer>` — at most one `<main>` per page +- Heading hierarchy: one `<h1>`, then `<h2>`s, then `<h3>`s — don't skip levels +- `<section>` needs an `aria-labelledby` or it's just a `<div>` to a screen reader + +**Forms:** +- Every input has a visible `<label>`. Placeholder text is not a label. +- Error messages associated via `aria-describedby`; form-level errors announced via `aria-live="polite"` (non-urgent) or `assertive` (urgent; use sparingly) +- Required fields marked both visually (color or `*`) and programmatically (`required` attribute) + +## ARIA (when native isn't enough) + +- `aria-label` / `aria-labelledby` for elements without visible text (icon-only buttons, close ✕ buttons) +- `aria-expanded` on disclosure controls (accordions, menus) +- `aria-controls` to connect a control to the region it toggles +- `aria-hidden="true"` for decorative icons +- `role="alert"` or `aria-live` regions for dynamic announcements + +**Rules of ARIA (from the WAI):** +1. If a native HTML element or attribute exists for what you need, use that first. +2. Don't change native semantics with ARIA unless absolutely necessary. +3. All interactive ARIA controls must be keyboard-accessible. +4. Don't use `role="presentation"` / `aria-hidden="true"` on focusable elements. +5. Interactive elements must have an accessible name. + +## Reduced Motion + +Respect `prefers-reduced-motion` for animations, transitions, parallax, auto-playing video, scroll-triggered reveals. The aesthetic doesn't have to disappear — just slow down or still the motion. + +```css +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} +``` + +Override per-element for critical motion (a loading spinner should still spin, just perhaps slower). The blanket rule above is a baseline; tune for context. + +## Images, Icons, and Media + +- `alt=""` for decorative images; descriptive `alt` for meaningful ones +- SVG icons that carry meaning: `role="img"` + `aria-label`; purely decorative SVGs: `aria-hidden="true"` +- Video: captions for any spoken content; autoplay muted; controls not hidden +- Audio-only: transcript + +## Smoke Checklist (for quick audits) + +- [ ] All text meets contrast (spot-check worst-case regions) +- [ ] Tab order matches visual order; all interactive elements reachable +- [ ] Visible focus ring on every focusable element +- [ ] Semantic HTML used where a native element exists +- [ ] Icon-only buttons have `aria-label` or visible text +- [ ] Form fields have labels; errors are associated +- [ ] `prefers-reduced-motion` respected +- [ ] No keyboard trap (you can Tab *out* of every modal/menu) +- [ ] Page heading hierarchy is sensible (one `<h1>`, no skipped levels) + +## Testing + +- **Manual keyboard:** Tab through the whole page +- **axe-core / Lighthouse** for automated audits (both run in Chrome DevTools) +- **Screen reader spot-check:** VoiceOver (macOS), NVDA (Windows), Orca (Linux). Hit the main flows once. +- **zoom test:** 200% browser zoom — does layout hold? + +Automated tools catch ~30-40% of accessibility issues. Manual + screen reader catches most of the rest. + +## Operational Context Note + +For defense / ISR / operational dashboards — accessibility is especially not optional. Users operating complex systems under time pressure depend on clear focus, unambiguous contrast, and keyboard control. Industrial / brutalist / utilitarian aesthetics *can* be highly accessible if designed with care; they can also be less accessible if monochrome palettes push contrast near the floor. diff --git a/frontend-design/references/design-review.md b/frontend-design/references/design-review.md new file mode 100644 index 0000000..656b488 --- /dev/null +++ b/frontend-design/references/design-review.md @@ -0,0 +1,93 @@ +# Design Review + +Self-audit before handoff. The goal isn't "did I follow the rules" — it's "does the build match the commitment, and are any AI-slop defaults hiding in here?" Assume defaults crept in somewhere; find them. + +## Archetype Check + +Pull up the commitment from Phase 2 (or the `design-rationale.md` if you emitted one). Answer honestly: + +- [ ] Does the build read as the chosen archetype to a stranger? +- [ ] Are the font pairing, palette, motion philosophy, and layout approach the ones committed to, or did they drift? +- [ ] Is the archetype recognizable on the first five seconds of viewing, or does it require explanation? + +A build that "sort of" hits the archetype usually hits none cleanly. Better to overshoot than hedge. + +## Anti-Pattern Grep + +These are specific defaults that sneak back in even after you committed to something else. Check for each: + +**Fonts:** +- [ ] No Inter, Roboto, Arial, Helvetica (unless deliberately justified for this archetype) +- [ ] No "system-ui" family unless the archetype is literally "system-native" +- [ ] Display font is distinct from body font — if both are the same (e.g., all Inter), that's a miss +- [ ] Variable fonts with too many weights load-heavy — pick 2-3 weights max + +**Palette:** +- [ ] No purple-to-pink gradient on white +- [ ] No "evenly-distributed" palette — 6 colors all at 50% saturation reading as "gray blah" +- [ ] Dominant colors take more space than accents; accents have real contrast +- [ ] No "generic teal" (#14b8a6 and its cousins) unless the archetype specifically earns it + +**Layout:** +- [ ] Not a cards-in-a-grid with no hierarchy +- [ ] Not centered-column-of-text-with-a-hero-image (the default blog post) +- [ ] Not three-equal-feature-boxes (the default SaaS landing page) +- [ ] There's at least one layout choice the reader will remember + +**Motion:** +- [ ] Hover states exist and surprise (not just `opacity: 0.8`) +- [ ] Page load has a considered reveal (staggered, or deliberately instant — not "jump in as DOM parses") +- [ ] `prefers-reduced-motion` respected +- [ ] No unrequested scroll-jacking or mandatory scroll animations + +**Background / Atmosphere:** +- [ ] Not plain white or plain `#0a0a0a` background (unless that's the archetype's literal point) +- [ ] Some depth: gradient mesh, noise, dramatic shadow, decorative border, ambient texture — something +- [ ] Whatever's chosen, it feels *designed* not *applied* (random noise texture on anything = lazy) + +**Components:** +- [ ] Buttons don't look like every shadcn button ever +- [ ] Cards aren't the generic "rounded-lg shadow-md bg-white p-6" pattern +- [ ] Form fields have considered states (hover, focus, error, disabled, loading) +- [ ] Custom cursor, custom selection color, custom scrollbar where fitting for the archetype + +## Code Quality Match + +The aesthetic and the code have to agree. Red flags: + +- [ ] Ornate maximalist design + 40 lines of CSS = mismatch (ornate needs elaborate code) +- [ ] Claimed "minimalism" + 2000 lines of utility classes + 5 dependencies = mismatch (minimal aesthetic needs restrained code) +- [ ] No CSS variables in a multi-page design = palette will drift across components +- [ ] Inline styles scattered in JSX = the system hasn't been thought through + +Elegance in the code is part of the deliverable, not an afterthought. + +## Accessibility Smoke Check + +Run through [accessibility.md](accessibility.md)'s smoke checklist at minimum. If the build will ship, run Lighthouse + axe as well; fix CRITICAL and SERIOUS findings before handoff. + +## Responsive Smoke Check + +Resize the viewport to `sm` (~640px) and `lg` (~1024px). Does the aesthetic translate, or does the layout collapse to the AI-default "one centered column of stacked elements"? Some archetypes *should* collapse to a single column on mobile — but that's a choice, not a fallback. Verify via [responsive.md](responsive.md)'s checklist. + +## Performance Sanity + +- [ ] No 5MB hero image +- [ ] No autoplay video that isn't essential +- [ ] Font loading isn't blocking render (use `font-display: swap` or similar) +- [ ] Animations don't thrash layout (use `transform` and `opacity`, not `width` / `top` / `left`) +- [ ] Third-party scripts loaded async / deferred + +If the aesthetic requires heavy assets (hero videos, WebGL, etc.), that's fine — but it's a documented trade-off, not an accident. + +## Convergence Check + +If you've used this skill recently, what did the last build look like? If the last three builds all picked "brutally minimal" or all used the same font pairing — convergence. Break the pattern deliberately on the next invocation. The aesthetic space is large; defaulting to the same corner repeatedly is a failure. + +## Final: The One-Sentence Test + +Can you write one sentence describing what's memorable about this build? Not "it's clean and modern" — that applies to everything and nothing. A real answer: "The asymmetric terminal-green monospace hero with the brutalist grid and tiny rotating pixel cursor." If the sentence is vague, the design didn't commit hard enough. + +## Handoff + +Emit a `design-rationale.md` via [rationale-template.md](rationale-template.md) so the next iteration has context. Commit the rationale alongside the code — future work starts with it loaded, not with the aesthetic forgotten. diff --git a/frontend-design/references/rationale-template.md b/frontend-design/references/rationale-template.md new file mode 100644 index 0000000..20dd1e1 --- /dev/null +++ b/frontend-design/references/rationale-template.md @@ -0,0 +1,133 @@ +# Rationale Template + +Drop the following into a `design-rationale.md` alongside the code at handoff. Brief, specific, honest. Future iterations of the interface start by reading this. + +--- + +```markdown +# Design Rationale — <component / page / project name> + +**Date:** YYYY-MM-DD +**Author:** <name or "AI-assisted via /frontend-design"> +**Invoked from:** <initial user prompt or request summary, 1-2 lines> + +## 1. Purpose + +<One paragraph. What is this for, who uses it, what problem it solves.> + +## 2. Archetype + +**Chosen:** <brutally minimal / maximalist chaos / retro-futuristic / organic / luxury / playful / editorial / brutalist / art deco / soft / industrial / custom variant> + +**Why:** <One sentence tying archetype to purpose + audience.> + +**Trading away:** <What this direction sacrifices. "Maximalism trades subtlety and scannability for memorability" / "Minimalism trades information density for focus" / etc.> + +## 3. Locked decisions + +- **Font pairing:** <display font> for headings, <body font> for text. <One-line why.> +- **Palette:** <primary colors> with <accent colors>. <Where dominants live, where accents appear.> +- **Motion philosophy:** <In one line — staggered page-load / aggressive hover / no motion / whatever.> +- **Layout approach:** <Asymmetric grid / classic 12-col / brutalist stack / magazine spread / whatever.> + +## 4. Deliberately absent + +<List what's NOT in the design even though someone might expect it. "No card drop shadows — monochrome blocks define structure instead." "No hero image — typography carries the emotional weight." Explicitly naming the absences prevents the next iteration from adding them back by default.> + +## 5. Accessibility notes + +- Contrast verified at <AA / AAA> against <palette elements> +- Keyboard navigation: <summary of focus order and any custom controls> +- `prefers-reduced-motion`: <handled / not applicable> +- Known concerns: <anything below threshold, noted for follow-up> + +## 6. Responsive notes + +- Primary viewport: <desktop / mobile-first / specific breakpoint> +- Translation approach: <how the aesthetic holds at smaller sizes> +- Unsupported viewports (if any): <below X px, behavior is Y> + +## 7. Implementation notes + +- Framework: <React / Vue / plain HTML / etc.> +- Dependencies added: <list; keep short> +- Integration assumptions: <what the consuming codebase must provide> +- Known tradeoffs: <perf vs aesthetic, dep weight, etc.> + +## 8. Open questions / follow-ups + +- [ ] <item> +- [ ] <item> + +## 9. References + +- Brand guide: <link if used> +- Moodboard: <link if used> +- Similar designs consulted: <list> +``` + +--- + +## Filled example (abbreviated) + +```markdown +# Design Rationale — SOCOM demo landing + +**Date:** 2026-04-19 +**Author:** AI-assisted via /frontend-design +**Invoked from:** "Build a landing page for the SOCOM demo; feels technical +without being sterile." + +## 1. Purpose +Public-facing landing for the SOCOM ATAC demo. Audience: procurement +officers + technical evaluators. Must feel precise, credible, and +operationally-serious without reading as generic defense-contractor-beige. + +## 2. Archetype +**Chosen:** industrial/utilitarian with restrained editorial accents. +**Why:** Audience is operational; aesthetic distinctiveness comes from +precision, not decoration. +**Trading away:** Decorative delight; warmth. In exchange, seriousness and +signal density. + +## 3. Locked decisions +- **Font pairing:** IBM Plex Mono for headings; IBM Plex Sans for body. + (Mono carries the operational signal; sans keeps body readable.) +- **Palette:** Near-black (#0a0e0f) dominant, cool slate (#3a4851) secondary, + single desaturated amber accent (#c88c3a) used only for ATAC callouts. +- **Motion philosophy:** No motion on page load; hover states are snap-fast + (80ms). Stillness = precision. +- **Layout approach:** Grid visible as 1px cool-slate rules; content sits + inside named cells. Hero aligns to a single numbered row, not centered. + +## 4. Deliberately absent +- No hero video, no animated gradient +- No card shadows; cells share the grid rules instead +- No purple, no consumer-fintech palette cues +- No "book a demo" urgency; CTA is "Contact procurement" + +## 5. Accessibility notes +- AA verified on all text/button states +- Focus rings: 2px amber outline + offset, `:focus-visible` only +- `prefers-reduced-motion`: applies; hover transitions drop to 0ms + +## 6. Responsive notes +- Primary: desktop 1440px +- Mobile: single column, grid rules preserved; named cells stack vertically + in document order +- Below 360px: layout is acceptable but not designed for + +## 7. Implementation notes +- Framework: Next.js 14 (App Router) + Tailwind + IBM Plex (self-hosted) +- No additional deps +- Uses existing design tokens from ./lib/tokens.ts +- Integration: expects `@/components/grid` and `@/components/cell` primitives + +## 8. Open questions +- [ ] Is the amber accent readable in direct sunlight on outdoor demos? +- [ ] Legal has approved the "ATAC" wordmark treatment + +## 9. References +- Brand guide: internal/DeepSat-brand-2026-03.pdf +- Moodboard: Monokuma.com, Field Notes, NASA technical manuals +``` diff --git a/frontend-design/references/responsive.md b/frontend-design/references/responsive.md new file mode 100644 index 0000000..18be11f --- /dev/null +++ b/frontend-design/references/responsive.md @@ -0,0 +1,90 @@ +# Responsive + +Mobile is the dominant traffic profile for consumer web; desktop dominates operational and enterprise contexts. Commit to a primary viewport early — retrofitting responsive behavior into a desktop-only design is more expensive than building with breakpoints from the start. + +## Decision: Mobile-First or Desktop-First + +**Mobile-first** (build the small-screen layout first, scale up): +- Consumer web, marketing, e-commerce, public-facing apps +- Progressive enhancement ethos — base experience works everywhere, more features at larger sizes +- CSS reads as `/* default (mobile) */` → `@media (min-width: X)` overrides +- Simpler to keep working on constrained devices + +**Desktop-first** (design for a big screen, gracefully degrade): +- Operational dashboards, ISR displays, pro tools, internal enterprise apps +- Information density is the point; mobile is a fallback or unsupported +- CSS reads as `/* default (desktop) */` → `@media (max-width: X)` overrides +- Harder to keep working when the small screen is an afterthought + +Pick one deliberately. Hybrids (different viewport designs for "phone / tablet / desktop" with no progression ethos) usually produce three mediocre layouts rather than one good one. + +## Breakpoints + +Use **named, consistent** breakpoints — not magic numbers scattered across files. A design-system variable keeps them coherent. + +**Typical set** (Tailwind's values are reasonable defaults): + +| Name | Width | Use | +|---|---|---| +| sm | 640px | Large phones, phablets | +| md | 768px | Tablets, small laptops | +| lg | 1024px | Laptops | +| xl | 1280px | Desktops | +| 2xl | 1536px | Large desktops, wide monitors | + +**Don't** introduce a breakpoint at an arbitrary exact pixel. If content reflows badly at 820px, push `md` up to 840px or decide the design needs an actual rearrangement at that size — not a pixel workaround. + +**Container queries** (`@container`) are now broadly supported and are often a better answer than viewport breakpoints for components that live in varied contexts. A card that's 300px wide in a sidebar and 900px wide on a detail page should branch on *its* size, not the viewport's. + +## Aesthetic Translation by Archetype + +Archetypes don't all respond to screen size the same way. Match the translation strategy to the direction chosen: + +| Archetype | Small-screen translation | +|---|---| +| Maximalist chaos | Simplify, don't dilute. Fewer layered effects; preserve the rule-breaking layout feel. | +| Brutally minimal | Scales naturally. Ensure spacing scales with viewport — "generous" at 1920px ≠ "generous" at 375px. | +| Retro-futuristic | Stacked vertical scroll with preserved detail. Don't lose the motif elements (grids, glows, terminal text) even if resized. | +| Organic / natural | Reflow gracefully; the aesthetic comes from shape and color, not grid. Near-free on mobile. | +| Luxury / refined | Preserve whitespace proportions. The whitespace *is* the design. Don't cram. | +| Playful / toy-like | Often translates well; the whimsy is in shapes/colors/animations, not layout. | +| Editorial / magazine | Hardest. Magazine spreads assume two-page layouts. Single column on mobile, but preserve type hierarchy and whitespace choreography. | +| Brutalist / raw | Scales naturally. Monospace and visible-grid aesthetics don't fight small screens. | +| Art deco / geometric | Retain the geometric motifs as accents; simplify complex patterns. | +| Soft / pastel | Reflow easily. Watch contrast on smaller screens where brightness shifts. | +| Industrial / utilitarian | Operational dashboards often unsupported on mobile — that's a legitimate product decision. If mobile is required, prioritize scanning over interaction. | + +## Responsive Typography + +- Use `clamp(min, preferred, max)` for fluid type that never breaks the layout: + ```css + h1 { font-size: clamp(2rem, 5vw + 1rem, 4rem); } + ``` +- Line length: aim for 45-75 characters per line at the primary viewport. On mobile, 30-40 is fine for body text. +- Line height scales inversely — tighter on headlines, looser on body, typically `1.2` → `1.6`. + +## Images and Media + +- `max-width: 100%` is the baseline; `object-fit: cover` for images that need to fill a container at different aspect ratios +- Use `<picture>` for art direction (different crops per viewport), not just different sizes +- `srcset` for resolution switching; browsers handle the choice automatically +- Hero backgrounds at 4K don't belong on mobile — deliver appropriately sized assets + +## Operational Dashboard Note + +For DeepSat-style ISR / operational work: the primary viewport is almost always a large desktop monitor. Mobile is unsupported. Don't pretend otherwise. If mobile is a declared requirement: + +- Prioritize *read-only* scanning over interactive manipulation +- Key metrics first, secondary details collapsed behind interactions +- Assume poor bandwidth + intermittent connectivity — data-sparing matters +- Don't split the canonical desktop layout 1:4 onto mobile tiles — design a separate layout with the same information priorities + +## Smoke Checklist + +- [ ] Primary viewport decided and documented in the rationale +- [ ] Named breakpoints — no magic pixel values in CSS +- [ ] Works at `sm`, `md`, `lg`, `xl` tests (at minimum) +- [ ] Typography scales fluidly or has tuned ramps per breakpoint +- [ ] Images use appropriate sizes per viewport +- [ ] At 200% browser zoom, layout still holds +- [ ] No horizontal scroll (unintentional) on any common viewport diff --git a/frontend-design/references/workflow.md b/frontend-design/references/workflow.md new file mode 100644 index 0000000..bd0f3a5 --- /dev/null +++ b/frontend-design/references/workflow.md @@ -0,0 +1,86 @@ +# Workflow + +Four phases for non-trivial frontend work. Cheap to skip individual phases when context warrants, but don't short-circuit the chain by default. + +## Phase 1 — Intake + +Before coding, understand what's being built and for whom. Ask these, one at a time, multiple-choice where possible. Don't batch. + +**Purpose** +- What is this interface for? (landing page / dashboard / component / marketing site / internal tool / client demo / design exploration / other) +- What problem does it solve? One sentence. + +**Audience** +- Who uses this? (general public / executives / technical users / operators / customers / internal team) +- What's their expected device / context? (desk on a big screen / mobile on the move / constrained environment) + +**Operational context** +- Consumer-facing or operational? (consumer → aesthetic distinctiveness helps; operational → readability + scannability matter more) +- Is there a design system to respect, or is this greenfield? +- Any brand guidelines or existing visual language to match / deliberately depart from? + +**Functional priority** +- Density vs scannability vs delight — which wins when they conflict? +- Read-only, interactive, or input-heavy? + +**Technical constraints** +- Framework / stack (React / Next / Vue / Svelte / vanilla HTML+CSS / static site / other) +- Existing design system (Tailwind / shadcn / custom / none) +- Performance budget (if any) +- Accessibility target (WCAG AA is default; AAA for some contexts) +- Browser support (modern-only OK, or need IE11-style fallbacks?) + +**References** +- Any moodboard links, screenshots, sites you like / dislike? +- Brand color palette, logos, fonts already in use? + +**Success criteria** +- What does "good" look like for this? One-sentence test ("looks professional but not corporate" / "feels like a game" / "hides complexity behind calm surfaces" / etc.) +- How will we know when to stop iterating? + +Stop asking when you can state the goal back in one sentence and the user confirms. + +## Phase 2 — Commitment + +Before writing code, lock the aesthetic direction explicitly. State all of these out loud (in output) so the user can push back before time is spent: + +- **Archetype chosen.** One of: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, or a named variant. +- **Why this archetype fits** the purpose and audience from Phase 1. +- **What's being traded away.** (Maximalism trades subtlety; minimalism trades information density; playful trades gravitas; etc.) +- **Font pairing**, one line. Display + body, both named. Not Inter, Roboto, Arial, or system defaults unless specifically justified. +- **Palette**, one line. 2-3 dominant colors + 1-2 sharp accents. Not "purple gradient on white." +- **Motion philosophy**, one line. ("Staggered page-load reveal, subtle hover states, no scroll-jacking" or "no motion — stillness and typography do the work" or "aggressive hover interactions — this is supposed to feel alive.") +- **Layout approach**, one line. (Asymmetric grid / classic 12-col / brutalist stack / magazine spreads / whatever fits the archetype.) + +**If the user pushes back**, revise before building. Cheaper to pivot now than after implementation. + +## Phase 3 — Build + +With the commitment locked, implement. The aesthetic guidance in `../SKILL.md` is the main reference for taste decisions. + +**Layout-significant work?** Load [responsive.md](responsive.md) and plan the breakpoint strategy *before* committing to a primary viewport layout. + +**Interactive components (forms, dialogs, menus, complex controls)?** Load [accessibility.md](accessibility.md) and apply the discipline during build, not as a retrofit. + +**Match implementation complexity to aesthetic vision.** Maximalism needs elaborate code (layered animations, custom cursors, grain overlays, scroll effects). Minimalism needs precision (impeccable spacing, considered typography scale, restraint in color). Don't build the wrong kind of effort. + +## Phase 4 — Review + +Before handoff, self-audit. Load [design-review.md](design-review.md) and walk the checklist: + +- Did the build hit the chosen archetype? +- Any AI-slop defaults slip back in? (Inter, purple-on-white, predictable card layouts, etc.) +- Accessibility smoke check (contrast, keyboard, focus, reduced-motion) +- Responsive smoke check (does the aesthetic translate to mobile?) +- Does the code quality match the aesthetic? (Lazy code under ornate design is a failure.) + +Emit a `design-rationale.md` using [rationale-template.md](rationale-template.md) so the next iteration or the next engineer has context for the choices made. + +## When to skip phases + +- **One-line style tweak** ("change the heading color to match the brand"): skip phases 1, 2, 4. Just apply the change. +- **Refactoring existing code without design changes**: not this skill — use the general refactor skill. +- **Bug fix in existing design**: skip phase 1 (context is already there) and phase 2 (don't pivot the archetype for a bug fix). Build and review. +- **Complete rebuild / new design**: don't skip any phase. + +The discipline is there to prevent bad decisions at speed. Skipping for genuinely trivial work is fine; skipping because "it's faster" on non-trivial work is how AI slop wins. |
