---
name: Affirm
tagline: 'Honest-money fintech in the dark — indigo #4a4af4 CTAs at near-pill 96px radius, light-weight white headlines, no fine print.'
updated_at: 2026-05-28T22:15:35.438Z
published_at: 2026-05-28T22:15:35.438Z
author: webdesignhot
source_url: https://www.affirm.com
spec: webdesignhot/0.1
quality: curated
featured: false
categories: [saas]
tags: [dark, structured, sans, fintech]
preview_swatch: ['#13131f', '#4a4af4', '#ffffff']
related: []
description: 'Affirm''s marketing site is buy-now-pay-later rebuilt as a trust object — a deep near-black canvas (`#13131f`) with light-weight (300) white headlines in Axiforma for Affirm, Calibre body text, and a single saturated indigo (`#4a4af4`) reserved for action surfaces. The signature move is geometry: CTA buttons round to a near-pill `96px` radius that reads soft and approachable on a serious dark stage, the visual translation of Affirm''s "no hidden fees, no surprises" promise. Where most fintech goes corporate-blue and sharp-cornered, Affirm goes confident-dark and generously rounded — honesty rendered as calm, legible, friction-free surface.'


# Canonical 8-role aliases (bg / text / brand / border / accent / muted / surface / danger).
# Maps role names to this entry's actual token names so role-aware
# downstream tools resolve `theme.background` → entry's `bg`, etc.
# Auto-generated by scripts/add-aliases.mjs — do not edit manually;
# regenerate after changing color token names.
aliases:
  background: bg
  foreground: text
  primary: brand
  primary-foreground: on-brand
  accent: accent-mint
  muted: text-soft
  border: border
  ring: border-brand
colors:
  bg: '#13131f'
  bg-deep: '#0c0c14'
  surface: '#1c1c2b'
  surface-elev: '#23233a'
  surface-light: '#ffffff'
  surface-light-quiet: '#f6f6fb'
  text: '#101820'                       # darkest ink — text on light cards/surfaces
  text-on-dark: '#ffffff'              # primary text on the dark canvas
  text-on-dark-muted: 'rgba(255,255,255,0.72)'
  text-on-dark-subtle: 'rgba(255,255,255,0.55)'
  text-soft: '#4a4a57'                 # secondary ink on light surfaces
  text-subdued: '#6b6b78'
  brand: '#4a4af4'                     # Affirm indigo — rgb(74,74,244)
  brand-hover: '#3a3ad6'
  brand-deep: '#2e2eb0'
  brand-light: '#7a7af7'
  brand-tint: '#e6e6fe'                # pale indigo wash for light-surface fills
  brand-bg-hover: 'rgba(74,74,244,0.08)'
  brand-on-dark-tint: 'rgba(74,74,244,0.18)'
  on-brand: '#ffffff'
  accent-mint: '#7affc1'               # soft success / "approved" mint highlight
  accent-sky: '#9fd8ff'                # cool decorative sky for illustration accents
  border: 'rgba(255,255,255,0.12)'     # hairline on dark canvas
  border-strong: 'rgba(255,255,255,0.24)'
  border-light: '#e2e2ec'              # border on light surfaces
  border-brand: '#4a4af4'
  link: '#9fa0ff'                      # link on dark canvas (lifted indigo for contrast)
  link-on-light: '#4a4af4'
  success: '#1f9d55'
  success-text: '#0f7a3e'
  success-bg: 'rgba(31,157,85,0.16)'
  warning: '#b06a00'
  warning-bg: 'rgba(176,106,0,0.14)'
  danger: '#d92d2d'
  danger-bg: 'rgba(217,45,45,0.14)'
  shadow-deep: 'rgba(0,0,0,0.45)'      # depth on the dark canvas
  shadow-soft: 'rgba(0,0,0,0.28)'
  shadow-light: 'rgba(16,24,32,0.10)'  # depth for elements on light surfaces

typography:
  display:
    family: '"Axiforma for Affirm", system-ui, -apple-system, sans-serif'
    weights: [300, 400, 500, 600, 700]
  body:
    family: 'Calibre, system-ui, -apple-system, sans-serif'
    weights: [400, 500, 600]
  mono:
    family: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace'
    weights: [400, 500]
  scale:
    display-hero:    { size: 80, weight: 300, lineHeight: 1.0,  tracking: '-0.03em',  family: display }
    display-lg:      { size: 56, weight: 300, lineHeight: 1.05, tracking: '-0.02em',  family: display }
    h1:              { size: 40, weight: 300, lineHeight: 1.1,  tracking: '-0.018em', family: display }
    h2:              { size: 32, weight: 400, lineHeight: 1.2,  tracking: '-0.012em', family: display }
    h3:              { size: 24, weight: 500, lineHeight: 1.25, tracking: '-0.005em', family: display }
    h4:              { size: 20, weight: 600, lineHeight: 1.3,  tracking: '0',        family: body }
    body-lg:         { size: 18, weight: 400, lineHeight: 1.55, tracking: '0',        family: body }
    body:            { size: 16, weight: 400, lineHeight: 1.55, tracking: '0',        family: body }
    body-emphasis:   { size: 16, weight: 600, lineHeight: 1.55, tracking: '0',        family: body }
    body-sm:         { size: 14, weight: 400, lineHeight: 1.5,  tracking: '0',        family: body }
    label:           { size: 13, weight: 500, lineHeight: 1.4,  tracking: '0',        family: body }
    button:          { size: 16, weight: 600, lineHeight: 1.0,  tracking: '0',        family: body }
    link:            { size: 14, weight: 500, lineHeight: 1.0,  tracking: '0',        family: body }
    caption:         { size: 12, weight: 500, lineHeight: 1.4,  tracking: '0.02em',   family: body }
    micro:           { size: 11, weight: 500, lineHeight: 1.3,  tracking: '0.03em',   family: body }
    legal:           { size: 12, weight: 400, lineHeight: 1.5,  tracking: '0',        family: body }

