# Aesthetic Directions

Named profiles to commit to before generating design code. Pick one, or propose a new profile with the same level of depth. The point is to decide **before** writing code, so every subsequent choice (font, radius, shadow, spacing, motion) derives from a single intention instead of converging on defaults.

**Rule**: State the chosen direction at the top of every output. Do not mix directions in the same artefact. Do not repeat the same direction twice in a row unless the user pins it.

---

## Profile: editorial-magazine

The feel of a printed quarterly. Long-form, confident typography. Grid-based but asymmetric. Rule lines and number-prefixed sections do the work that icons and shadows would do elsewhere. Warm paper background, ink-dark body, one saturated accent for emphasis.

**Typography**
- Display: **Fraunces** — variable serif, crank the OPSZ axis up for headlines
- Body: **Newsreader** — warm serif, optimised for long reading
- Label / metadata: **JetBrains Mono** at 11px, letter-spacing 0.2em, uppercase
- Import: `@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght,SOFT@9..144,300..900,0..100&family=Newsreader:ital,opsz,wght@0,6..72,200..800;1,6..72,200..800&family=JetBrains+Mono:wght@400;500&display=swap');`
- Scale: major third (1.25). Base 18px, display up to 96px.
- Leading: body 1.6, display 0.95
- Drop caps on feature openers. `initial-letter: 3` with serif family.

**Palette**
- Paper: `oklch(97% 0.015 80)` — warm off-white, not pure white
- Ink: `oklch(18% 0.02 40)` — deep brown-black, never #000
- Accent: `oklch(48% 0.16 25)` — terracotta, used on one italic word per headline and on pull-quotes
- Rule: `oklch(25% 0.04 40)` — for hairlines
- Neutrals (9-step): oklch(L 0.02 40) where L ∈ {97, 92, 86, 78, 60, 45, 32, 22, 14}
- Semantic: success `oklch(50% 0.12 145)`, warning `oklch(65% 0.15 60)`, danger `oklch(45% 0.18 25)`

**Spacing**
- Base: 4px. Scale: 4, 8, 12, 16, 24, 40, 64, 96, 160
- Column gap: 24px on 12-col grid
- Body measure: 62ch max
- Section separations: 96-160px, never the same as inner padding

**Radii + borders**
- Radius: 0 on containers. 2px on inputs. No rounded cards.
- Border: hairlines at 1px in ink. Accent rules at 2px.
- Shadows: none. Depth comes from rules and spacing.

**Motion**
- Duration: 320ms for enters, 200ms for exits
- Easing: `cubic-bezier(0.2, 0.8, 0.2, 1)` — quart-out
- Page load: stagger display-text words by 40ms
- Hover: no motion on body, 1px ink underline slides in under links

**Signature moves**
1. Drop caps on feature openers (3-line initial, serif, accent colour)
2. Number-prefixed sections: `01` in mono, section title in serif, 24px gap, 1px rule above
3. Italic emphasis word in headlines, in accent colour, carrying the whole mood

**Avoid block**
- Gradients (any kind, any place)
- Rounded cards
- Drop shadows
- Inter, Roboto, or any geometric sans for body
- Icon chips above headings
- Centered headlines longer than 3 words

---

## Profile: swiss-modernist

The feel of Müller-Brockmann, Vignelli, early Helvetica Now specimens. Objective, flush-left, grid-rigorous. Colour used sparingly as a signalling layer, not as decoration. Every element sits on a 12-column grid. Negative space is a first-class element.

**Typography**
- Display + body: **Neue Haas Grotesk Display** (or **Inter Display** as fallback — acceptable here, as it is the single direction where geometric sans is the point). Paid: Neue Haas. Free substitute: **IBM Plex Sans**.
- Mono: **IBM Plex Mono**
- Import (free): `@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;700&family=IBM+Plex+Mono:wght@400;500&display=swap');`
- Scale: perfect fourth (1.333). Base 16px. Display 64px max — restraint.
- Leading: body 1.5, display 1.05
- Tracking: headlines at -0.02em, body at 0, labels uppercase with 0.08em

**Palette**
- Paper: `oklch(99% 0 0)` — near-pure white, tinted imperceptibly warm
- Ink: `oklch(15% 0 0)` — near-black, slightly cool
- Accent: `oklch(55% 0.22 28)` — signal red, used on one element per screen
- Neutral 9-step: oklch(L 0 0) where L ∈ {99, 94, 88, 80, 65, 50, 35, 22, 12}
- No other hues. Red is the only colour.

**Spacing**
- Base: 8px. Scale strictly 8, 16, 24, 32, 48, 64, 96, 128
- 12-column grid, 24px gutter
- Baseline grid: 8px. All vertical rhythm snaps to it.

