# Capsule — Construction Instructions & AI Prompting Guide
> Version 1.0 · Complete decision framework for building with the Capsule 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

The Capsule system is built on a single conviction: **form follows fluidity.** Every decision that replaces a sharp corner with a pill, a static surface with a glowing focus state, or a flat badge with a transparency-tinted chip is a deliberate signal that this product is smooth, modern, and engineered with intention. It communicates speed and precision without sacrificing approachability.

This is not rounded-for-the-sake-of-it. It is the aesthetic language of contemporary developer tooling — think GitHub's dark interface, Vercel's deployment dashboard, Linear's project tracker. The dark layered backgrounds, the electric blue accent, the pill-everything philosophy — they all tell the user: *this is powerful, familiar, and built for people who build things.*

---

### The 10 Commandments of This System

**1. Everything is a pill.**  
Buttons, inputs, badges, toggles, status chips, and dropdown triggers all use `border-radius: 9999px`. This is the defining rule. Deviating from it on interactive elements breaks the system's visual identity. The only exceptions are: textareas (`16px`), checkboxes (`4px`), cards (`16px`), modals (`16px–20px`), and table cells (`0px`).

**2. Blue is the only accent.**  
`#58a6ff` is the system's single interactive signal. It appears on: primary button backgrounds, input focus borders/glows, outline button text and border, active link color, and selected/active states. Do not introduce a second accent color. Do not use blue as a background for any container.

**3. Dark layers, not dark flat.**  
The system uses three distinct dark background tones: `#0d1117` (base), `#161b22` (surface), `#21262d` (elevated/hover). These create hierarchy without light. Cards on the page surface, hover states within cards, and active rows in tables are all expressed through these tonal steps — not through color or borders alone.

**4. Outfit for UI, Nunito Sans for display.**  
This is the font law. Outfit handles all interactive UI text — buttons, inputs, labels, body copy, navigation, descriptions. Nunito Sans handles all display — page titles, hero text, and large numerical values. IBM Plex Mono is reserved for code, branch names, and technical identifiers only.

**5. Transparency-tinted status badges.**  
Status colors in the Capsule system are never solid fills. They are always `rgba(color, 0.15)` backgrounds with full-opacity text. This keeps the badge visually connected to the dark surface beneath it, rather than fighting it. Solid badge fills are forbidden.

**6. Blue glow is earned by primary interactions.**  
The `box-shadow: 0 4px 16px rgba(88, 166, 255, 0.25)` glow appears on primary button hover only. It is the system's most distinctive interactive signal. It must not appear on secondary buttons, cards, labels, or any non-primary-button element.

**7. Rounded containers, never squared.**  
Cards and modals in this system use `border-radius: 16px` to `20px`. This is not a gentle rounding — it is a strong, deliberate curve that echoes the pill elements within. Never use `0px` or `4px` radius for container-level elements in this system.

**8. Borders define surfaces.**  
In a dark-mode system, borders are not decorative — they define the boundary between surface layers. Every card and input has `border: 1px solid #30363d`. This 1px rule is non-negotiable. Do not remove it. Do not increase it to 2px except for focused inputs.

**9. No accent lines on containers.**  
Unlike warm or editorial systems, the Capsule system does not use top accent lines on cards or modals. The surface contrast and border system provide sufficient visual definition. Adding colored top-border lines would conflict with the system's clean, uniform dark surfaces.

**10. Motion is purposeful but swift.**  
Transitions are 200ms for state changes, 350ms max for panel/modal entry. The glow shadow on hover has the same 200ms timing. The toggle slide uses 200ms with ease-out. Nothing bounces, pulses, or flashes unless it is a live-status indicator. Speed in motion mirrors the platform's purpose.

---

## 2. The Two-Font Law

This system uses two sans-serif fonts with distinct weight and size roles, plus one monospace font for technical content. Every piece of text belongs to exactly one of three categories:

### Category 1: Display — Nunito Sans
**Assignment question: Is this text a large title, hero heading, or prominent numerical value?**

If yes → Nunito Sans, weight 800–900.

- Page hero title: YES → Nunito Sans 900
- Large section heading: YES → Nunito Sans 800
- Dashboard stat number (e.g., "1,204 deployments"): YES → Nunito Sans 800
- Modal title: NO → use Outfit 700 instead (modals are UI, not display)
- Card heading: NO → Outfit 700
- H4 and below: NO → Outfit

**Nunito Sans is for scale.** When something needs to command attention through size — not through color or decoration — use Nunito Sans at high weight. At smaller sizes, Nunito Sans and Outfit are nearly indistinguishable; use Outfit.

---

### Category 2: UI / Body — Outfit
**Assignment question: Is this text any UI element — button, input, label, nav, description, body copy, or heading below 24px?**

If yes → Outfit.

- Button text: YES → Outfit 700 (primary) / 500 (secondary)
- Input text: YES → Outfit 400
- Input placeholder: YES → Outfit 400
- Field label: YES → Outfit 500
- Section titles (the small uppercase dividers): YES → Outfit 600
- Body paragraph: YES → Outfit 400
- Badge text: YES → Outfit 700
- Navigation items: YES → Outfit 500
- Descriptions under headings: YES → Outfit 400
- Table cell text: YES → Outfit 400
- Table header: YES → Outfit 600
- Dropdown items: YES → Outfit 400
- Modal title (24px, bold): YES → Outfit 700

Outfit is the workhorse of this system. When in doubt, use Outfit.

---

### Category 3: Mono / Technical — IBM Plex Mono
**Assignment question: Is this text a code snippet, branch name, commit hash, command, or technical identifier?**

If yes → IBM Plex Mono.

- Branch name (e.g., `feat/new-ui`): YES → IBM Plex Mono
- Commit hash (e.g., `a3f2c1d`): YES → IBM Plex Mono
- CLI command or code block: YES → IBM Plex Mono
- File path: YES → IBM Plex Mono
- API key or token: YES → IBM Plex Mono
- Version string (e.g., `v2.4.1`): YES → IBM Plex Mono
- Regular label or timestamp: NO → Outfit
- Badge text: NO → Outfit (not mono)