radius:
  micro: 2
  sm: 4
  md: 8
  lg: 12
  xl: 16
  card: 24
  pill: 96
  full: 9999

spacing:
  base: 4
  scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96, 128]

layout:
  page-width: 1280
  prose-width: 720
  header-height: 64
  gutter: 24
  section-y: 96

components:
  button-primary:
    bg: brand
    text: on-brand
    radius: 96
    padding: '14px 28px'
    font: 'Calibre 16px / weight 600'
    hover: 'background → #3a3ad6'
    use: 'Primary CTA — "Get started", "Apply now". Near-pill 96px radius reads soft and friendly on the dark stage.'
  button-secondary:
    bg: surface-light
    text: text
    radius: 96
    padding: '14px 28px'
    font: 'Calibre 16px / weight 600'
    hover: 'background → #f6f6fb'
    use: 'White pill button on the dark canvas — high-contrast secondary path.'
  button-ghost:
    bg: transparent
    text: text-on-dark
    border: '1px solid rgba(255,255,255,0.24)'
    radius: 96
    padding: '14px 28px'
    hover: 'border → rgba(255,255,255,0.4), background → rgba(255,255,255,0.06)'
    use: 'Outlined tertiary action on the dark canvas.'
  button-link:
    bg: transparent
    text: link
    radius: 0
    font: 'Calibre 14px / weight 500'
    hover: 'underline appears'
    use: 'Inline text action — "Learn more", "See how it works".'
  card:
    bg: surface-light
    text: text
    border: 'none'
    radius: 24
    padding: 24
    shadow: 'rgba(0,0,0,0.45) 0 24px 48px -24px'
    use: 'Light content card lifted off the dark canvas with deep soft shadow.'
  card-dark:
    bg: surface
    text: text-on-dark
    border: '1px solid rgba(255,255,255,0.12)'
    radius: 24
    padding: 24
    use: 'Elevated panel that stays within the dark world.'
  badge:
    bg: brand-on-dark-tint
    text: brand-light
    radius: 96
    padding: '4px 12px'
    font: 'Calibre 12px / weight 500'
    use: 'Pill tag on the dark canvas — eyebrow labels, status chips.'
  input:
    bg: surface-light
    border: '1px solid #e2e2ec'
    text: text
    radius: 8
    padding: '12px 16px'
    placeholder: '#6b6b78'
    focus: 'border → #4a4af4, ring 0 0 0 3px rgba(74,74,244,0.25)'

motion:
  ease-standard: 'cubic-bezier(0.4, 0, 0.2, 1)'
  ease-emphasized: 'cubic-bezier(0.2, 0, 0, 1)'
  ease-out: 'cubic-bezier(0, 0, 0.2, 1)'
  duration-fast: 150
  duration-standard: 240
  duration-slow: 320
  hover-lift: 'translate-Y(-2px) + shadow deepen'
  reduced-motion: 'respects prefers-reduced-motion: reduce — opacity-only transitions, no translate, no scale'

breakpoints:
  mobile: 640
  tablet: 1024
  desktop: 1280
  wide: 1536

shadows:
  ambient: 'rgba(0,0,0,0.28) 0 4px 12px'
  soft: 'rgba(0,0,0,0.28) 0 12px 28px -8px'
  elevated: 'rgba(0,0,0,0.45) 0 24px 48px -24px'
  deep: 'rgba(0,0,0,0.55) 0 40px 80px -32px'
  light-surface: 'rgba(16,24,32,0.10) 0 8px 24px -8px'
  ring: '0 0 0 3px rgba(74,74,244,0.25)'

accessibility:
  contrast-text-on-bg: 17.4                # #ffffff on #13131f — AAA
  contrast-ink-on-light: 16.9              # #101820 on #ffffff — AAA
  contrast-text-on-brand: 4.9              # #ffffff on #4a4af4 — AA
  contrast-brand-on-dark: 5.1              # #9fa0ff link on #13131f — AA
  focus-ring: '3px ring rgba(74,74,244,0.25) + 2px solid #4a4af4'
  reduced-motion-honored: true
  keyboard-nav: 'tab order follows DOM; visible focus ring on all interactive elements; skip-to-content link in header'