**Radii + borders**
- Radius: 0 everywhere. No exceptions.
- Border: 1px in ink on dividers. 2px signal-red for emphasis.
- Shadows: none.

**Motion**
- Duration: 180ms
- Easing: `cubic-bezier(0.4, 0, 0.2, 1)` — material standard
- Instant, precise, no overshoot
- Prefers-reduced-motion disables all transitions

**Signature moves**
1. Flush-left headlines, never centered, ragged right
2. Metadata in uppercase mono at 11px, tracked 0.08em
3. Signal red on one element per viewport — a section marker, an underlined verb, a rule

**Avoid block**
- Gradients
- Decorative colour
- Radii
- Any serif
- Centered text
- Icon illustrations (use typographic marks instead)

---

## Profile: brutalist-raw

The feel of Are.na, early Craigslist, Jenny Odell's archival sites. Browser defaults as aesthetic choice. No styling is a statement. Dense information, hard edges, documentary tone. Black on grey-white, maybe one crude colour.

**Typography**
- Display + body: **Times New Roman** or **Helvetica** — system fonts, no import
- Alternative: **Libre Caslon Text** (Google) for more character while staying raw
- Import (if used): `@import url('https://fonts.googleapis.com/css2?family=Libre+Caslon+Text:ital,wght@0,400;0,700;1,400&display=swap');`
- Scale: no scale. H1 at 2em, H2 at 1.5em, body at 1em. Browser defaults.
- Leading: 1.4 body, 1.1 headlines
- Underlined links in default blue acceptable; or all-black links with underline

**Palette**
- Background: `oklch(95% 0 0)` — newsprint grey-white
- Ink: `#000` — here, pure black is allowed because rawness is the point
- Optional accent: `oklch(55% 0.22 28)` red, or a sickly `oklch(75% 0.15 100)` yellow
- No other colours.

**Spacing**
- No scale. Default margins on paragraphs (1em top/bottom).
- Max-width on body: 66ch
- Layouts use HTML tables, dl/dt/dd, fieldsets

**Radii + borders**
- Radius: 0
- Border: 1-3px solid black on tables, fieldsets, images
- Shadows: none

**Motion**
- None. No transitions. Instant state changes. This is a document.

**Signature moves**
1. HTML tables used as layout, visibly
2. `<fieldset>` and `<legend>` used for grouping, unstyled or minimally styled
3. Images with thick black borders, no cropping, captions below in italic

**Avoid block**
- Any custom font beyond system/Caslon
- Radii
- Shadows
- Animation of any kind
- Grid systems, cards, or containers
- Colour beyond the single allowed accent

---

## Profile: neo-brutalist-playful

The feel of Gumroad (2022), Figma community covers, Linear's earliest pages. Thick borders, flat shadow offsets, chunky type, saturated colour blocks. Confident, slightly toy-like, high-contrast.

**Typography**
- Display: **Space Grotesk** at 600-700 weight
- Body: **Space Grotesk** at 400-500
- Mono accent: **Space Mono**
- Import: `@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Space+Mono:wght@400;700&display=swap');`
- Scale: major third (1.25). Base 16px. Display to 72px.
- Leading: body 1.5, display 1.0
- Tracking: headlines -0.01em, no letter-spacing on labels

**Palette**
- Paper: `oklch(97% 0.02 100)` — warm cream
- Ink: `oklch(15% 0.02 280)` — blue-black
- Primary: `oklch(72% 0.20 145)` — electric green
- Secondary: `oklch(70% 0.22 30)` — tomato red
- Tertiary: `oklch(85% 0.18 80)` — marigold
- Use 2-3 primaries per composition. High saturation.

**Spacing**
- Base: 4px. Scale 4, 8, 16, 24, 32, 48, 64
- Comfortable padding on cards: 24-32px

**Radii + borders**
- Radius: 12-24px on cards, 999px on pills — consistent within a composition
- Border: 3-4px solid ink on every container
- Shadow: hard offset `8px 8px 0 oklch(15% 0.02 280)`. No blur, no alpha.

**Motion**
- Duration: 150ms
- Easing: `cubic-bezier(0.4, 0, 0.2, 1)`
- Hover: translate card by `-2px -2px` and increase shadow to `10px 10px 0`, giving a lift without blur
- Active: reset translate, shadow to `4px 4px 0` — the button is "pressed"

**Signature moves**
1. Hard offset shadow that animates on hover/active — the interface has physical weight
2. Two saturated colours clashing deliberately (green and red; red and yellow)
3. Chunky pills for CTAs with thick ink border and offset shadow

**Avoid block**
- Soft shadows (any blur above 0)
- Low-saturation palettes
- Gradients
- Subtle — this direction is loud or it is nothing
- Serif body text

---

## Profile: luxury-refined