IBM Plex Mono is used sparingly. If the content is not explicitly technical/code, use Outfit.

---

### Font Decision Flowchart

```
Is it a large hero/display title (≥30px, page-level)? ──YES──► Nunito Sans, 800–900
        │ NO
        ▼
Is it any UI element (button, input, label, nav, body, heading <24px)? ──YES──► Outfit
        │ NO
        ▼
Is it code, a branch name, commit hash, or technical identifier? ──YES──► IBM Plex Mono
        │ NO
        ▼
Default to Outfit
```

---

## 3. Color Application Rules

### 3.1 Background Selection Rules

| Surface | Color | Why |
|---------|-------|-----|
| Page body | `#0d1117` | Deepest layer — the base dark |
| Cards / panels | `#161b22` | Surface layer — visually lifted from page |
| Hover fill / nested row | `#21262d` | Elevated layer — active state within a surface |
| Inputs | `#0d1117` | Same as page base — inputs are inset, not raised |
| Modal | `#161b22` | Same as surface — elevated by shadow, not color |
| Table header | `#0d1117` | Slightly sunken vs table body |
| Dropdown panel | `#161b22` | Surface level, bordered |
| Sidebar | `#161b22` | Surface level, persistent |

**Rule:** You have exactly three dark tones. Do not invent a fourth. `#0d1117` is the ground. `#161b22` is one step above. `#21262d` is the hover/active state within a surface. Use them in that order of visual height.

---

### 3.2 Blue Accent Usage Rules

Blue is the interactive signal. Use it in exactly these contexts:

1. **Primary button background** — `#58a6ff` fill with `#0d1117` text
2. **Input focus** — `border-color: #58a6ff` + `box-shadow: 0 0 0 3px rgba(88,166,255,0.15)`
3. **Outline button** — `color: #58a6ff` + `border: 1.5px solid #58a6ff`
4. **Active link / branch name highlight** — `color: #58a6ff`
5. **Info/running badge** — `background: rgba(88,166,255,0.15)` + `color: #58a6ff`

**Allowed, but use with restraint:**
- Blue text on table rows for clickable branch names or links
- Blue counter or number highlight for active items
- Blue dot for live/active status indicator

**Never:**
- Blue as a card or modal background
- Blue text on body copy that is not a link
- Blue gradient fills on surfaces
- Multiple blue elements competing in the same viewport section

---

### 3.3 Text Color Assignment

Always ask: what is the information priority of this text?

| Priority | Color | Examples |
|----------|-------|---------|
| Highest — primary content | `#e6edf3` | Modal titles, headings, values, strong labels |
| High — supporting content | `#c9d1d9` | Descriptions, body copy, nav labels |
| Medium — contextual | `#8b949e` | Field labels, captions, helper text, muted nav |
| Low — metadata, dim | `#484f58` | Section titles (uppercase), timestamps, dim icons |
| Disabled | `#30363d` | Greyed-out states, not meant to be read |
| On accent (blue button) | `#0d1117` | Dark text on bright blue button only |

**Rule:** Never use `#e6edf3` for secondary information. The hierarchy only holds when the color scale is applied consistently. If you reach for a brighter shade to emphasize something, you are undermining every other instance of that shade in the interface.

---

### 3.4 Semantic Color Rules

For success, warning, error, and info states — always apply all three:
- Tinted background at `rgba(color, 0.15)`
- Fully-opaque text in the full semantic color
- Optional: border at `rgba(color, 0.30)`

Never use a semantic color as solid fill on a badge. Never use just text color alone without the background tint. The combination of tinted background + colored text is what makes the status readable against dark surfaces.

---

### 3.5 Purple — The Fifth Semantic Color

This system includes `#bc8cff` (purple) as a non-standard fifth semantic state — used for "Preview", "Beta", "Staging", or ambiguous in-progress states. Apply it with the same transparency rule:

```css
background: rgba(188, 140, 255, 0.15);
color: #bc8cff;
```

Purple should not appear in more than one badge type per interface. If you need more states, use the neutral badge (`#21262d` background, `#8b949e` text, `1px solid #30363d` border).

---

## 4. Border Radius Decision Framework

This is the most distinctive and most commonly misapplied aspect of the system. The rule is simple but absolute: **if it is interactive and small, it is a pill.**

### Is this element a button?
→ `border-radius: 9999px` — no exceptions. All button sizes. All button variants.

### Is this element a text input or select trigger?
→ `border-radius: 9999px` — single-line inputs are always pills.

### Is this a textarea?
→ `border-radius: 16px` — full pill radius on a wide, multi-line element looks wrong. Use `16px` to maintain the rounded character without the excess.

### Is this a badge or status chip?
→ `border-radius: 9999px` — all badges are pills.

### Is this a toggle/switch track?
→ `border-radius: 9999px` — always.

### Is this a card or panel?
→ `border-radius: 16px` — strong rounding, not subtle.

### Is this a modal or dialog?
→ `border-radius: 16px` (standard) or `20px` (large) — must be visibly rounded.

### Is this a dropdown panel?
→ `border-radius: 16px` — matches the pill input that triggered it.

### Is this a checkbox?
→ `border-radius: 4px` — the only square-ish interactive element.

### Is this a table cell?
→ `border-radius: 0px` — cells are always flat.

---

### Quick Reference Table

| Element | Radius |
|---------|--------|
| Button (all sizes) | 9999px |
| Text input | 9999px |
| Textarea | 16px |
| Select / Dropdown trigger | 9999px |
| Badge / chip (all) | 9999px |
| Toggle track | 9999px |
| Radio button | 9999px |
| Checkbox | 4px |
| Card | 16px |
| Modal (standard) | 16px |
| Modal (large) | 20px |
| Dropdown panel | 16px |
| Tooltip | 8px |
| Table container | 8px |
| Table cell | 0px |
| Navigation bar | 0px |
| Floating nav item / tab | 9999px |
| Status pill row | 9999px |
| Progress bar | 9999px |
| Avatar (circular) | 9999px |
| Avatar (square crop) | 8px |