lineage:
  summary: |
    Affirm sits at the intersection of two fintech traditions: the editorial
    light-weight headline pioneered by Stripe (display type at weight 300, set
    huge, set white) and the friendly geometry of the consumer-lending wave
    (Klarna, Cash App) where very-rounded buttons soften financial anxiety. Its
    distinctive choice is to run that approachable geometry on a serious dark
    canvas (#13131f) rather than the usual bright white — confidence and calm
    instead of cheer. The single saturated indigo (#4a4af4) is the only chromatic
    accent and is reserved for action; everything else is white, ink, and the
    near-black ground. Axiforma for Affirm (a custom geometric grotesque) carries
    the display voice; Calibre — the Klim grotesque also used by the UK government
    and the British Airways identity — carries the body. The radius story is the
    whole brand thesis: a 96px near-pill on a CTA is the visual form of "no hidden
    fees" — nothing sharp, nothing hidden, nothing that catches.
  influences:
    - name: Calibre (Klim Type Foundry)
      role: Body typeface — humanist grotesque, used for running text and UI labels
      url: https://klim.co.nz/retail-fonts/calibre/
    - name: Stripe
      role: Light-weight (300) display headline convention in fintech marketing
      url: https://stripe.com
    - name: Klarna
      role: Consumer-BNPL register — very-rounded buttons that soften financial decisions
      url: https://www.klarna.com
    - name: Cash App
      role: Confident dark-canvas fintech surface with a single saturated accent
      url: https://cash.app
    - name: Linear
      role: Dark-first product aesthetic — near-black ground, hairline borders, restrained accent
      url: https://linear.app

dark-mode: native   # Affirm's marketing surface is dark by default (#13131f canvas); light surfaces are inset cards
---

## 1. Visual Theme & Atmosphere

Affirm's marketing site is buy-now-pay-later rebuilt as a trust object. The page opens on a deep near-black canvas (`#13131f`) — not pure black, but an ink with the faintest blue-violet undertone that keeps the surface from feeling oppressive. Against it, headlines arrive in white at an unusually light weight (`300`) and an enormous size, set in the custom Axiforma for Affirm. The combination is calm and confident: a serious financial stage that nonetheless feels open and unhurried. Where most BNPL competitors reach for bright, cheerful white backgrounds to feel friendly, Affirm reaches for dark and lets the friendliness come from geometry and restraint instead.

The defining gesture is the radius. Affirm's call-to-action buttons round to a near-pill `96px` — so soft that on a short button it reads as a full pill, and on a wider one as a generously rounded capsule. This is not a decorative flourish; it is the brand thesis made visible. Affirm's entire proposition is "no hidden fees, no surprises, no compounding interest" — and the radius is the literal translation of that promise into form. Nothing is sharp. Nothing catches. Every action surface is rounded to the point of obvious friendliness, so the geometry itself signals honesty before a word is read.

Colour is rationed with discipline. A single saturated indigo (`#4a4af4`) is the only chromatic accent in the system, and it is reserved almost exclusively for action — primary buttons, links, focus rings, and the occasional small highlight. Everything else is built from white, the deep ink, and the near-black ground. The scarcity is the point: when the indigo appears, it always means "this is the thing to do next." Against the dark canvas the indigo glows, while white pill buttons offer the high-contrast secondary path.

Typography carries the personality split. Axiforma for Affirm — a custom geometric grotesque — handles display, and at weight `300` set large it reads editorial and premium, the same light-headline move Stripe brought to fintech. Calibre, Klim Type Foundry's humanist grotesque, handles body and UI; it is warm, legible, and quietly trustworthy (it is the same family behind the UK government's identity work). Body text on dark uses white at `72%` opacity rather than pure white, which softens the contrast just enough to feel like reading rather than scanning.

The overall impression is of a fintech that has decided to be calm. There is no gradient maximalism, no playful pastel, no corporate-blue conservatism. There is a dark room, very large light type, generously rounded indigo actions, and a great deal of breathing space. It reads honest because it looks like it has nothing to hide.

**Key Characteristics:**
- Dark near-black canvas (`#13131f`) with a faint blue-violet undertone — confident, not oppressive
- Light-weight (`300`) white display headlines set huge in Axiforma for Affirm — editorial, premium
- Near-pill `96px` CTA radius — the visual form of "no hidden fees," soft and approachable
- A single rationed indigo accent (`#4a4af4`), reserved for action surfaces only
- Calibre body text on dark at `72%` white opacity — readable, warm, never harsh
- White pill buttons as the high-contrast secondary path on the dark canvas
- Light surfaces (`#ffffff` cards) inset into the dark world, lifted with deep soft shadows
- Hairline borders (`rgba(255,255,255,0.12)`) instead of solid rules on the canvas
- Generous whitespace and a `4px`-based spacing rhythm scaling to large section gutters
- No gradients on UI, no warm accents, no decorative colour — discipline as a trust signal

## 2. Color Palette & Roles

### Canvas

- **Canvas** (`#13131f`): the primary dark background — every section, the default ground for the whole site.
- **Canvas Deep** (`#0c0c14`): darkest ground for footers and full-bleed immersive bands.
- **Surface** (`#1c1c2b`) [→ dark-card]: elevated panel that stays inside the dark world.
- **Surface Elev** (`#23233a`): higher-elevation dark panel — popovers, sticky bars.
- **Surface Light** (`#ffffff`): inset light card lifted off the dark canvas.
- **Surface Light Quiet** (`#f6f6fb`): off-white for alternating areas inside a light card.

### Text

- **Text on Dark** (`#ffffff`): primary headings and high-emphasis text on the canvas.
- **Text on Dark Muted** (`rgba(255,255,255,0.72)`): body copy on dark — softened for reading.
- **Text on Dark Subtle** (`rgba(255,255,255,0.55)`): captions, metadata, legal on dark.
- **Text / Ink** (`#101820`): darkest ink — headings and body on light cards/surfaces.
- **Text Soft** (`#4a4a57`): secondary ink on light surfaces.
- **Text Subdued** (`#6b6b78`): placeholder and tertiary ink on light surfaces.

### Brand

- **Affirm Indigo** (`#4a4af4`) [→ rgb(74,74,244)]: the one accent — primary CTA fill, links, focus, brand highlights.
- **Indigo Hover** (`#3a3ad6`): pressed and hover state on primary buttons.
- **Indigo Deep** (`#2e2eb0`): darkest indigo for active/pressed on light surfaces.
- **Indigo Light** (`#7a7af7`): badge text and lifted indigo on dark panels.
- **Indigo Tint** (`#e6e6fe`): pale indigo wash for fills on light surfaces.
- **Indigo on Dark Tint** (`rgba(74,74,244,0.18)`): subtle indigo chip background on the canvas.
- **On Brand** (`#ffffff`): text/icon colour on indigo fills.

### Accent

- **Mint** (`#7affc1`): soft "approved / success" highlight in illustrations and status moments. Decorative — never a button fill.
- **Sky** (`#9fd8ff`): cool decorative accent for illustration and data viz only.

### Interactive

- **Link on Dark** (`#9fa0ff`): lifted indigo for links on the canvas (raised for contrast against `#13131f`).
- **Link on Light** (`#4a4af4`): the base indigo for links on light surfaces.
- **Brand BG Hover** (`rgba(74,74,244,0.08)`): subtle hover wash for indigo text/ghost actions.

### Borders

- **Border** (`rgba(255,255,255,0.12)`): default hairline on the dark canvas.
- **Border Strong** (`rgba(255,255,255,0.24)`): higher-emphasis hairline, ghost-button outline.
- **Border Light** (`#e2e2ec`): default border for inputs and dividers on light surfaces.
- **Border Brand** (`#4a4af4`): active/focus border on inputs and selected elements.

### Shadow Colors

- **Shadow Deep** (`rgba(0,0,0,0.45)`): primary lift for light cards against the dark canvas.
- **Shadow Soft** (`rgba(0,0,0,0.28)`): ambient/hover shadow on dark.
- **Shadow Light** (`rgba(16,24,32,0.10)`): subtle ink-tinted shadow for elements sitting on light surfaces.

### Semantic

- **Success** text `#0f7a3e` on `rgba(31,157,85,0.16)` background; base `#1f9d55`.
- **Warning** text/icon `#b06a00` on `rgba(176,106,0,0.14)` background.
- **Danger** text/icon `#d92d2d` on `rgba(217,45,45,0.14)` background.
- **Info** indigo `#4a4af4` text on `#e6e6fe` (indigo-tint) background.

## 3. Typography Rules

### Font Family

- **Display**: Axiforma for Affirm — a custom geometric grotesque, used for headings at light-to-medium weights.
- **Display fallback chain**: `"Axiforma for Affirm", system-ui, -apple-system, sans-serif`.
- **Body**: Calibre — Klim Type Foundry's humanist grotesque, used for running text, UI, and labels.
- **Body fallback chain**: `Calibre, system-ui, -apple-system, sans-serif`.
- **Mono companion**: `ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace` — for the rare APR/numeric callout.
- **Weight discipline**: display runs light (`300`) at large sizes and steps up to `400`–`600` as it shrinks; body runs `400` with `500`/`600` for emphasis and UI. No display weight above `700`.

### Hierarchy

| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes |
|------|------|------|--------|-------------|----------------|-------|
| Display Hero | Axiforma | 80 | 300 | 1.0 | -0.03em | White on dark, light-weight headline authority |
| Display Large | Axiforma | 56 | 300 | 1.05 | -0.02em | Secondary hero / section opener |
| H1 | Axiforma | 40 | 300 | 1.1 | -0.018em | Page titles |
| H2 / Section | Axiforma | 32 | 400 | 1.2 | -0.012em | Feature section titles |
| H3 | Axiforma | 24 | 500 | 1.25 | -0.005em | Card headings, sub-sections |
| H4 | Calibre | 20 | 600 | 1.3 | 0 | Small headings, switches to body family |
| Body Large | Calibre | 18 | 400 | 1.55 | 0 | Intro paragraphs, feature descriptions |
| Body | Calibre | 16 | 400 | 1.55 | 0 | Standard reading text |
| Body Emphasis | Calibre | 16 | 600 | 1.55 | 0 | Inline bold within body |
| Body Small | Calibre | 14 | 400 | 1.5 | 0 | Secondary copy, dense areas |
| Button | Calibre | 16 | 600 | 1.0 | 0 | Primary/secondary button label |
| Link / Nav | Calibre | 14 | 500 | 1.0 | 0 | Navigation and inline links |
| Label | Calibre | 13 | 500 | 1.4 | 0 | Form labels, field headings |
| Caption | Calibre | 12 | 500 | 1.4 | 0.02em | Eyebrows, metadata, small labels |
| Micro | Calibre | 11 | 500 | 1.3 | 0.03em | Tiny labels, badge text |
| Legal | Calibre | 12 | 400 | 1.5 | 0 | Disclosures, APR fine print |

### Principles

- **Light display, set large** — the hero headline is `300` weight at `80px`. Lightness reads premium and editorial; the size carries the authority. This is the brand's most distinctive typographic move.
- **Two families, clear jobs** — Axiforma for Affirm handles all display; Calibre handles all body, UI, and labels. The handoff happens at H4 (20px), where headings switch to the body family.
- **Progressive weight, inverse to size** — display gets heavier as it gets smaller (`300` → `400` → `500`), keeping small headings legible without making large ones shout.
- **Tight tracking at display** — negative letter-spacing scales with size (`-0.03em` at 80px down to `0` by 20px) to keep large light type from feeling loose.
- **Body never pure-white** — running text on dark uses `rgba(255,255,255,0.72)`, not `#ffffff`, to lower glare and read like prose.
- **Generous line height for body** — `1.55` on body sizes; light type on dark needs the air.
- **Legal copy is honest, not buried** — disclosures use `12px` Calibre `400` at readable contrast rather than being shrunk into invisibility. The "no fine print" promise extends to the typography of the fine print.

## 4. Component Stylings

### Buttons

**Primary Indigo**
- Background: `#4a4af4`
- Text: `#ffffff`
- Padding: `14px 28px`
- Radius: `96px` (near-pill)
- Font: 16px Calibre weight 600
- Hover: background → `#3a3ad6`, `translate-Y(-2px)`
- Use: primary CTA — "Get started", "Apply now", "Sign up"

**Secondary White Pill**
- Background: `#ffffff`
- Text: `#101820`
- Padding: `14px 28px`
- Radius: `96px`
- Font: 16px Calibre weight 600
- Hover: background → `#f6f6fb`
- Use: high-contrast secondary path on the dark canvas

**Ghost / Outlined**
- Background: transparent
- Text: `#ffffff`
- Border: `1px solid rgba(255,255,255,0.24)`
- Padding: `14px 28px`
- Radius: `96px`
- Hover: border → `rgba(255,255,255,0.4)`, background → `rgba(255,255,255,0.06)`
- Use: tertiary action on dark

**Text Link Button**
- Background: transparent
- Text: `#9fa0ff` (on dark) / `#4a4af4` (on light)
- Font: 14px Calibre weight 500
- Hover: underline appears
- Use: inline action — "Learn more", "See how it works →"

### Cards & Containers

**Light Card (default)**
- Background: `#ffffff`
- Text: `#101820`
- Radius: `24px`
- Padding: `24px`
- Shadow: `rgba(0,0,0,0.45) 0 24px 48px -24px`
- Use: feature cards inset into the dark canvas, lifted with deep soft shadow

**Dark Panel**
- Background: `#1c1c2b`
- Text: `#ffffff`
- Border: `1px solid rgba(255,255,255,0.12)`
- Radius: `24px`
- Padding: `24px`
- Use: elevated content that stays within the dark world

### Badges, Tags, Pills

**Indigo Chip (on dark)**
- Background: `rgba(74,74,244,0.18)`
- Text: `#7a7af7`
- Padding: `4px 12px`
- Radius: `96px`
- Font: 12px Calibre weight 500
- Use: eyebrow labels, status chips on the canvas

**Success Pill**
- Background: `rgba(31,157,85,0.16)`
- Text: `#0f7a3e` (on light) / mint `#7affc1` (on dark)
- Padding: `4px 12px`
- Radius: `96px`
- Use: "Approved", "0% APR" status

### Inputs & Forms

- Background: `#ffffff`
- Border: `1px solid #e2e2ec`
- Radius: `8px`
- Padding: `12px 16px`
- Label: `#101820`, 13px Calibre weight 500
- Text: `#101820`, 16px Calibre weight 400
- Placeholder: `#6b6b78`
- Focus: border → `#4a4af4` plus 3px ring `rgba(74,74,244,0.25)`
- Error: border `#d92d2d`, helper text `#d92d2d` 13px
- Note: inputs use a tighter `8px` radius (not the `96px` pill) — fields read as containers, only actions read as pills

### Navigation

- Dark sticky header over `#13131f` (or translucent `rgba(19,19,31,0.8)` with `backdrop-filter: blur(12px)`)
- Brand logotype left-aligned in `#ffffff`
- Links: Calibre 14px weight 500, `#ffffff` text, hover → `rgba(255,255,255,0.72)`
- Primary CTA right-aligned: indigo `#4a4af4` pill button (`96px` radius) — "Get started"
- Secondary: white pill or ghost button — "Sign in"
- Mobile: hamburger toggle; menu slides into a full dark overlay
- Dropdowns: `#1c1c2b` surface, `24px` radius, `rgba(255,255,255,0.12)` hairline border, deep shadow

## 5. Layout Principles

### Spacing System

- Base unit: `4px`
- Scale: `0, 4, 8, 12, 16, 24, 32, 48, 64, 96, 128`
- Density observation: tight and even at the small end (`4`–`16` for component internals), expanding to large jumps (`64`, `96`, `128`) for section rhythm. The `4px` base keeps UI precise; the large steps give the dark canvas room to breathe.

### Grid & Container

- Max content width: `~1280px`
- Prose/reading column: `~720px` for body-heavy sections
- Hero: centred or left-aligned single column, very large light headline, generous top/bottom padding
- Feature sections: 2–3 column grids of light cards inset on the dark ground
- Asymmetric hero common — large headline left, product illustration or payment-schedule mock right
- Gutter: `24px` between columns

### Whitespace Philosophy

- **Calm over density** — the dark canvas plus generous spacing is the trust register; emptiness reads as confidence, not waste.
- **Light cards as islands** — white content cards float in the dark with deep shadow and `24px` radius, creating clear figure-ground separation.
- **Air around the headline** — large light type is given substantial margin so the weight-300 display never feels crowded.

### Section Cadence

- Predominantly dark `#13131f` throughout, with occasional `#0c0c14` deep bands and full-white sections for high-contrast pivots (often a pricing/eligibility or "how it works" step block)
- Light card grids alternate with full-bleed illustrated dark bands to vary rhythm
- Section vertical padding: `96px`+ on desktop, contracting toward `48px` on mobile

## 6. Shapes & Radius Scale

| Tier | Value | Use |
|------|-------|-----|
| Micro | 2px | Fine inset details, tiny indicators |
| Standard | 4px | Subtle rounding, small chips |
| Comfortable | 8px | Inputs, selects, form fields |
| Relaxed | 12px | Small containers, nested panels |
| Large | 16px | Modals, dropdown menus |
| Card | 24px | Content cards, dark panels — the workhorse container radius |
| Pill | 96px | Buttons and tags — the signature near-pill action radius |
| Full | 9999px | Avatars, icon circles, toggle thumbs |

The radius scale has a deliberate gap: containers top out around `24px`, then jump straight to `96px` for action surfaces. That gap is intentional — it separates "things you read" (gently rounded cards) from "things you do" (emphatically rounded pills). On a short button, `96px` resolves to a full pill; on a wide one, a generous capsule. This is the brand's geometric thesis: actions are unmistakably soft, signalling the "no hidden fees, no sharp edges" promise. Inputs deliberately stay at `8px` so fields never get confused with actions.

## 7. Depth & Elevation

| Level | Treatment | Use |
|-------|-----------|-----|
| 0 — Flat | No shadow | Dark canvas background, inline text |
| 1 — Ambient | `rgba(0,0,0,0.28) 0 4px 12px` | Subtle dark-panel lift, hover hints |
| 2 — Soft | `rgba(0,0,0,0.28) 0 12px 28px -8px` | Dropdowns, dark popovers |
| 3 — Elevated | `rgba(0,0,0,0.45) 0 24px 48px -24px` | Light cards inset on the dark canvas |
| 4 — Deep | `rgba(0,0,0,0.55) 0 40px 80px -32px` | Modals, floating panels, hero product mocks |
| L — Light surface | `rgba(16,24,32,0.10) 0 8px 24px -8px` | Elements sitting on white surfaces |
| 5 — Ring | `0 0 0 3px rgba(74,74,244,0.25)` + `2px solid #4a4af4` | Keyboard focus ring |

**Shadow Philosophy** — Affirm's depth system is tuned for a dark world. Because the canvas is near-black, shadows must be genuinely dark (`rgba(0,0,0,0.45)`+) and large/soft to register at all — a faint shadow simply disappears on `#13131f`. Light cards therefore use deep, wide, top-offset shadows with strong negative spread, which lifts them off the ground like physical objects under soft overhead light. On the rare light surface, shadows flip to a subtle ink-tinted `rgba(16,24,32,0.10)` so elements still read as raised without the heavy darkness that dark-canvas cards need. There are no coloured or glow shadows — depth stays neutral so the rationed indigo never has to compete with it.

## 8. Interaction & Motion

### Easing Curves

- **Standard** `cubic-bezier(0.4, 0, 0.2, 1)` — default for most state transitions
- **Emphasized** `cubic-bezier(0.2, 0, 0, 1)` — hero entrances and large reveals
- **Out** `cubic-bezier(0, 0, 0.2, 1)` — exits and dismissals

### Duration Buckets

- Fast: `150ms` — colour swaps, hover ring fades, link underlines
- Standard: `240ms` — button hover, card lift, dropdown open
- Slow: `320ms` — modal entrance, hero reveals, payment-schedule animations

### Per-Component Micro-States

- **Button hover** — background colour shift + `translate-Y(-2px)` and shadow deepen over `240ms` standard ease. The pill geometry stays fixed.
- **Card hover** — shadow deepens from Level 3 to Level 4 and lifts `translate-Y(-2px)` over `240ms`.
- **Link hover** — underline animates in from 0 to 100% width over `150ms`; colour holds.
- **Input focus** — border → `#4a4af4` plus 3px ring `rgba(74,74,244,0.25)` over `150ms`.
- **Dropdown open** — opacity 0→1 + `translate-Y(-6px)` over `240ms` emphasized ease.
- **Payment-schedule reveal** — illustrative "4 payments / 0% APR" timelines stagger in over `320ms`, one node at a time, to dramatise the no-interest story.

### Page Transitions

- Marketing pages use standard browser navigation. In-viewport modules fade and rise (`opacity` + `translate-Y(16px)` → `0`) over `320ms` via Intersection Observer.

### Reduced Motion Strategy

- `@media (prefers-reduced-motion: reduce)` — all transitions degrade to opacity-only at `120ms` linear. Translate, scale, and the staggered schedule reveals are removed; auto-playing hero animation is paused and shown in its resting state.

## 9. Accessibility & A11y

### Contrast Pairs

- `#ffffff` text on `#13131f` canvas — **17.4:1** (AAA at all sizes)
- `rgba(255,255,255,0.72)` body on `#13131f` canvas — **~9.0:1** (AAA at body sizes)
- `#101820` ink on `#ffffff` light card — **16.9:1** (AAA at all sizes)
- `#ffffff` text on `#4a4af4` indigo button — **4.9:1** (AA at body sizes; AAA at 18px+/bold)
- `#9fa0ff` link on `#13131f` canvas — **5.1:1** (AA) — links are lifted from base indigo specifically to clear AA on dark
- `#4a4af4` link on `#ffffff` light surface — **5.0:1** (AA)
- `#0f7a3e` success text on `rgba(31,157,85,0.16)` over white — **~4.6:1** (AA)

Note: base `#4a4af4` on the `#13131f` canvas is ~3.3:1 — below AA for body text. This is why link text on dark uses the lifted `#9fa0ff`, and why the indigo on the canvas is used as a *fill* (with white text on top) rather than as text directly on the ground.

### Focus Indicators

- Default focus ring: `2px solid #4a4af4` plus a `3px` `rgba(74,74,244,0.25)` halo
- On the dark canvas the indigo ring sits against the lifted background and remains clearly visible
- Inputs use the same ring inset against their white field
- Focus is never removed without an equally visible replacement

### ARIA Patterns

- **Disclosure / Accordion** — `aria-expanded` on the trigger, `aria-controls` to the panel; used heavily for the FAQ and APR disclosures
- **Dialog** — `role="dialog"` `aria-modal="true"` with focus trap and `aria-labelledby` to the title
- **Tabs** — `role="tablist"` / `role="tab"` / `role="tabpanel"` with arrow-key navigation for "how it works" steppers
- **Listbox / Combobox** — `aria-activedescendant` for keyboard selection in store/merchant pickers

### Keyboard Navigation

- Tab order follows DOM source order; no `tabindex` overrides except `-1` for offscreen content
- Skip-to-content link in the header (visible on focus)
- `Esc` closes dropdowns, modals, and overlays
- Arrow keys navigate within tablists and comboboxes
- All pill buttons and links reachable and operable via keyboard

### Screen Reader Hints

- Icon-only buttons get `aria-label`; decorative icons get `aria-hidden="true"`
- Disclosures and APR figures use `aria-describedby` to associate legal text with the offer
- Live regions (`aria-live="polite"`) for inline form validation and eligibility results

### Reduced Motion

- Honoured via `prefers-reduced-motion: reduce` — payment-schedule and reveal animations are disabled; opacity-only fades retained for state legibility.

## 10. Responsive Behavior

### Breakpoints

| Name | Width | Key Changes |
|------|-------|-------------|
| Mobile | <640px | Single column, hero headline reduces sharply, cards stack |
| Tablet | 640–1024px | 2-column card grids, moderate padding |
| Desktop | 1024–1280px | Full layout, 3-column feature grids |
| Wide | ≥1280px | Centred `1280px` content with generous dark margins |

### Touch Targets

- Pill buttons keep `14px` vertical padding for a `≥44px` effective hit area
- Navigation links get `12–16px` horizontal spacing for tap forgiveness
- Tags/chips keep a minimum `12px` horizontal padding even at small sizes

### Collapsing Strategy

- Hero: `80px` display → ~`40px` on mobile, weight `300` maintained
- Navigation: horizontal links + CTA → hamburger with full-screen dark overlay menu
- Feature cards: 3-column → 2-column → single stacked, radius held at `24px`
- Primary CTA persists prominently on mobile, often pinned or repeated near the fold
- Section vertical padding: `96px+` → `48px` on mobile
- Payment-schedule illustrations: horizontal timeline → vertical stack on mobile

### Image Behavior

- Light cards and product mocks keep their `24px` radius and deep shadow at all sizes
- Hero illustrations simplify on mobile (fewer layers, no parallax)
- Dark panels retain hairline borders so edges stay legible against the canvas

### Container Queries

- Cards within a feature grid use container queries to switch from horizontal (icon + text side by side) to stacked layout when the card drops below ~320px wide, independent of viewport.

## 11. Content & Voice

### Tone

Honest, plain-spoken, reassuring. Affirm's voice is built around the absence of tricks: it states what something costs, what it doesn't cost, and what happens next, in clear short sentences. It never hypes and never hedges. The register is "we'll tell you the truth and it's good news" — confident calm rather than excitement.

### Microcopy Patterns

- **Button verbs** — `Get started`, `Apply now`, `See your options`, `Sign in`. Never `Click here`, never `Buy now pay later!!`.
- **The honesty refrain** — copy repeatedly surfaces `No hidden fees`, `No late fees`, `Know your total upfront`, `0% APR available`. The fee-honesty is the headline, not the footnote.
- **Error message recipe** — what happened + what to do: "We couldn't verify that. Double-check your details or try a different card."
- **Success confirmations** — terse and reassuring: `You're approved`, `Payment scheduled`, `All set`.
- **Legal/APR copy** — written to be read, not hidden: plain `12px` Calibre at readable contrast.

### Empty States

- Direct and calm: `Nothing here yet` followed by a primary pill CTA `See how it works` and a `Learn more →` link.
- No mascots, no apology, no "Oops!".
- Supporting line at `16px` Calibre `400` in muted white on dark.

### CTA Verb Conventions

- Primary: `Get started`, `Apply now`, `Sign up`
- Secondary: `See your options`, `How it works`, `Sign in`
- Tertiary: `Learn more →` (with right-arrow glyph)

## 12. Dark Mode & Theming

Affirm's marketing surface is **dark by default** (`#13131f` canvas) — there is no separate light/dark toggle on the marketing site; the dark world *is* the brand. Light appears only as inset surfaces (`#ffffff` cards) and the occasional full-white pivot section.

Within the default dark world:
- Background: `#13131f` (deep bands `#0c0c14`)
- Text: `#ffffff` for headings, `rgba(255,255,255,0.72)` for body
- Borders: `rgba(255,255,255,0.12)` hairlines
- Cards: `#ffffff` light islands (Level-3 deep shadow) or `#1c1c2b` dark panels
- CTA: indigo `#4a4af4` — colour does not change between contexts
- Links: `#9fa0ff` on dark, `#4a4af4` on light surfaces

Implementations targeting an Affirm-flavour *light* theme (e.g. an app surface) can map:
- `bg` `#13131f` → `#ffffff`
- `text-on-dark` `#ffffff` → `text` `#101820`
- `surface` `#1c1c2b` → `surface-light` `#ffffff`
- `border` `rgba(255,255,255,0.12)` → `border-light` `#e2e2ec`
- `link` `#9fa0ff` → `#4a4af4`
- `brand` `#4a4af4` stays — the indigo is brand-locked and used identically in both worlds

## 13. Lineage & Influences

Affirm sits at the intersection of two fintech traditions. The first is the editorial light-weight headline that Stripe brought to the category — display type set at weight `300`, set huge, this time white on a dark stage. The second is the friendly geometry of the consumer-lending wave (Klarna, Cash App), where very-rounded buttons soften the anxiety inherent in borrowing money. Affirm's distinctive synthesis is to run that approachable geometry on a serious, confident dark canvas rather than the bright white most BNPL brands default to. The result reads as calm rather than cheerful: a financial product that signals trust through restraint and rounded edges instead of exclamation marks.

The typography carries two foundry pedigrees. Axiforma for Affirm — a custom geometric grotesque — gives the display voice its premium, editorial lightness, while Calibre, Klim Type Foundry's humanist grotesque (the same family behind the UK government's identity system), gives the body its warm legibility. The radius is the whole brand thesis distilled into a single token: a `96px` near-pill on a CTA is the literal form of "no hidden fees, no sharp edges, nothing that catches." Affirm rejects gradient maximalism, warm playful pastels, and legacy corporate-blue conservatism alike — its discipline (one accent, dark ground, light type, soft pills) *is* the message. The dark-first product aesthetic owes something to Linear's near-black grounds and hairline borders, repurposed from developer tooling to consumer finance.