The feel of high-end restaurants, Aesop, Loro Piana, The New York Times T magazine covers. Enormous whitespace, a hairline rule instead of a border, a restrained palette of one warm neutral + ink + a single metallic accent. Quiet confidence.

**Typography**
- Display: **Playfair Display** at 400, weight pulled up only on pull-quotes
- Body: **Inter** at 380-420 weight, used sparingly — this is the one direction where Inter is acceptable because it acts as a foil to the serif
- Accent: **Playfair Display Italic** for pull-quotes
- Import: `@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Playfair+Display:ital,wght@0,400;0,500;0,700;1,400;1,500&display=swap');`
- Scale: minor third (1.2). Base 16px, display to 80px.
- Leading: body 1.7, display 1.0
- Tracking: display -0.01em, labels uppercase with 0.25em

**Palette**
- Paper: `oklch(96% 0.01 90)` — cream
- Ink: `oklch(20% 0.01 40)` — soft black with warmth
- Accent: `oklch(65% 0.10 80)` — antique gold, used hairline-thin
- Neutral: oklch(L 0.01 90) where L ∈ {96, 92, 86, 78, 62, 42, 28, 20}

**Spacing**
- Base: 8px. Scale 8, 16, 24, 40, 64, 96, 160, 240
- Minimum margin around hero content: 96px
- Body measure: 58ch
- Sections separated by 160-240px of pure white

**Radii + borders**
- Radius: 0 on cards. 2px on inputs only.
- Border: 1px hairlines in ink for dividers. 0.5px acceptable if rendering permits.
- Shadow: none

**Motion**
- Duration: 600-800ms for entrances — luxury is slow
- Easing: `cubic-bezier(0.16, 1, 0.3, 1)` — expo-out
- Page load: each element fades in at 80ms stagger
- No hover translate. Hover = faint underline in gold, appears over 400ms.

**Signature moves**
1. Enormous negative space around the hero — 240px above and below
2. Single gold hairline between sections, 1px, centered
3. Italic pull-quote in Playfair, set in gold, hanging in the margin

**Avoid block**
- Any saturated colour
- Shadows (any)
- Icons (use text and rules instead)
- Hurried motion — anything under 400ms
- Multiple accent colours

---

## Profile: organic-warm

The feel of small-batch food brands, ceramics studios, regenerative-agriculture sites. Soft, irregular, hand-made. Non-uniform border radii, terracotta and moss, hand-drawn SVG accents. Warm but not retro.

**Typography**
- Display: **Söhne Breit** (paid) or **Recoleta** (paid). Free substitute: **DM Serif Display**
- Body: **Söhne** (paid) or **DM Sans** (free)
- Handwriting accent: **Caveat** for one occasional hand-written annotation
- Import (free): `@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..700;1,9..40,300..700&family=DM+Serif+Display&family=Caveat:wght@400;500&display=swap');`
- Scale: major second (1.125) — gentle, close ratios
- Leading: body 1.7, display 1.1
- Tracking: 0 everywhere, no uppercase labels

**Palette**
- Paper: `oklch(95% 0.03 85)` — cream with pink undertone
- Ink: `oklch(25% 0.05 40)` — earthy brown
- Terracotta: `oklch(60% 0.14 35)`
- Sand: `oklch(82% 0.06 75)`
- Moss: `oklch(45% 0.08 145)`
- Sky: `oklch(72% 0.06 220)` — dusty blue

**Spacing**
- Base: 4px. Scale 4, 8, 12, 20, 32, 52, 84 — Fibonacci-ish, not geometric
- Content feels loose, not rigid

**Radii + borders**
- Radius: irregular. e.g. `border-radius: 24px 48px 32px 40px` on cards — every corner different
- Or: `border-radius: 64% 36% 55% 45% / 40% 50% 50% 60%` for organic blob containers
- Border: 1-2px in ink or terracotta, optional
- Shadow: soft, short. `0 2px 8px -4px oklch(40% 0.05 40 / 0.15)`

**Motion**
- Duration: 400ms
- Easing: `cubic-bezier(0.34, 1.2, 0.64, 1)` — gentle overshoot, a single degree of bounce (not elastic)
- Hover: slight rotate, 1-2deg

**Signature moves**
1. Asymmetric border-radius on every card — no two corners equal
2. Hand-drawn SVG accents: wavy underlines, circular annotations in Caveat
3. Slight rotation (1-3deg) on images in a gallery — arranged like prints pinned to a wall

**Avoid block**
- Geometric perfection
- Gradients
- Dark mode
- Any sans-serif that feels technical (Inter, Roboto, IBM Plex)
- Hard shadows

---

## Profile: retro-futurist

The feel of Winamp, early Kraftwerk covers, vaporwave re-imagined for 2025. CRT bloom, scanline overlay, bitmap fonts for display, monospace for everything else. Orange, cyan, magenta on deep not-quite-black. This is the **one** direction where cyan-on-dark is earned.