---

## 5. Background & Surface Rules

### 5.1 The Dark Layering Model

Think of the screen as having four tonal layers, each slightly lighter than the one below:

```
Layer 4 (highest): Modals, Dropdowns, Tooltips  → #161b22 (surface) + shadow
Layer 3:           Cards, Panels, Sidebar        → #161b22 (surface)
Layer 2:           Hover / Active fills          → #21262d (elevated)
Layer 1 (lowest):  Page Background               → #0d1117 (base)
```

**Key insight:** Modals and cards use the same `#161b22` background. The modal appears elevated not because it is lighter — but because of its shadow, border, and the darkened overlay behind it. Do not attempt to achieve elevation by lightening the background.

---

### 5.2 Input Background Rule

Inputs use the same `#0d1117` base background as the page. This means the input field recesses into the background — it is "below" the card surface that contains it. The pill border `#30363d` and the focus ring `#58a6ff` provide the input's affordance and definition.

This is different from light-mode systems where inputs are raised above the surface. In Capsule, inputs are sunken below the card surface by sharing the page base color.

---

### 5.3 No Light Surfaces

Do not use any light, white, or off-white background anywhere in this system. There are no cream tones, no white cards, no light-mode exceptions. If a component is built for light mode, it is a separate theme — not the Capsule system. The entire system exists in the dark spectrum.

---

### 5.4 Backdrop Blur Rules

Use backdrop blur for modal overlays only:

```css
.modal-overlay {
  background: rgba(0, 0, 0, 0.50);
  backdrop-filter: blur(4px);
}
```

The blur value is `4px` — lighter than in warm systems, because the dark overlay itself is already visually heavy. A stronger blur would make the UI feel slow or obscure important content behind the modal.

Do not use backdrop blur for tooltips, dropdowns, or navigation elements.

---

### 5.5 When NOT to Use a Background

The following elements should have no background:
- Ghost/text buttons — `background: transparent`
- Section titles (the `UPPERCASE DIVIDERS`) — no background, just text and a bottom border
- Inline labels — no background
- Links within body copy — no background

Adding a background to these elements adds visual noise that fights the system's clean dark surfaces.

---

## 6. Shadow & Elevation Rules

### 6.1 The Dark Mode Shadow Rule

All shadows use pure black. The formula:

```css
rgba(0, 0, 0, [opacity])
```

In dark-mode design, shadows need higher opacity than in light-mode to be perceptible, because the background is already dark. The modal shadow at `rgba(0,0,0,0.70)` is intentionally heavy — this is correct.

---

### 6.2 Elevation and Shadow Pairing

| What You're Building | Shadow to Use |
|---------------------|---------------|
| Flat card on page | `--shadow-card` (2px 8px, 25% opacity) |
| Dropdown or select panel | `--shadow-dropdown` (16px 32px, 50% opacity) |
| Sidebar / persistent panel | `--shadow-md` (8px 24px, 40% opacity) |
| Modal / dialog | `--shadow-modal` (24px 64px, 70% opacity) |
| Toast notification | `--shadow-lg` (16px 40px, 50% opacity) |
| Tooltip | `--shadow-sm` (4px 12px, 30% opacity) |
| Primary button hover | `--shadow-blue-glow` (4px 16px blue radiance) |

---

### 6.3 The Blue Glow — Primary Button Hover Signature

Every primary blue button emits a blue glow on hover:

```css
box-shadow: 0 4px 16px rgba(88, 166, 255, 0.25);
```

This is the Capsule system's signature interactive detail. It must appear on primary button hover and on nothing else. The glow communicates: "this is the primary action, and it is responsive to you."

---

### 6.4 Cards — Border Over Shadow

In most cases, Capsule cards rely on their border (`1px solid #30363d`) rather than shadow for definition. The card background `#161b22` differentiates it from the page `#0d1117` enough to create visual separation.

When a card needs additional lift — for example, in a featured or important position — apply:
```css
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
```

Do not apply shadow and border together for elevation. The border is structural; the shadow is a lift signal. They serve different purposes and can coexist, but should not be used redundantly.

---

### 6.5 Never Use Warm-Toned Shadows

Do not use `rgba(100, 80, 30, ...)`, amber, brown, or any warm-tinted shadow in this system. The Capsule system is cool and dark. All shadows are black-based. Warm shadows would visually conflict with the cool blue accent and dark neutral palette.

---

## 7. The Blue Accent — When and How

The blue accent `#58a6ff` is the interactive signal for this system. Here are the exact rules:

### When to Use Blue

| Use It | Don't Use It |
|--------|-------------|
| Primary button background | Card backgrounds |
| Input focus border | Modal backgrounds |
| Input focus ring (box-shadow) | Section backgrounds |
| Outline button color + border | Decorative elements |
| Active link / navigable text | Body copy text |
| Info/running badge | All other badge types |
| Active nav item indicator | Nav bar background |
| Selected row indicator (subtle) | Table fills |

**Rule:** Every blue element says "this is interactive or this is active." If an element is not interactive and not in an active state, it should not be blue.

---

### How to Apply Focus

The focus state in this system is a two-part signal:

```css
.input:focus {
  border-color: #58a6ff;                          /* border turns blue */
  box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.15); /* soft glow ring */
}
```

Both parts must appear together. The border change alone is too subtle against dark surfaces. The glow ring alone has no precise boundary. Together they create a clear, accessible focus signal.

---

### How NOT to Use Blue

- Never as a surface/background color for cards, sections, or modals
- Never for non-interactive text (labels, descriptions, timestamps)
- Never for destructive or warning states — those have their own semantic colors
- Never for decorative borders on containers

---

## 8. Typography Application Rules

### 8.1 The Section Title Pattern

The most common typographic pattern in this system is the section divider:

```
TYPOGRAPHY                         ← Outfit 600, 10px, uppercase, #484f58, tracking 0.14em
─────────────────────────────      ← 1px border-bottom #21262d, padding-bottom 8px
                                   ← 20px gap before first content
[Section content begins]
```

This pattern appears before every logical section of content within a card. It is a neutral, understated divider — never bold, never colored, never large. The uppercase treatment and extreme letter-spacing do the work.

---

### 8.2 The Header Row Pattern

For page-level headers in this system, the pattern is horizontal, not vertical:

```
[Left: Theme number + Title]      [Right: Metadata badges]
  "04"                             "Radius: ∞" · "Dark Mode" · "Outfit Font"
  "Capsule Design"
```

This is the Capsule page header — the title sits on the left with a small eyebrow number, and the right side holds neutral metadata badges. The title uses a mix: the theme number in muted `#484f58`, the title word in accent blue `#58a6ff`, and the word "Design" in primary white `#e6edf3`.

---

### 8.3 Weight as Hierarchy

Since Outfit and Nunito Sans are both sans-serif, the primary typographic hierarchy tool is weight, not serif/sans contrast. Apply these weights with precision:

| Hierarchy Level | Weight | Color |
|-----------------|--------|-------|
| Display / Hero | 900 | `#e6edf3` |
| Primary heading | 700–800 | `#e6edf3` |
| Subheading | 500–700 | `#c9d1d9` |
| Body copy | 400 | `#8b949e` |
| Section title (small caps) | 600 | `#484f58` |
| Label | 500 | `#8b949e` |
| Caption / timestamp | 300–400 | `#484f58` |

Never use weight 300 for anything that needs to be read clearly. Use it only for timestamps, dim captions, and placeholder-adjacent information.

---

### 8.4 Letter Spacing Rules

| Font & Context | Spacing | Why |
|----------------|---------|-----|
| Nunito Sans display | `-0.02em` to `-0.03em` | Tighter at large sizes = more authority |
| Outfit headings (700) | `-0.01em` | Slight tightening at large sizes |
| Outfit body (400) | `0em` | Default — never touch at reading sizes |
| Outfit button | `0.01em` | Minimal opening for readability at 14px |
| Section titles (uppercase) | `0.14em` | Maximum — creates breathing room |
| Badge text (uppercase) | `0.03em` | Modest opening — maintains pill proportions |
| IBM Plex Mono | `0em` | Default — monospace needs no adjustment |

---

### 8.5 Uppercase Usage

Uppercase text in this system appears in exactly two contexts:
1. **Section titles** — `TYPOGRAPHY`, `BUTTONS`, `COLOR PALETTE` — the 10px Outfit 600 dividers
2. **Badge text** — `DEPLOYED`, `BUILDING`, `FAILED` — status identifiers

Do not uppercase body copy, headings, button text, labels, or nav items. Uppercase in this system means "category header" or "status." Used elsewhere, it reads as shouting.

---

## 9. Spacing Construction Rules

### 9.1 The Padding Budget for Components

Every component has a default "padding budget":

| Component | Padding |
|-----------|---------|
| Badge | 3px vertical, 12px horizontal |
| Form field input (pill) | 10px vertical, 18px horizontal |
| Textarea | 12px vertical, 18px horizontal |
| Button small | 5px vertical, 14px horizontal |
| Button base | 10px vertical, 22px horizontal |
| Button large | 12px vertical, 28px horizontal |
| Card compact | 20px all sides |
| Card standard | 24px all sides |
| Modal standard | 32px all sides |
| Page section | 40px vertical, varies horizontal |
| Sidebar | 24px all sides |
| Status pill row | 8px vertical, 16px horizontal |

**Rule:** Never compress padding to fit more content. The pill shape of inputs and buttons is visually defined by their horizontal padding. Reducing `18px` to `12px` makes pills look like flat rectangles. Maintain the full padding budget.

---

### 9.2 Vertical Rhythm in Forms

When building forms, follow this spacing sequence:

```
[Field Label — Outfit 500, 12px]
         ↕ 6px
[Input — pill, #0d1117 bg, #30363d border]
         ↕ 16px (between field groups)
[Next Field Label]
```

The 6px label-to-input gap is tighter than in editorial systems — this is intentional. The pill input visually "belongs" to its label through proximity. The 16px between field groups provides enough separation to read them as distinct fields.

---

### 9.3 Section Title → Content Sequence

This is the standard vertical sequence within any card section:

```
[Section Title — UPPERCASE, 10px, #484f58, border-bottom]
    ↕ 20px (margin-bottom from section title)
[First content element]
    ↕ 8px–14px (between content items)
[More content]
```

The 20px gap below the section title is mandatory. Never place content immediately after the divider line without this breathing room.

---

### 9.4 Button Group Spacing

When two buttons appear together:

```css
.btn-group {
  display: flex;
  gap: 10px;
}
```

10px is the Capsule system's button gap (vs 12px in editorial systems). The pill shape adds visual padding around buttons that makes them feel more separated than rectangular buttons at the same gap. 10px correctly calibrates this.

In a Cancel + Confirm pair, both buttons are equal width (`flex: 1` each). In this system, the pill buttons are symmetrical by design — there is no visual weight difference between a filled and an outlined pill of the same size, other than color.

---

## 10. Component Construction Guides

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

**Step 1: Overlay**
- Position fixed, full viewport
- Background: `rgba(0, 0, 0, 0.50)` + `backdrop-filter: blur(4px)`
- Z-index: 400

**Step 2: Modal container**
- Background: `#161b22`
- Border: `1px solid #30363d`
- Border-radius: `20px` (large feel) or `16px` (standard)
- Padding: `32px`
- Max-width: `480px`
- Box-shadow: `0 24px 64px rgba(0, 0, 0, 0.70)`
- No accent line — do not add a top colored border

**Step 3: Modal header**
- Title: Outfit 700, `20px`, `#e6edf3`
- Margin-bottom on title: `6px`