**Named influences:**
- Calibre (Klim Type Foundry) — body typeface, humanist grotesque for running text and UI
- Stripe — light-weight (300) display headline convention in fintech marketing
- Klarna — consumer-BNPL register, very-rounded friendly buttons
- Cash App — confident dark-canvas fintech with a single saturated accent
- Linear — dark-first aesthetic, hairline borders, restrained accent discipline

## 14. Do's and Don'ts

### Do

- Use the deep near-black canvas `#13131f` as the default ground — dark is the brand
- Set hero headlines in Axiforma at weight `300`, large, white — lightness reads premium
- Round every CTA and tag to the `96px` near-pill — the soft geometry IS the honesty message
- Ration the indigo `#4a4af4` to action surfaces only — links, primary buttons, focus
- Use white pill buttons as the high-contrast secondary path on dark
- Set body text on dark at `rgba(255,255,255,0.72)`, not pure white, for comfortable reading
- Float light `#ffffff` cards on the dark canvas with deep soft shadows and `24px` radius
- Keep inputs at `8px` radius — fields are containers, only actions are pills
- Lift link text to `#9fa0ff` on dark so it clears AA contrast against the canvas
- Write APR/legal copy to be read — plain `12px` Calibre at honest contrast, never buried
- Use hairline `rgba(255,255,255,0.12)` borders instead of solid rules on the canvas
- Pair one indigo primary pill with a white or ghost secondary — never two filled colours

