--- name: frontend-design description: > WellForge visual direction — choosing palette, typography, layout and the one signature element deliberately, instead of the look every project in the stack gets by default. Use when designing a NEW product surface (a greenfield first UI, a landing/marketing/public page, a standalone prototype or demo), when reshaping an existing UI on purpose, or when the user asks for "personality", "a visual identity", or something that "doesn't look AI-generated". Do NOT use to add a feature inside a project that already has a design system — there the system wins. Authoritative for the surface-class gate, the two-pass token system, the anti-default calibration list, the contrast/motion floor, and how direction lands in design.md and the theme (never ad-hoc CSS). --- # Frontend design — visual direction, gated Everything else in WellForge pushes toward **sameness**, on purpose: reuse the component library, match the surrounding code, never introduce a second UI library. That is correct for the internal apps most of the pipeline builds, and wrong exactly when the surface *is* the product — a landing page, a first impression, a demo someone decides on in eight seconds. This skill is the narrow escape hatch. It is not a licence to redecorate: it applies to a specific class of surface, produces a **token system** decided before any code, and hands that system to frontend-dev to implement as **theme tokens**. Sameness stays the default; this is the documented exception. ## The surface-class gate — run this first, state the result | Surface | Verdict | What you do | |---|---|---| | A feature inside a project that already has a theme (every **adopted**/brownfield project, every scaffold past its first UI) | **The system wins** | Apply it well. No new palette, no new type pairing, no new radius scale. Reuse components, use existing tokens, add nothing to the token set. Read only the *Quality floor* and *CSS pitfalls* below, then go back to the designer's normal flow. | | A new **public-facing** area of an existing product (first landing page, marketing site, docs shell, a new product line) | **Extend, don't restart** | Inherit the existing type system and neutral scale. You get **one** new axis — usually an accent plus the signature element. State what you inherited and what you changed. | | A greenfield project's first UI, a standalone prototype, a demo or artifact whose whole job is impression | **Full direction** | The two-pass process below. | Ambiguous? **Ask** — same rule as discovering the component library: never resolve ambiguity by defaulting. And there is no path where distinctiveness beats a stated brief: **where the user or the spec pins an axis down, that wins**, including when it asks for one of the defaults listed below. ## Rigor tiers Per [`rigor-tiers`](../rigor-tiers/SKILL.md): `production`/`mvp` run the designer, so both passes run there. `spike` never spawns the designer — but the main loop may load this skill when the spike's *whole point* is a visual prototype. In that case run **pass 1 only**: name the tokens, skip the critique round and the evidence log, mark it `// SPIKE:` and move. ## Pass 1 — the token system, before any code Four named things. No prose designs, no "modern and clean" — every entry is a value someone can implement or argue with. - **Color** — 4–6 named hex values (`ink`, `paper`, `signal`, …), each with the job it does. Not "a palette generated from a hue"; roles first, then values. - **Type** — the faces for 2+ roles: a characterful **display** face used with restraint, a **body** face that complements rather than echoes it, and a **utility** face if there is data or captions. Name the scale, weights and tracking. **State the delivery mechanism** per face — self-hosted (`@fontsource/*` or a local `woff2`) or a system stack. A CDN `` is not a delivery mechanism in a project with a CSP or an offline build; check before you choose a face you cannot ship. - **Layout** — one sentence of prose plus an ASCII wireframe. Compare two before picking one. - **Signature** — the single element this page is remembered by, and why it belongs to *this* subject. One. Everything around it stays quiet. Ground it in the actual subject. The spec's domain — its materials, artifacts, vocabulary, the shape of its data — is where non-generic choices come from. If the spec doesn't pin the subject down enough to design from, name the subject, its audience and the page's single job yourself, and say that you did. ## Pass 2 — critique the plan, then write code Review the token system against the brief **before** implementing. The test: *would this plan come out roughly identical for a different brief in the same stack?* If yes, it is a default wearing a plan's clothes — revise it and say what you changed and why. Three looks currently dominate AI-generated design; all are legitimate for some briefs, and none of them should be where you spend a free axis: 1. Warm cream background (~`#F4F1EA`), high-contrast serif display, terracotta accent. 2. Near-black background, one bright acid-green or vermilion accent. 3. Broadsheet layout: hairline rules, zero border-radius, dense newspaper columns. WellForge has a **fourth** default, and it is ours: untouched Mantine plus Tailwind's slate/indigo, `rounded-md`, `shadow-sm`, a stat row with a gradient number. It is the right answer for an internal admin screen and a non-answer for a product surface. Recognise it when you produce it. Also question structural devices that only *look* like information: numbered eyebrows (01 / 02 / 03) earn their place when the content genuinely is an ordered sequence and the order matters to the reader — otherwise they are decoration with a monospace font. Same for motion: one orchestrated moment beats scattered effects, and scattered effects are themselves a tell. Match execution to ambition — maximalist directions need elaborate follow-through, minimal ones need precision in spacing and type. Then remove one accessory before you ship. ## Where it lands The durable artifact is a section in `design.md`, between **Component inventory** and **Accessibility** ([`spec-driven`](../spec-driven/SKILL.md) format): ```markdown ## Visual direction | Token | Value | Job | |---|---|---| | `--color-ink` | `#…` | body text, rules | | … | | | Type: / / ; scale <…> Layout: Signature: Risk: ``` Then, at implementation time: - **frontend-dev implements this as theme configuration** — Mantine `createTheme` / CSS custom properties / the Tailwind theme extension — *never* as hex literals inside components. A token used by exactly one component is a smell: promote it or delete it. - Mockups, and the directions you tried and rejected, go under `.forge/design//` alongside the [`visual-companion`](../visual-companion/SKILL.md) evidence. That directory is **gitignored** in the templates — it is scratch, not the record. If a rejected direction matters, it belongs in the `Risk:` line, not only in the scratch dir. ## Quality floor — checkable, not aspirational - **Contrast: compute it, don't eyeball it.** Every text/background pair the palette allows must clear 4.5:1 (3:1 for ≥24px text and for UI boundaries). A palette that hasn't been checked isn't finished. This is the visual half of design.md's **Accessibility** section — it does not replace it. - **Focus is visible.** Replacing the default focus ring is fine; replacing it with something *less* visible is a defect. A custom ring must survive both the light and dark palette. - **Reduced motion is honoured by media query**, not by restraint. `prefers-reduced-motion: reduce` kills or shortens every non-essential transition. - **Responsive to 360px.** The signature element degrades gracefully or is dropped at small widths — it never causes horizontal scroll. ## CSS pitfalls in this stack - Watch selector specificity between section-level classes and element-level ones — the classic symptom is section padding that silently cancels out. - In Mantine + Tailwind the recurring bug is a Tailwind utility losing to Mantine's own styles. Fix it through the theme, `styles`/`classNames` props, or `Box` — not with a wall of `!important`. ## What this skill does NOT license - No new UI library, no new CSS-in-JS runtime, no font that the project's CSP or build cannot actually deliver ([`react-ts-vite`](../react-ts-vite/SKILL.md) conventions still hold). - No rewriting existing screens because the new direction is nicer — that is a separate feature with its own spec (the drift rule). - The designer still writes no code: this produces the `## Visual direction` section, and frontend-dev implements it.