**Step 4: Description**
- Outfit 400, `13px`, `#8b949e`
- Line-height: `1.6`
- Margin-bottom: `20px`

**Step 5: Input (if applicable)**
- Pill input: `background: #0d1117`, `border: 1.5px solid #30363d`, `border-radius: 9999px`
- Padding: `10px 18px`
- Font: Outfit 400, 14px, `#e6edf3`
- Margin-bottom: `12px`

**Step 6: Button row**
- Flex, gap: `10px`, justify-content: `flex-end`
- Cancel: `background: #21262d`, `border: 1px solid #30363d`, `color: #8b949e`, pill radius
- Confirm: `background: #58a6ff`, `color: #0d1117`, `font-weight: 700`, pill radius
- Destructive: `background: #f85149`, `color: #fff`, pill radius

**Step 7: Entry animation**
- Modal starts at `translateY(12px)` and opacity 0
- Transitions to `translateY(0)` and opacity 1
- Duration: transform `350ms` ease-standard, opacity `200ms` ease-out

---

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

**Step 1: Container**
- Background: `#161b22`
- Border: `1px solid #30363d`
- Border-radius: `16px`
- Padding: `24px`
- No top accent line
- Optional shadow: `0 2px 8px rgba(0,0,0,0.25)` for featured cards

**Step 2: Section title**
- Outfit 600, `10px`, uppercase, `#484f58`, tracking `0.14em`
- Border-bottom: `1px solid #21262d`
- Padding-bottom: `8px`
- Margin-bottom: `20px`

**Step 3: Content**
- Body text: Outfit 400, `14px–15px`, `#8b949e`
- Strong values: Outfit 700, `#e6edf3`
- Gap between items: `8px–14px`

---

### 10.3 How to Build a Status Badge — Step by Step

**Step 1: Shell**
- Border-radius: `9999px`
- Padding: `3px 12px`
- Display: `inline-flex`, `align-items: center`

**Step 2: Pick the semantic color**
- Deployed / Active / Success → `#3fb950`
- Building / Pending / Warning → `#d29922`
- Failed / Error → `#f85149`
- Running / Info → `#58a6ff`
- Preview / Beta → `#bc8cff`
- Neutral → `#8b949e`

**Step 3: Apply the transparency rule**
- Background: `rgba([color-rgb], 0.15)` — never solid
- Text: the full-opacity hex value of the semantic color
- No border needed (optional: `rgba([color-rgb], 0.30)` border for more definition)

**Step 4: Typography**
- Outfit 700, `11px`, uppercase, `letter-spacing: 0.03em`

---

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

**Step 1: Container**
- Overflow: `hidden`
- Border-radius: `8px` (slightly softer than cards — tables are data-dense)
- The card wrapping the table handles `border: 1px solid #30363d`

**Step 2: Header row**
- No background color (inherits base `#0d1117`)
- Font: Outfit 600, `11px`, uppercase, `#8b949e`, `letter-spacing: 0.08em`
- Padding: `10px 14px`
- Border-bottom: `1px solid #21262d`

**Step 3: Body rows**
- Font: Outfit 400, `14px`, `#c9d1d9`
- Padding: `12px 14px`
- Border-bottom: `1px solid #21262d`
- Hover: `background: #21262d`
- Last row: remove border-bottom

**Step 4: Status in cells**
- Use the pill badge component
- Branch names: Outfit or IBM Plex Mono, `color: #58a6ff`
- Timestamps: Outfit 400, `#484f58`

---

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

**Step 1: Track**
- Width: `44px`, height: `24px`
- Background: `#30363d` (off) / `#58a6ff` (on)
- Border-radius: `9999px`
- `position: relative`

**Step 2: Thumb**
- Width: `18px`, height: `18px`
- Background: `#ffffff`
- Border-radius: `50%`
- Position: `absolute`, top: `3px`, left: `3px`
- `transform: translateX(0)` (off) / `transform: translateX(20px)` (on)
- Transition: `transform 200ms ease-out`
- Optional: `box-shadow: 0 1px 3px rgba(0,0,0,0.30)` for thumb lift

**Step 3: Label**
- Outfit 400, `13px`, `#8b949e`
- Placed to the right of or left of the track
- Gap from track: `12px`

---

## 11. Interactive States — Full Decision Guide

### 11.1 Button States

**Primary button (blue pill):**
- Default: `background: #58a6ff`, `color: #0d1117`
- Hover: `background: #79b8ff` + `box-shadow: 0 4px 16px rgba(88,166,255,0.25)`
- Active/press: `transform: scale(0.98)`, immediate (50ms)
- Disabled: `opacity: 0.35`, `cursor: not-allowed`
- Loading: `opacity: 0.70` + spinner character, `pointer-events: none`

**Secondary button (dark pill):**
- Default: `background: #21262d`, `border: 1px solid #30363d`
- Hover: `background: #30363d`
- Active: `transform: scale(0.98)`
- Disabled: `opacity: 0.35`

**Outline button (ghost blue pill):**
- Default: `background: transparent`, `border: 1.5px solid #58a6ff`, `color: #58a6ff`
- Hover: `background: rgba(88,166,255,0.10)`
- Active: `transform: scale(0.98)`

**Destructive button (red pill):**
- Default: `background: #f85149`
- Hover: `background: #ff6b6b`
- Active: `transform: scale(0.98)`

---

### 11.2 Input Focus

**Text Input:**
- Default: `border: 1.5px solid #30363d`
- Hover: `border-color: #484f58`
- Focus: `border-color: #58a6ff` + `box-shadow: 0 0 0 3px rgba(88,166,255,0.15)`
- Error: `border-color: #f85149` + `box-shadow: 0 0 0 3px rgba(248,81,73,0.15)`
- Disabled: `opacity: 0.40`, `cursor: not-allowed`

**Dropdown (when open):**
- Same as focus state on the trigger
- Panel appears below with `border-radius: 16px`, `box-shadow: 0 16px 32px rgba(0,0,0,0.50)`