### Don't

- Don't use a bright white background as the default surface — Affirm's ground is dark
- Don't use sharp or small (`4–8px`) radii on buttons — CTAs must be near-pill `96px`
- Don't introduce a second accent colour — indigo is the only chromatic action colour
- Don't put base `#4a4af4` as text directly on the dark canvas — it fails AA; use it as a fill or lift to `#9fa0ff`
- Don't set hero headlines bold (`600`+) — the light `300` weight is the signature
- Don't use Axiforma for body copy — switch to Calibre at H4 and below
- Don't add gradients or glow shadows to UI — depth stays neutral, colour stays rationed
- Don't shrink or hide the fine print — the "no hidden fees" promise extends to its typography
- Don't use warm accents (orange, yellow) for interactive elements — indigo is primary
- Don't pill-round input fields — keep them at `8px` so they read as containers, not actions
- Don't use faint shadows on the dark canvas — they vanish; cards need deep `rgba(0,0,0,0.45)`+ lift
- Don't use pure black `#000000` as the ground — the `#13131f` blue-violet ink is warmer and on-brand

## 15. Agent Prompt Guide

### Quick Color Reference

- Canvas (background): Deep Ink `#13131f`
- Heading text on dark: White `#ffffff`
- Body text on dark: `rgba(255,255,255,0.72)`
- Ink (text on light cards): `#101820`
- Primary CTA: Affirm Indigo `#4a4af4`
- CTA Hover: Indigo `#3a3ad6`
- Link on dark: Lifted Indigo `#9fa0ff`
- Light card surface: White `#ffffff`
- Border (on dark): `rgba(255,255,255,0.12)`
- Success: `rgba(31,157,85,0.16)` bg / `#0f7a3e` text
- Accent (decorative): Mint `#7affc1`