**Typography**
- Display: **VT323** or **Press Start 2P** — bitmap, pixelated
- Body: **Space Mono** or **JetBrains Mono**
- Labels: **Space Mono** uppercase, tracked 0.1em
- Import: `@import url('https://fonts.googleapis.com/css2?family=VT323&family=Space+Mono:ital,wght@0,400;0,700;1,400&family=Press+Start+2P&display=swap');`
- Scale: perfect fourth (1.333). Base 14px — smaller, denser.
- Leading: 1.4 body, 1.0 display
- No kerning adjustments — pixelated fonts fight them

**Palette**
- Background: `oklch(15% 0.02 280)` — inky blue-black, not pure
- Cyan: `oklch(80% 0.15 200)` — bright but pushed slightly toward teal
- Orange: `oklch(75% 0.18 55)` — safety orange
- Magenta: `oklch(65% 0.25 340)` — hot pink
- Foreground text: `oklch(92% 0.02 80)` — off-white

**Spacing**
- Base: 8px (matches pixel grid)
- Scale 8, 16, 24, 32, 48, 64
- All measurements multiples of 8 — CRT-era pixel discipline

**Radii + borders**
- Radius: 0 or 2px max — pixels don't bevel
- Border: 2px solid in accent colour
- Shadow: replaced by CRT glow. `box-shadow: 0 0 12px oklch(80% 0.15 200 / 0.6)` on accented elements.

**Motion**
- Duration: 80-120ms — arcade-fast
- Easing: `steps(4, end)` — stepped, not smooth
- Hover: colour flip (cyan → magenta), instant
- Optional: scanline overlay as a `linear-gradient` with 2px stripes, low opacity, `pointer-events: none` fixed layer

**Signature moves**
1. Scanline overlay across the whole viewport, 2px stripes at 4% opacity
2. Glow shadow on primary text — the CRT bloom
3. Stepped transitions — no smooth eases, everything snaps

**Avoid block**
- Serif typography
- Smooth cubic-bezier eases
- Soft pastel palettes
- Modern drop shadows (use glow instead)
- Warm off-white backgrounds (this direction lives in deep blue)

---

## Profile: soft-pastel

The feel of Notion's marketing site (circa 2022), Stripe's illustrations, Linear's empty states. Airy, pastel, friendly without being infantile. Generous whitespace, pastel oklch values, thin outlines, rounded-but-not-pill.

**Typography**
- Display: **Fraunces** at 400-500, SOFT axis turned up
- Body: **Cabinet Grotesk** (paid) or **Figtree** (free)
- Import: `@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght,SOFT@9..144,400..600,50..100&family=Figtree:wght@400;500;600&display=swap');`
- Scale: minor third (1.2). Base 17px. Display to 64px.
- Leading: body 1.65, display 1.1
- Tracking: 0, never uppercase

**Palette**
- Paper: `oklch(98% 0.02 280)` — palest lavender-white
- Ink: `oklch(30% 0.04 280)` — soft dark lilac, not black
- Primary pastel: `oklch(88% 0.05 150)` — mint
- Secondary pastel: `oklch(88% 0.06 40)` — peach
- Tertiary: `oklch(88% 0.06 260)` — periwinkle
- Accent (for CTAs only): `oklch(60% 0.15 310)` — soft violet

**Spacing**
- Base: 4px. Scale 4, 8, 12, 20, 32, 52, 84, 128
- Loose — whitespace is the texture

**Radii + borders**
- Radius: 12-16px on cards. 24px on larger containers. 8px on inputs.
- Border: 1px in oklch neutral, or no border with pastel fill
- Shadow: very soft. `0 1px 2px oklch(30% 0.04 280 / 0.04), 0 8px 24px -8px oklch(30% 0.04 280 / 0.08)`

**Motion**
- Duration: 280ms
- Easing: `cubic-bezier(0.22, 1, 0.36, 1)` — gentle quart-out
- Hover: scale `1.01`, shadow slightly denser
- Entrances: fade-up 8px, 280ms

**Signature moves**
1. Pastel card fills with no border — colour is the edge
2. Illustrated empty states in the same pastel palette, simple geometric shapes
3. Serif display over sans body — soft but not fluffy

**Avoid block**
- Saturated colour
- Dark mode
- Gradients (use flat pastels instead)
- Hard shadows
- Thick borders
- Pill radii (999px) — too toy-like for this direction

---

## When to propose a new direction

If none of the eight above fits the brief, propose a new named profile in the same format. Every field — typography, palette, spacing, radii, motion, signature moves, avoid block — must be answered. A new direction without an `Avoid block` is an incomplete direction.

The `avoid` section is the most important. It is what prevents the direction from drifting back into generic AI output mid-implementation.