---

### 11.3 Table Row Hover

```css
tr:hover td { background: #21262d; }
```

This is a subtle but perceptible row highlight. The transition is `background 100ms ease-out` — fast enough to feel responsive without being distracting.

---

### 11.4 Dropdown Item Hover

```css
.dropdown-item:hover {
  background: #21262d;
  color: #58a6ff;  /* text turns accent blue */
}
```

The item's text turning blue on hover is a Capsule-specific convention — it connects dropdown option selection to the system's primary interactive color.

---

## 12. Layout Construction Rules

### 12.1 Page Layout Model

The standard Capsule dashboard page uses a `max-width: 1200px` content area centered on the `#0d1117` page background, with `40px 24px` padding (vertical / horizontal):

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

---

### 12.2 Dashboard Grid Pattern

Most Capsule dashboards follow a two-column primary layout for the main content area:

```css
/* Primary layout: wide content + narrow controls */
.layout-main {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

/* Equal columns for stats / feature groups */
.layout-equal {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}
```

Cards are separated by `20px` gaps — not `24px`. The pill elements within cards already have generous internal padding; the card gap does not need to be as large as in editorial systems.

---

### 12.3 Card Stack Rhythm

When multiple cards stack vertically, the margin-bottom between them is always `20px`:

```css
.card + .card { margin-bottom: 20px; }
/* or */
.card-stack { display: flex; flex-direction: column; gap: 20px; }
```

---

### 12.4 Page Header Layout

The Capsule page header uses a horizontal flex layout — title left, metadata badges right:

```css
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 40px;
}
```

---

## 13. Animation Rules

### 13.1 What Can Animate

| Element | Property | Duration | Easing |
|---------|----------|----------|--------|
| Button hover | `background`, `box-shadow` | 200ms | ease-out |
| Button press | `transform: scale(0.98)` | 50ms | linear |
| Input focus | `border-color`, `box-shadow` | 200ms | ease-out |
| Toggle thumb | `transform` | 200ms | ease-out |
| Toggle track | `background` | 200ms | ease-out |
| Dropdown open | `display + opacity` | 150ms | ease-out |
| Modal entry | `transform: translateY`, `opacity` | 350ms / 200ms | ease-standard / ease-out |
| Dropdown item hover | `background`, `color` | 100ms | ease-out |
| Table row hover | `background` | 100ms | ease-out |

### 13.2 What Should Not Animate

- Card appearances on page load (no fade-in unless the page itself is loading)
- Section title opacity
- Badge colors changing in response to data updates (state changes should be instant)
- Scroll-triggered effects
- Parallax or motion on background elements

### 13.3 Live Status Indicators

The only allowed pulse animation is on a live-status dot — for example, a green dot beside "Live" or "Active":

```css
@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.4; }
}
.live-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #3fb950;
  animation: pulse-dot 2s ease-in-out infinite;
}
```

This is the only pulsing element allowed in the system. Use it only for genuinely live/streaming indicators.

---

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

### Typography Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Use italic text anywhere | Capsule has no italic style — all fonts are upright |
| Use serif fonts | All text is sans-serif in this system |
| Use Nunito Sans for buttons or UI labels | Reserve Nunito Sans for large display titles only |
| Use IBM Plex Mono for labels or descriptions | Use Outfit — mono is for code/technical identifiers only |
| Use `font-weight: 300` for readable content | 300 is for timestamps and captions only |
| Set letter-spacing on body text | Only uppercase elements and display text adjust tracking |

---

### Color Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Use white or light-mode backgrounds | All backgrounds are dark (`#0d1117`, `#161b22`, `#21262d`) |
| Use blue as a background color | Blue is for interactive elements only |
| Use solid-fill status badges | Always use `rgba` tinted backgrounds |
| Use warm-toned shadows (`rgba(100,80,30,...)`) | Use black shadows (`rgba(0,0,0,...)`) |
| Use a second accent color | Only `#58a6ff` is the accent |
| Use `#ffffff` pure white for inputs | Inputs use `#0d1117` — same as page base |
| Apply blue glow to secondary buttons | Blue glow is for primary buttons only |

---

### Border Radius Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Use square buttons (`border-radius: 0` or `2px`) | All buttons are `9999px` pills |
| Use `4px` or `8px` radius on inputs | Inputs are `9999px` pills |
| Use sharp or low-radius cards (`4px`) | Cards are `16px` |
| Use `9999px` on textareas | Textareas are `16px` |
| Use `0px` on checkboxes | Checkboxes are `4px` |

---

### Structural Anti-Patterns

| ❌ Never | ✅ Instead |
|---------|----------|
| Add a gold or colored top accent line to cards | No accent lines — cards are flat-topped |
| Add a decorative top border to modals | Modals use shadow only for definition |
| Use `#ffffff` backgrounds in any component | The darkest tone is `#0d1117` — nothing is lighter |
| Use gradient fills on any surface | Gradients on surfaces are forbidden |
| Create a fourth dark background tone | Three tones only: `#0d1117`, `#161b22`, `#21262d` |
| Apply blue glow to cards or panels | The glow is only for primary button hover |

---

## 15. AI Prompting Instructions

When using AI tools to generate interfaces in the Capsule system, include these instructions in your prompt:

---

**System prompt to include:**

> Build this UI using the Capsule design system.  
>  
> Core rules:  
> — Dark mode only. Background: `#0d1117`. Cards/panels: `#161b22`. Hover fills: `#21262d`.  
> — All buttons, inputs (single-line), badges, and toggles use `border-radius: 9999px` (pill shape). Textareas use `border-radius: 16px`. Cards and modals use `border-radius: 16px`.  
> — Primary accent: `#58a6ff`. Use for: primary button fill, input focus border, outline button. Blue glow `box-shadow: 0 4px 16px rgba(88,166,255,0.25)` on primary button hover only.  
> — Fonts: Outfit for all UI text (buttons, labels, body, nav). Nunito Sans for large display titles only. IBM Plex Mono for code and branch names only.  
> — Status badges: always `rgba(color, 0.15)` background + full-opacity text. Never solid fills.  
> — Section titles: Outfit 600, 10px, uppercase, `#484f58`, `letter-spacing: 0.14em`, with `border-bottom: 1px solid #21262d`.  
> — No warm shadows. Use `rgba(0,0,0,...)` for all shadows.  
> — No top accent lines on cards or modals.  
> — Text hierarchy: `#e6edf3` (primary) → `#c9d1d9` (body) → `#8b949e` (labels) → `#484f58` (metadata/muted).