### Example Component Prompts

- "Create a hero section on a deep dark background `#13131f`. Headline at 80px Axiforma weight 300, line-height 1.0, letter-spacing -0.03em, color `#ffffff`. Subtitle at 18px Calibre weight 400, line-height 1.55, color `rgba(255,255,255,0.72)`. Indigo CTA pill (`#4a4af4`, 96px radius, 14px 28px padding, white text, Calibre 16px weight 600) plus a white secondary pill (`#ffffff` bg, `#101820` text, 96px radius)."
- "Design a feature card: white background `#ffffff`, 24px radius, 24px padding, shadow `rgba(0,0,0,0.45) 0 24px 48px -24px`, sitting on a dark `#13131f` canvas. Title at 24px Axiforma weight 500, color `#101820`. Body at 16px Calibre weight 400, color `#4a4a57`."
- "Build an indigo chip badge on the dark canvas: `rgba(74,74,244,0.18)` background, `#7a7af7` text, 96px radius, 4px 12px padding, 12px Calibre weight 500."
- "Create navigation: dark sticky header over `#13131f` with `backdrop-filter: blur(12px)`. Calibre 14px weight 500 links in white. Right-aligned indigo pill CTA 'Get started' (`#4a4af4`, 96px radius, white text) plus a ghost 'Sign in' (transparent, 1px solid `rgba(255,255,255,0.24)`, white text, 96px radius)."
- "Design a payment-schedule module: four nodes on a dark `#13131f` background showing '4 interest-free payments'. Numbers in Axiforma weight 300, labels in Calibre 13px weight 500 at `rgba(255,255,255,0.72)`. Active node highlighted with indigo `#4a4af4`. Reveal nodes with a 320ms staggered fade-and-rise."
- "Build a form: white input field, `#e2e2ec` border, 8px radius, 12px 16px padding, label 13px Calibre weight 500 `#101820`. On focus, border → `#4a4af4` with a 3px `rgba(74,74,244,0.25)` ring. Submit is a 96px-radius indigo pill button."

### Iteration Guide

1. Start dark — the canvas is `#13131f`, not white. If the surface is light, you've drifted from the brand.
2. Round CTAs hard — buttons and tags use `96px` radius (near-pill); this is the single most identifying token.
3. Keep inputs at `8px` — fields are containers, not actions; never pill-round them.
4. Set the hero headline in Axiforma weight `300`, large and white — light, not bold, is the signature.
5. Ration the indigo — `#4a4af4` only on actions, links, and focus. If you reach for a second accent colour, stop.
6. On dark, body text is `rgba(255,255,255,0.72)`; links are lifted `#9fa0ff` (base indigo fails AA as text on the canvas).
7. Make card shadows deep — `rgba(0,0,0,0.45)`+ with wide spread, or they vanish on the dark ground.
8. Keep the fee-honesty copy loud and the legal copy legible — "no hidden fees" is the message, and even the fine print is readable.
