# Neumorph — Construction Instructions & AI Prompting Guide
> Version 1.0 · Complete decision framework for building with the Neumorph system

---

## Table of Contents

1. [Design Philosophy & Core Rules](#1-design-philosophy--core-rules)
2. [The Two-Font Law](#2-the-two-font-law)
3. [Color Application Rules](#3-color-application-rules)
4. [Border Radius Decision Framework](#4-border-radius-decision-framework)
5. [Background & Surface Rules](#5-background--surface-rules)
6. [Shadow & Elevation Rules](#6-shadow--elevation-rules)
7. [The Blue Accent — When and How](#7-the-blue-accent--when-and-how)
8. [Typography Application Rules](#8-typography-application-rules)
9. [Spacing Construction Rules](#9-spacing-construction-rules)
10. [Component Construction Guides](#10-component-construction-guides)
11. [Interactive States — Full Decision Guide](#11-interactive-states--full-decision-guide)
12. [Layout Construction Rules](#12-layout-construction-rules)
13. [Animation Rules](#13-animation-rules)
14. [What Never to Do — Anti-Pattern List](#14-what-never-to-do--anti-pattern-list)
15. [AI Prompting Instructions](#15-ai-prompting-instructions)
16. [New Project Checklist](#16-new-project-checklist)
17. [Component Pattern Library](#17-component-pattern-library)
18. [Responsive Construction Rules](#18-responsive-construction-rules)
19. [Accessibility Guidelines](#19-accessibility-guidelines)
20. [Common Scenarios — Decision Trees](#20-common-scenarios--decision-trees)

---

## 1. Design Philosophy & Core Rules

### The Fundamental Premise

Neumorph is built on a single technique repeated relentlessly: **every element is carved from the same material using only light and shadow.** There is one background color (`#e0e5ec`) for the entire interface — page, cards, buttons, inputs, table rows. Nothing is a different color from anything else. Depth, hierarchy, and interactivity are communicated exclusively through a dual-shadow pair that simulates a light source from the upper-left.

This is the aesthetic of a beautifully machined physical object — a soft-touch remote control, a bathroom scale, an analog dial — translated into a screen. If you ever reach for a border or a second background color to separate two elements, you have broken the system's central constraint.

---

### The 10 Commandments of This System

**1. There is exactly one background color.**
`#e0e5ec` is used for the page, every card, every button, every input, every table row. Never introduce a second neutral tone — depth comes from shadow, not color.

**2. Every element is either raised or inset — never flat, never bordered.**
Cards, buttons (default), dropdown panels → raised. Inputs, badges, checkboxes, radios, table rows → inset. There is no third state and no `border: 1px solid ...` anywhere in this system.

**3. The shadow pair is always dual-directional and symmetric.**
Dark shadow bottom-right (`#b8c0cc`), light shadow top-left (`#ffffff`), same blur radius and offset magnitude for both. `box-shadow: 9px 9px 18px #b8c0cc, -9px -9px 18px #ffffff` — never a single shadow, never mismatched offsets.

**4. Pressing flips raised to inset.**
Every interactive raised element (buttons, dropdown items) must transition to its inset shadow pair on `:active`, instantly, with no easing overshoot. This is the system's core, non-negotiable interaction signal.

**5. Color-coding lives in text, not in shells.**
Primary/destructive buttons and success/warning/error badges all share the exact same shell (shadow, radius, background) — only the label text color changes. Do not give a "success" badge a green background; give it a green *label* on the same inset shell as every other badge.

**6. Inputs are always inset, buttons are always raised (until pressed).**
This binary distinction is how users subconsciously tell "a well I type into" from "a button I press" without any color or border cues.

**7. Blue is the only saturated accent, used sparingly.**
`#5b8def` (fill) / `#3f63b3` (text) appears only for: toggle "on" state, focus ring, primary button text, active dropdown item text. It never becomes a background fill larger than a toggle thumb.

**8. Table rows are separate inset pills, not ruled lines.**
`border-spacing: 0 8px` with each row independently inset and radius-capped at the ends — never a bordered/striped table.

**9. Quicksand governs more than headings.**
Unlike most systems, the rounded display font extends to buttons and badges — because its soft letterforms visually harmonize with the soft shadow language. Inter is reserved for body copy, inputs, and table content only.

**10. No shadows change color — only their raised/inset direction changes.**
Do not introduce a colored (e.g., blue) shadow anywhere. Every shadow in the system uses the same `#b8c0cc` / `#ffffff` pair, always.

---

## 2. The Two-Font Law

### Category 1: Display / Structural — Quicksand
**Assignment question: Is this a heading, subheading, button label, or badge label?**

If yes → Quicksand, weight 600–700.

- Page hero title: YES → Quicksand 700
- Section heading: YES → Quicksand 600
- Subheading: YES → Quicksand 600
- Button label: YES → Quicksand 600 (this is the system's key deviation from most collections)
- Badge label: YES → Quicksand 700
- Section title (uppercase divider): YES → Quicksand 700
- Input text: NO → Inter
- Body paragraph: NO → Inter

### Category 2: Content — Inter
**Assignment question: Is this body copy, input text, or tabular data?**

If yes → Inter.

- Primary/secondary body text: YES → Inter 400
- Input / textarea value: YES → Inter 400
- Field label: YES → Inter 700 (bold, but still Inter — small labels stay in the body font even at heavier weight)
- Table header / cell: YES → Inter

### Font Decision Flowchart

```
Is it a heading, subheading, button label, or badge label? ──YES──► Quicksand, 600–700
        │ NO
        ▼
Default to Inter
```

---

## 3. Color Application Rules

### 3.1 The One-Background Rule

There is a single background hex value for the entire system: `#e0e5ec`. Apply it to:
- `body` / page container
- `.nm-raised` (cards)
- `.nm-inset` (wells)
- `.btn` (all button variants)
- `.input`
- Table cells

**Never** introduce a second neutral background — no "off-white card on grey page." If you need to differentiate two elements, change their shadow direction (raised vs. inset), not their fill color.

### 3.2 Blue Accent Usage Rules

Use blue in exactly these contexts:

1. **Toggle "on" fill** — `background: #5b8def`
2. **Focus ring** — `box-shadow: ..., 0 0 0 3px rgba(91,141,239,0.3)`
3. **Primary button text** — `color: #3f63b3` (text only, shell unchanged)
4. **Active dropdown item text** — `color: #3f63b3`
5. **Subheading text** — `color: #5b8def`

**Never:**
- Blue as a card or page background
- Blue as a button/badge shell background (only the toggle track gets a solid blue fill)
- A second saturated accent hue anywhere in the system

### 3.3 Text Color Assignment

| Priority | Color | Examples |
|----------|-------|----------|
| Highest | `#3c4759` | Headings, primary values, body text |
| Medium | `#4a5568` | Section headings |
| Low | `#5b6478` | Section titles, field labels |
| Lowest | `#7a8499` | Secondary/caption text |
| Disabled | `#a3acbd` | Greyed-out states |
| Accent | `#3f63b3` | Primary button/link text |
| Destructive | `#c0392b` | Destructive button/link text |

### 3.4 Semantic Color Rules

Semantic colors are muted, low-saturation, and applied to **text only** on top of the standard inset badge shell:
- Success text `#2f9e63`, Warning `#c78a1f`, Error `#c0392b`, Info `#3f63b3`
- The badge shell itself (`box-shadow: var(--shadow-inset-sm)`, `background: #e0e5ec`) never changes between semantic variants

---

## 4. Border Radius Decision Framework

The rule is simple: **radius scales with the size of the raised/inset shape, but nothing is ever fully sharp.**

### Is this a card or raised surface?
→ `border-radius: 18px`

### Is this a button, input, or dropdown item well?
→ `border-radius: 14px` (buttons/inputs), `10px` (dropdown items)

### Is this a dropdown panel?
→ `border-radius: 16px`

### Is this a badge, switch track, or radio?
→ `border-radius: 9999px` — fully circular/pill

### Is this a checkbox?
→ `border-radius: 8px` — the one soft-square exception

### Is this a table cell?
→ End cells get `12px` on their outer corner only; middle cells are `0px` (they form one continuous inset pill per row)

### Quick Reference Table

| Element | Radius |
|---------|--------|
| Card / raised surface | 18px |
| Dropdown panel | 16px |
| Button / input | 14px |
| Dropdown item | 10px |
| Table row end-cap | 12px |
| Checkbox | 8px |
| Badge / switch / radio | 9999px |

---

## 5. Background & Surface Rules

### 5.1 The Flat Material Model

```
Everything: #e0e5ec — page, cards, buttons, inputs, badges, table rows
```

There is no layering model with multiple background tones (unlike most other systems in this collection). This is the single most distinctive constraint of Neumorph — internalize it before building anything.

### 5.2 Raised vs. Inset Decision Rule

```
Is the user meant to press/click it, and is it currently NOT being pressed? → Raised
Is it a container the user reads/types INTO, or is it currently being pressed? → Inset
```

### 5.3 No Borders, Ever

Zero `border` declarations exist anywhere in this system except the two ghost-button variants (outline/dashed), which intentionally break the "molded material" illusion on purpose as a deliberate lower-emphasis treatment.

---

## 6. Shadow & Elevation Rules

### 6.1 The Dual-Shadow Formula

```css
/* Raised */
box-shadow: [offset]px [offset]px [blur]px #b8c0cc, -[offset]px -[offset]px [blur]px #ffffff;

/* Inset */
box-shadow: inset [offset]px [offset]px [blur]px #b8c0cc, inset -[offset]px -[offset]px [blur]px #ffffff;
```

Both shadows in a pair always use the same offset magnitude and blur radius — only the sign (direction) and the `inset` keyword differ.

### 6.2 Elevation and Shadow Pairing

| What You're Building | Shadow |
|---------------------|--------|
| Card (large raised) | `9px 9px 18px / -9px -9px 18px` |
| Button (medium raised) | `6px 6px 12px / -6px -6px 12px` |
| Small control (badge/checkbox, small raised) | `4px 4px 8px / -4px -4px 8px` |
| Input (large inset) | `inset 5px 5px 10px / inset -5px -5px 10px` |
| Badge/checkbox (small inset) | `inset 3px 3px 6px / inset -3px -3px 6px` |

### 6.3 Never Mix Raised and Inset on the Same Element Simultaneously

An element is either fully raised or fully inset at any given moment — never both. The only transition is a full swap between the two states (e.g., button press).

---

## 7. The Blue Accent — When and How

### When to Use Blue

| Use It | Don't Use It |
|--------|--------------|
| Toggle "on" track fill | Card/page backgrounds |
| Focus ring | Badge/button shell backgrounds |
| Primary button/link text | Body copy |
| Subheading text | Table row fills |

### How NOT to Use Blue

- Never as a shell background for buttons/badges (text-color only, per Commandment 5)
- Never paired with a second accent hue
- Never as an ambient shadow color

---

## 8. Typography Application Rules

### 8.1 The Uppercase Section Title Pattern

```
TYPOGRAPHY                          ← Quicksand 700, 12px, uppercase, #5b6478, tracking 0.08em
                                     ← 18px gap before content
[Section content begins]
```

### 8.2 The Header Eyebrow Pattern

```
THEME 10 · SOFT UI                  ← eyebrow, Quicksand 700, tracking 0.14em, uppercase, #5b8def
Neu·morph                           ← title, Quicksand 700, clamp(28px,4vw,44px), #3c4759, accent word in blue
Quicksand + Inter · radius 18px     ← subtitle, Inter 14.5px, #5b6478
```

### 8.3 Weight as Hierarchy

| Hierarchy Level | Font | Weight | Color |
|-----------------|------|--------|-------|
| Display | Quicksand | 700 | `#3c4759` |
| Section heading | Quicksand | 600 | `#4a5568` |
| Subheading | Quicksand | 600 | `#5b8def` |
| Body | Inter | 400 | `#3c4759` |
| Field label | Inter | 700 | `#5b6478` |
| Secondary/caption | Inter | 400 | `#7a8499` |

---

## 9. Spacing Construction Rules

### 9.1 The Padding Budget for Components

| Component | Padding |
|-----------|---------|
| Badge | 5px vertical, 13px horizontal |
| Input | 12px vertical, 16px horizontal |
| Button | 12px vertical, 24px horizontal |
| Card (standard) | 28px vertical, 32px horizontal |
| Card (header) | 32px vertical, 36px horizontal |
| Table cell | 14px vertical, 16px horizontal |
| Dropdown item | 10px vertical, 12px horizontal |

### 9.2 Vertical Rhythm in Forms

```
[Field Label — Inter 11.5px bold, #5b6478]
         ↕ 7px
[Input — inset well, 14px radius]
         ↕ 14–16px (between field groups)
[Next Field Label]
```

### 9.3 Card Gap Rhythm

Cards need a minimum `20px` gap in grid layouts — since there's no color/border boundary, insufficient spacing causes adjacent card shadows to visually bleed into each other.

---

## 10. Component Construction Guides

### 10.1 How to Build a Card — Step by Step

**Step 1: Container** — `#e0e5ec` background, `border-radius: 18px`, `box-shadow: 9px 9px 18px #b8c0cc, -9px -9px 18px #ffffff`, `padding: 28px 32px`

**Step 2: Section title** — Quicksand 700, 12px, uppercase, `#5b6478`, tracking `0.08em`, margin-bottom `18px`

**Step 3: Content** — body text Inter 400, `#3c4759`. Never add a border or a differently-colored inner block — nest another raised or inset shape instead if you need to show internal structure.

### 10.2 How to Build a Button — Step by Step

**Step 1: Shell** — `#e0e5ec` background, `border-radius: 14px`, `padding: 12px 24px`, raised medium shadow

**Step 2: Pick the text color for the variant** — default: `#3c4759`; primary: `#3f63b3`; destructive: `#c0392b`

**Step 3: Outline/dashed variants** — drop the shadow entirely, add a `1.5px solid/dashed` border instead (the deliberate non-molded exception)

**Step 4: Press state** — swap `box-shadow` to the inset-sm pair on `:active`, revert immediately on release

### 10.3 How to Build an Input — Step by Step

**Step 1: Shell** — `#e0e5ec` background, no border, `border-radius: 14px`, `padding: 12px 16px`, inset-lg shadow (always inset, never raised)

**Step 2: Focus** — keep the inset shadow, append a `0 0 0 3px rgba(91,141,239,0.3)` ring as a third box-shadow layer

**Step 3: Variants** — textarea adds `resize:vertical`; disabled sets `opacity:0.5` on the whole element

### 10.4 How to Build a Toggle — Step by Step

**Step 1: Track (off)** — `44px × 26px`, `border-radius: 9999px`, `#e0e5ec` background, inset-sm shadow

**Step 2: Track (on)** — background flips to `#5b8def`, shadow flips to raised-sm (filled tracks read as raised, not inset)

**Step 3: Thumb** — `20px × 20px` circle, `#e0e5ec` background, raised-sm shadow, `translateX(18px)` when on

---

## 11. Interactive States — Full Decision Guide

### 11.1 Button States

- Default: `box-shadow: var(--shadow-raised-md)`
- Hover: unchanged shadow (Neumorph does not use hover-shadow changes — the material doesn't "glow")
- Active/Pressed: `box-shadow: var(--shadow-inset-sm)` — the core interaction
- Disabled: `opacity: 0.5`, shadow unchanged

### 11.2 Input Focus

```css
.input:focus {
  box-shadow: var(--shadow-inset-lg), 0 0 0 3px rgba(91,141,239,0.3);
}
```

The inset shadow never disappears on focus — the ring is *added* on top, not swapped in.

### 11.3 Dropdown Item Hover

```css
.dropdown-item:hover { box-shadow: var(--shadow-inset-sm); color: #3f63b3; }
```

---

## 12. Layout Construction Rules

### 12.1 Page Layout Model

```css
.page-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px 24px 100px;
}
```

### 12.2 Dashboard Grid Pattern

```css
.layout-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.layout-3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; }
```

---

## 13. Animation Rules

### 13.1 What Can Animate

| Element | Property | Duration | Easing |
|---------|----------|----------|--------|
| Button press | `box-shadow` | 100ms | ease-out |
| Toggle thumb | `transform` | 150ms | ease-out |
| Dropdown/modal entry | `opacity`, `transform` | 250ms | ease-standard |

### 13.2 What Should Not Animate

- Card shadows at rest (only interactive elements transition their shadow)
- Text color changes (instant, no fade)
- Any bounce/spring — motion here mimics a physical press, which is quick and damped, not springy

---

## 14. What Never to Do — Anti-Pattern List

### Typography Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Use Inter for button/badge labels | Quicksand governs buttons and badges in this system |
| Use a third font family | Only Quicksand + Inter exist |

### Color Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Introduce a second background color | Everything shares `#e0e5ec` |
| Give a badge/button variant a colored shell | Color lives in text only |
| Use a colored ambient shadow | Shadows are always `#b8c0cc` / `#ffffff` |

### Border Radius Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Use sharp 0px corners | Minimum radius is 8px (checkbox) |
| Round buttons into full pills | Buttons are `14px`, not `9999px` |

### Structural Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Add a `border` to a card, button, or input | Use raised/inset shadow only |
| Use a single (non-dual) shadow | Always pair dark + light shadows |
| Leave an element in a state that's neither raised nor inset | Every surface must choose one |

---

## 15. AI Prompting Instructions

**System prompt to include:**

> Build this UI using the Neumorph design system.
>
> Core rules:
> — There is exactly one background color for everything: `#e0e5ec` (page, cards, buttons, inputs, table rows).
> — No borders anywhere except the outline/dashed button variants. Depth comes entirely from a dual-directional shadow: dark `#b8c0cc` shadow bottom-right, light `#ffffff` shadow top-left, matched offsets and blur.
> — Every element is either "raised" (buttons default, cards, dropdown panels) or "inset" (inputs, badges, checkboxes, radios, table rows) — never flat, never both.
> — Buttons flip from raised to inset shadow on `:active` (the "press" interaction). This must be present on every clickable element.
> — Border-radius: cards `18px`, buttons/inputs `14px`, dropdown panel `16px`, dropdown items `10px`, badges/switch/radio `9999px`, checkbox `8px`.
> — Primary accent: `#5b8def` (blue) — used ONLY for: toggle-on fill, focus ring, primary/active text color. Never as a shell background.
> — Color-code buttons and badges via TEXT color only (`#3f63b3` primary, `#c0392b` destructive, etc.) — the shell shadow/background never changes between variants.
> — Fonts: Quicksand for headings, subheadings, buttons, and badges. Inter for body copy, inputs, and tables.
> — Table rows use `border-spacing: 0 8px` with each row as its own inset pill, not a bordered/striped list.

---

## 16. New Project Checklist

**Fonts:**
- [ ] Quicksand imported (weights 600, 700)
- [ ] Inter imported (weights 400, 700)

**Colors:**
- [ ] Single `#e0e5ec` background applied everywhere
- [ ] `#5b8def` reserved strictly for toggle-on / focus ring / accent text

**Radius:**
- [ ] Cards at `18px`, buttons/inputs at `14px`
- [ ] Badges/switch/radio at `9999px`, checkbox at `8px`

**Shadows:**
- [ ] Every raised element has the dual dark/light shadow pair
- [ ] Every inset element has the inverted `inset` pair
- [ ] No single shadows, no colored shadows (except focus ring)

**Structure:**
- [ ] No borders except outline/dashed button variants
- [ ] Buttons transition raised → inset on `:active`
- [ ] Badges/buttons color-code via text only

---

## 17. Component Pattern Library

### Pattern: Stat Card (Raised)

```html
<div class="nm-raised" style="padding:24px;">
  <div class="nm-section-title">Usage</div>
  <div style="font-family:'Quicksand';font-size:32px;font-weight:700;color:#3c4759;">84%</div>
</div>
```

### Pattern: Page Header

```html
<div class="nm-raised" style="padding:32px 36px;margin-bottom:32px;">
  <div style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:#5b8def;margin-bottom:10px;">Theme 10 · Soft UI</div>
  <h1 style="font-size:clamp(28px,4vw,44px);font-weight:700;margin:0;color:#3c4759;">Neu<span style="color:#5b8def;">morph</span></h1>
</div>
```

### Pattern: Inset Badge Row

```html
<span class="nm-badge" style="color:#2f9e63;">Success</span>
<span class="nm-badge" style="color:#c78a1f;">Warning</span>
<span class="nm-badge" style="color:#c0392b;">Error</span>
```

---

## 18. Responsive Construction Rules

**Below 480px:**
- Grids collapse to single column
- Card padding reduces from 28–32px to 20px

**480px–1023px:**
- Two-column layouts remain where space allows

**1024px+:**
- Full system at designed specifications

---

## 19. Accessibility Guidelines

### 19.1 Color Contrast Requirements

| Pairing | Notes |
|---------|-------|
| `#3c4759` on `#e0e5ec` | ~7.2:1 — AA/AAA safe |
| `#7a8499` on `#e0e5ec` | ~3.3:1 — borderline; use only for non-essential captions |
| `#3f63b3` on `#e0e5ec` | ~5.8:1 — AA safe for normal text |

**Rules:**
- Because the entire system relies on subtle shadow contrast rather than color contrast, always verify buttons/inputs remain distinguishable in high-contrast / forced-color OS modes — provide a fallback border via `@media (forced-colors: active)`.
- Never rely on shadow direction alone to convey a required/error state — pair inset error badges with the red text color, not shadow changes.

### 19.2 Focus Management

- All interactive elements need `outline: 2px solid #5b8def; outline-offset: 2px;` for `:focus-visible`, since the ambient shadow system alone may not be sufficient for visible focus indication.

---

## 20. Common Scenarios — Decision Trees

### Scenario: "Should this be raised or inset?"

```
Is the user meant to type into it or is it a status readout? ──YES──► Inset
        │ NO
        ▼
Is it currently being pressed? ──YES──► Inset
        │ NO
        ▼
Default: Raised
```

### Scenario: "How do I show a semantic color (success/error/etc.)?"

```
Change the TEXT color only.
Keep the shell (background, radius, shadow) identical to every other badge/button.
```

### Scenario: "What radius do I use?"

```
Is it a badge, switch, or radio? ──YES──► 9999px
        │ NO
        ▼
Is it a checkbox? ──YES──► 8px
        │ NO
        ▼
Is it a button or input? ──YES──► 14px
        │ NO
        ▼
Default: 18px (card)
```

---

*End of Instructions — Neumorph v1.0*
*Design System Document: neumorph-design-system.md*
*Instructions Document: neumorph-instructions.md*