---

## 16. New Project Checklist

Before writing any code, verify:

**Fonts:**
- [ ] Nunito Sans imported (weights 300–900)
- [ ] Outfit imported (weights 300–800)
- [ ] IBM Plex Mono imported (weights 300–500)
- [ ] `font-family: 'Outfit', sans-serif` set on `body`

**Colors:**
- [ ] `--color-bg-base: #0d1117` on root/container
- [ ] `--color-bg-surface: #161b22` for cards
- [ ] `--color-bg-elevated: #21262d` for hover states
- [ ] `--color-blue-400: #58a6ff` as primary accent

**Radius:**
- [ ] All buttons have `border-radius: 9999px`
- [ ] All single-line inputs have `border-radius: 9999px`
- [ ] Textareas have `border-radius: 16px`
- [ ] All badges have `border-radius: 9999px`
- [ ] Cards have `border-radius: 16px`
- [ ] Modals have `border-radius: 16px–20px`

**Shadows:**
- [ ] No warm-toned shadows
- [ ] Modal uses `0 24px 64px rgba(0,0,0,0.70)`
- [ ] Primary button hover has blue glow
- [ ] No other elements have the blue glow

**Structure:**
- [ ] No light or white backgrounds anywhere
- [ ] No top accent lines on cards or modals
- [ ] Status badges use `rgba` backgrounds, not solid
- [ ] Inputs use `#0d1117` background (same as page)

---

## 17. Component Pattern Library

### Pattern: Deployment Row Card

```html
<div class="card">
  <div class="section-title">Deployments</div>
  <table>
    <thead>
      <tr>
        <th>Project</th>
        <th>Status</th>
        <th>Branch</th>
        <th>Time</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="font-weight:600;color:#e6edf3;">design-system</td>
        <td><span class="badge badge-deployed">Ready</span></td>
        <td style="color:#58a6ff;font-family:'IBM Plex Mono';">main</td>
        <td style="color:#484f58;">2m ago</td>
        <td><button class="btn-secondary" style="font-size:11px;padding:5px 14px;">Visit</button></td>
      </tr>
    </tbody>
  </table>
</div>
```

---

### Pattern: Branch Status Pill Row

```html
<div style="background:#21262d;border-radius:9999px;padding:8px 16px;
            display:flex;align-items:center;justify-content:space-between;">
  <span style="font-size:13px;color:#e6edf3;">main branch</span>
  <span class="badge badge-deployed">Live</span>
</div>
```

---

### Pattern: Page Header

```html
<div class="page-header">
  <div>
    <div style="font-size:11px;letter-spacing:0.10em;text-transform:uppercase;
                color:#484f58;margin-bottom:6px;font-weight:600;">Theme 04</div>
    <h1 style="font-family:'Outfit',sans-serif;font-size:44px;font-weight:800;
               margin:0;letter-spacing:-0.02em;">
      <span style="color:#58a6ff;">Capsule</span> Design
    </h1>
  </div>
  <div style="display:flex;gap:8px;flex-wrap:wrap;">
    <span class="badge badge-neutral">Radius: ∞</span>
    <span class="badge" style="background:rgba(88,166,255,0.15);color:#58a6ff;
                               border:1px solid #30363d;">Dark Mode</span>
    <span class="badge badge-neutral">Outfit Font</span>
  </div>
</div>
```

---

### Pattern: Confirm Modal

```html
<div class="modal-backdrop">
  <div class="modal">
    <div style="font-family:'Outfit',sans-serif;font-size:20px;font-weight:700;
                margin-bottom:6px;color:#e6edf3;">Deploy to Production</div>
    <div style="font-size:13px;color:#8b949e;margin-bottom:20px;line-height:1.6;">
      Select the branch and environment, then confirm the deployment.
    </div>
    <input class="input" placeholder="Branch name (e.g. main)" style="margin-bottom:12px;">
    <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:8px;">
      <button class="btn-secondary">Cancel</button>
      <button class="btn-primary">Deploy Now</button>
    </div>
  </div>
</div>
```

---

## 18. Responsive Construction Rules

### 18.1 Breakpoint Behavior

**Below 480px (Mobile S):**
- Modal padding reduces from 32px to 20px
- Modal border-radius reduces from 20px to 16px
- Button groups stack vertically (`flex-direction: column`)
- Hero Nunito Sans title reduces 2 weight sizes (900 → 700) and 2 type sizes
- Card padding reduces from 24px to 16px
- Two-column grids collapse to single column
- Page header stacks vertically (title above badges)

**480px–767px (Mobile L):**
- Modal fills screen with 16px margin on left/right
- Two-column layouts collapse to single column
- Navigation collapses to hamburger or bottom bar
- Table scrolls horizontally within card container
- Button text maintains full font size

**768px–1023px (Tablet):**
- Two-column grids active
- Cards at standard `24px` padding
- Modal at standard size and radius
- Full typography scale restored
- Page header horizontal layout returns

**1024px+ (Desktop):**
- Full system at designed specifications
- 2fr + 1fr layouts enabled
- All padding at full token values

---

### 18.2 Typography Scaling

| Element | Desktop | Tablet | Mobile |
|---------|---------|--------|--------|
| Hero Display | 3rem | 2.25rem | 1.875rem |
| Page H1 | 2.25rem | 1.875rem | 1.5rem |
| Section H2 | 1.875rem | 1.5rem | 1.25rem |
| Card/Modal Title | 1.25rem | 1.25rem | 1.125rem |
| Body | 0.875rem | 0.875rem | 0.9375rem (slightly larger) |
| Badge | 11px | 11px | 11px |
| Section title (caps) | 10px | 10px | 10px |

Body copy slightly increases on mobile to compensate for distance from screen.

---

## 19. Accessibility Guidelines

### 19.1 Color Contrast Requirements

| Pairing | Contrast | WCAG Level |
|---------|----------|-----------|
| `#e6edf3` on `#0d1117` | 15.8:1 | AAA ✓ |
| `#e6edf3` on `#161b22` | 12.4:1 | AAA ✓ |
| `#c9d1d9` on `#0d1117` | 10.7:1 | AAA ✓ |
| `#8b949e` on `#0d1117` | 5.2:1 | AA ✓ |
| `#58a6ff` on `#0d1117` | 5.9:1 | AA ✓ |
| `#0d1117` on `#58a6ff` | 5.9:1 | AA ✓ |
| `#3fb950` on `#0d1117` | 5.1:1 | AA ✓ |
| `#f85149` on `#0d1117` | 4.7:1 | AA ✓ |
| `#484f58` on `#0d1117` | 2.1:1 | ✗ Muted/decorative only |

**Rules:**
- `--color-text-muted` (`#484f58`) is acceptable ONLY for section titles and timestamps — never for required reading content.
- `--color-text-disabled` (`#30363d`) is intentionally below contrast — only for disabled UI.

---

### 19.2 Focus Management

- All interactive elements must have a visible `:focus-visible` state
- Focus ring: `outline: 2px solid #58a6ff; outline-offset: 2px;`
- Input focus uses border + glow — never remove both
- Never use `outline: none` without providing the border+glow alternative
- Modal opening must trap focus within the modal
- Modal closing must return focus to the trigger element

---

### 19.3 ARIA Requirements

```html
<!-- Modal -->
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
  <h2 id="modal-title">Deploy to Production</h2>
</div>

<!-- Field label association -->
<label for="branch-input">Branch name</label>
<input id="branch-input" type="text" placeholder="main" />

<!-- Error state -->
<input aria-invalid="true" aria-describedby="branch-error" />
<div id="branch-error" role="alert">Branch name is required</div>

<!-- Toggle -->
<button role="switch" aria-checked="true" aria-label="Auto deploy">
  <!-- toggle track + thumb -->
</button>

<!-- Status badge (purely visual) -->
<span class="badge badge-deployed" aria-label="Status: Deployed">Deployed</span>
```

---

### 19.4 Dark Mode Specific Accessibility Notes

- Never rely solely on color to convey state — always pair color with text label (e.g., don't use a red dot without the word "Failed")
- Ensure that `#484f58` text (section titles, timestamps) is never used for informational content the user needs to act on
- The blue glow on primary button hover should be accompanied by a color shift — both signals together serve users who may not perceive glow
- Disabled buttons at `opacity: 0.35` must not be the only signal of disabled state — pair with `cursor: not-allowed` and `aria-disabled="true"`

---

## 20. Common Scenarios — Decision Trees

### Scenario: "Should this button be a pill?"

```
Is it a button of any kind (primary, secondary, outline, destructive, ghost)? ──YES──► 9999px pill
        │ NO
        ▼
Is it a form submit or close button inside a modal? ──YES──► 9999px pill
        │ NO
        ▼
Is it a table row action (Visit, View, Logs)? ──YES──► 9999px pill (smaller padding)
        │ NO
        ▼
Is it an icon-only action (no text)? ──YES──► 9999px (circle) or 8px square
```

---

### Scenario: "What background does this element use?"

```
Is it the page body? ──YES──► #0d1117
        │ NO
        ▼
Is it a card, modal, panel, or sidebar? ──YES──► #161b22
        │ NO
        ▼
Is it a hovered row, dropdown item, or active fill? ──YES──► #21262d
        │ NO
        ▼
Is it an input field (text, textarea, select)? ──YES──► #0d1117
        │ NO
        ▼
Default: inherit from parent (no background set)
```

---

### Scenario: "How should I show a loading state on a button?"

```
Reduce opacity to 0.70
Add pointer-events: none
Replace button text with: spinner_character + " Loading..."
After resolution (2s+):
  Replace with: "✓ Done"
  After 1.2s: restore original text and opacity
```

Do not change the button's color during loading. Do not disable hover states during loading (the opacity communicates non-interactivity sufficiently).

---

### Scenario: "Which shadow level should I use?"

```
Is the element a modal or dialog?
──YES──► 0 24px 64px rgba(0,0,0,0.70) — mandatory

Is the element a dropdown panel?
──YES──► 0 16px 32px rgba(0,0,0,0.50)

Is the element a hovered primary button?
──YES──► 0 4px 16px rgba(88,166,255,0.25) — blue glow only

Is the element a toast or notification?
──YES──► 0 16px 40px rgba(0,0,0,0.50)

Is the element a card (featured)?
──YES──► 0 2px 8px rgba(0,0,0,0.25) — optional

Is the element a flat card (data table wrapper)?
──YES──► no shadow — use border only

Is the element a tooltip?
──YES──► 0 4px 12px rgba(0,0,0,0.30)
```

---

### Scenario: "Should this have a top accent line?"

```
Is this system the Capsule theme? ──YES──► No accent line. Ever.
```

The Capsule system does not use top accent lines on any component. This question should never arise. If you are tempted to add one, you are importing a pattern from a different design system.

---

### Scenario: "Should I use Nunito Sans or Outfit here?"

```
Is this text ≥30px and a standalone display title? ──YES──► Nunito Sans, 800–900
        │ NO
        ▼
Is this text any UI element or body copy? ──YES──► Outfit
        │ NO
        ▼
Is this a code value, branch name, or technical identifier? ──YES──► IBM Plex Mono
        │ NO
        ▼
Default: Outfit
```

---

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