---
version: alpha
name: SoFi
website: "https://www.sofi.com"
description: >-
  SoFi's marketing canvas is the all-in-one finance app argument rendered as a bright white catalogue stacked on top of a deep aubergine "#211747" payday band — a teal-voltage CTA "#00a2c7" anchors every primary action, Larsseit weight 800 carries display from a 50px hero down to a 28px section opener with a tight -1.4px negative tracking, and TT Norms at weight 400 handles the body register at 14/21 with weight 700 reserved for label and button text. Buttons sit at a 12px radius (8px 18px padding, 40px tall, "127px" CTA width), cards fan across a 20px / 4px / 12px / 15px radius scale, and the brand alternates white catalogue rows against the aubergine band with no gradient transitions.
seo:
  title: "SoFi Design System for React — Teal #00a2c7, Larsseit 800, 19 components"
  metaDescription: "SoFi's all-in-one finance design system as a DESIGN.md file. Teal #00a2c7, Larsseit 800, 19 colors, 19 components. For React, Next.js, and AI tools."
  highlights:
    - "Teal voltage as the click — #00a2c7 fills the `Get Started` CTA at 12px radius, while a deeper #00819d carries link text and the nav-link register"
    - "Larsseit 800 for display — the 50px hero ('Save on summer stays') tracks tight at -1.4px, and the 36px and 28px tiers step down at -0.5px and -0.784px"
    - "Two-mode rhythm — white #ffffff catalogue bands slam against an aubergine #211747 payday band with no soft transition"
    - "TT Norms 14/21 carries body — the workhorse text token at weight 400 (98 occurrences), with weight 700 reserved for button and label text"
    - "20px and 12px radii dominate — 20px (frequency 18) lands on the rounded card chrome, 12px (frequency 8) on the CTA pill, with 4px on inline tags"
  tags:
    - "Banking & Payments"
    - "Fintech & Crypto"
  lastUpdated: "2026-05-13"
  author:
    name: "Dov Azencot"
    url: "https://x.com/dovazencot"
  opening: |
    SoFi's marketing canvas is the visual argument for a consumer finance app that bundles banking, borrowing, and investing into one stack. The page opens on a near-white "#ffffff" canvas — the literal `theme-color` meta value — with text in "#212121" (frequency 666) and a deeper aubergine "#211747" (frequency 337) doing the secondary heavy-lift across the payday band and dark feature cards. The single brand voltage, teal "#00a2c7", lands on exactly one place at a time: the `Get Started` CTA in the top nav (`a#main-nav-cta`, 127px wide, 40px tall, 12px radius). A deeper teal "#00819d" handles link text and the logo-anchored nav-link register. Display type is Larsseit at the single workhorse weight 800 — a heavyweight grotesque scaling from 28 to 50px with tight negative tracking (-0.5 to -1.4px). Body type is TT Norms at 14/21 weight 400, with weight 700 reserved for button labels and `h3` headings.

    This page packages the SoFi marketing surface into a single DESIGN.md file built on the Google Labs DESIGN.md specification. Inside the spec: 19 color tokens grouped into brand-voltage, structural ink, and aubergine-payday roles; 11 typography tokens spanning a 50px Larsseit 800 hero down to a 12px TT Norms caption with the full weight stack (400, 500, 700, 800); 6 radius tokens including the load-bearing 20px card corner, the 12px CTA, and a 500px pill; 9 spacing tokens climbing from a 5px micro to an 80px section band; and 19 component tokens covering buttons, the dark hero card, the rounded product feature card, top nav, FAQ rows, and the disclosure footer. Every hex is quoted; every radius and padding lands as an exact pixel string.

    A working React or Next.js developer drops the file into Claude, Cursor, or GitHub Copilot and the agent reproduces SoFi's two-mode catalogue rhythm rather than a generic neobank dashboard. Tokens map onto Tailwind config or CSS variables, and components reference each other by name. The system is worth studying for one disciplined choice: where most consumer-fintech brands (Chime, Cash App, Acorns) lean on a single voltage that fills hero CTAs and inline links alike, SoFi splits the teal into two registers — bright "#00a2c7" for click-the-button moments and deeper "#00819d" for click-the-link moments. The split keeps the voltage from carpeting the page.
  related:
    - href: "/design"
      title: "Browse all design systems"
      description: "The full directory of DESIGN.md files on shadcn.io, with live mockups for each."
    - href: "https://www.sofi.com"
      title: "SoFi — official site"
      description: "The all-in-one finance app marketing canvas — source of every hex, font, and radius in this spec."
    - href: "https://github.com/google-labs-code/design.md"
      title: "The DESIGN.md specification"
      description: "Google Labs' open spec for machine-readable design system files — the format this page is built on."
  questions:
    - id: "primary-color"
      title: "What is SoFi's primary brand color and how is it used?"
      answer: "Teal — `#00a2c7`, the brand voltage that fills the `Get Started` CTA at the top of every page (`a#main-nav-cta`, 127px × 40px, 12px corner radius, white text). It is the only color tagged `layer: brand` in the extraction. Frequency on the captured surface is 37 total occurrences — 14 as a fill, 12 as a border, 10 as text, 1 inside a gradient. A deeper companion `#00819d` (frequency 76, layer:structural) carries link text and the nav-link register including the `Sofi homepage` logo anchor — the brand splits the teal into a CTA register and a link register rather than running a single voltage. Body text never carries either teal; that work falls to `#212121` and `#211747`."
    - id: "typography"
      title: "What typography does SoFi use, and what should I use if Larsseit isn't available?"
      answer: "SoFi runs two typeface families: Larsseit at the single workhorse weight 800 for every display tier (28-50px) and section heading, and TT Norms at weights 400, 500, 700 for body, nav, inputs, and button labels. Display sizes track tight: the 50px hero at -1.4px, the 36px section opener at -0.5px, the 28px scene heading at -0.784px. Body type uses zero or near-zero tracking. When Larsseit is unavailable, Inter at weight 800 is the closest open-source path; alternatively Gilroy or Greycliff CF render the same blocky-grotesque silhouette. For TT Norms substitutes, Inter at 400/700 or Roobert lands close. Clamp display line-height to roughly 1.2× (60px on 50px, 33.6px on 28px) and keep negative tracking on the heavy weights."
    - id: "voltage-split"
      title: "Why does SoFi split its teal into two hex values instead of using one?"
      answer: "The marketing canvas runs two teals — `#00a2c7` (layer:brand) and `#00819d` (layer:structural) — and they do different jobs. `#00a2c7` is the lighter teal reserved for filled CTA pills like `Get Started` (white text on teal, 12px radius). `#00819d` is the deeper teal reserved for link text, the `Sofi homepage` logo anchor, and the nav-link register. The split is deliberate: it keeps the brand voltage from spreading across every link on the page, which would dilute the CTA's pull. Most consumer-fintech brands use a single voltage for both jobs; SoFi reserves the brighter teal for the click and the deeper teal for the read."
    - id: "two-mode-rhythm"
      title: "What is the two-mode rhythm and how strict is it?"
      answer: "The marketing canvas alternates two structural background colors in full-bleed bands: white `#ffffff` for catalogue rows (product feature grids, FAQ accordions, link lists) and aubergine `#211747` for payday and storytelling bands (dark cards, the hero overlay when a photographic background is in play). The two switch with hard edges — no gradient transitions, no soft overlays. Inside aubergine bands, white `#ffffff` carries text (the `hero-heading` is white-on-dark at 50px / Larsseit 800 / -1.4px); inside white bands, `#212121` carries text and `#00819d` carries links. The deep navy `#211747` is the third structural fill, frequency 337 (148 as text, 23 as background, 166 as border)."
    - id: "radius-scale"
      title: "Why does SoFi run a 20px / 12px / 4px radius scale instead of an 8px-based grid?"
      answer: "The captured radius scale collapses to four dominant values: 20px (frequency 18, the workhorse card corner), 12px (frequency 8, the CTA pill plus mid-size cards), 4px (frequency 10, inline tags and table chrome), and 15px (frequency 8, an oddly specific mid-step for product mockup cards). A 500px pill and a 100px softer-corner card variant complete the scale. The brand's choice of 15px alongside 12px is unusual — most systems collapse to a single mid-radius. Avoid 16px or 8px corners (they don't appear in the captured stylesheet) and never use a 0px sharp corner on a feature card."
    - id: "known-gaps"
      title: "What's missing from this DESIGN.md spec?"
      answer: "A few items, documented in the Known Gaps section: precise hover, pressed, and focus states across button variants are not captured — only the base CTA is documented and the extractor flagged the input component as null on the home surface. The authenticated dashboard surfaces (transactions, accounts, investing, lending) are out of scope; only the public marketing canvas at sofi.com is in this spec. The illustrated yellow `#fbd974` and salmon `#f2817d` highlight tones appear as decoration-only in product mockup tiles and are listed as accents but not assigned to interactive surfaces. Mobile-app screenshot art direction and the regulatory disclosure block are described in prose but not enumerated."

colors:
  primary: "#00a2c7"
  primary-deep: "#00819d"
  on-primary: "#ffffff"
  ink: "#212121"
  ink-mute: "#424242"
  ink-faint: "#575757"
  aubergine: "#211747"
  aubergine-deep: "#211747"
  canvas-light: "#ffffff"
  canvas-mist: "#eae9e9"
  surface-default: "#ffffff"
  surface-payday: "#211747"
  hairline-light: "#b9b9b9"
  hairline-deep: "#211747"
  accent-butter: "#fbd974"
  accent-salmon: "#f2817d"
  accent-sky: "#6699cc"
  on-dark: "#ffffff"
  scrim: "#000000"

typography:
  display-hero:
    fontFamily: "Larsseit, Helvetica, Arial, sans-serif"
    fontSize: 50px
    fontWeight: 800
    lineHeight: 1.2
    letterSpacing: "-1.4px"
  display-lg:
    fontFamily: "Larsseit, Helvetica, Arial, sans-serif"
    fontSize: 36px
    fontWeight: 800
    lineHeight: 1.0
    letterSpacing: "-0.5px"
  display-md:
    fontFamily: "Larsseit, Helvetica, Arial, sans-serif"
    fontSize: 28px
    fontWeight: 800
    lineHeight: 1.2
    letterSpacing: "-0.784px"
  heading-sm:
    fontFamily: "Larsseit, Helvetica, Arial, sans-serif"
    fontSize: 20px
    fontWeight: 700
    lineHeight: 1.2
    letterSpacing: "-0.56px"
  label-bold:
    fontFamily: "Larsseit, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 700
    lineHeight: 1.2
    letterSpacing: "0"
  body-lg:
    fontFamily: "TT Norms, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: "0"
  body-md:
    fontFamily: "TT Norms, Helvetica, Arial, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: "0"
  body-sm:
    fontFamily: "TT Norms, Helvetica, Arial, sans-serif"
    fontSize: 12.8px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: "0"
  button-md:
    fontFamily: "TT Norms, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 700
    lineHeight: 1.25
    letterSpacing: "0"
  caption:
    fontFamily: "TT Norms, Helvetica, Arial, sans-serif"
    fontSize: 12px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: "0"
  caption-bold:
    fontFamily: "TT Norms, Helvetica, Arial, sans-serif"
    fontSize: 12px
    fontWeight: 700
    lineHeight: 1.5
    letterSpacing: "0"

rounded:
  none: "0px"
  xs: "4px"
  sm: "12px"
  md: "15px"
  lg: "20px"
  xl: "100px"
  pill: "500px"

spacing:
  xxs: "5px"
  xs: "8px"
  sm: "9px"
  md: "12px"
  base: "18px"
  lg: "20px"
  xl: "30px"
  2xl: "40px"
  3xl: "80px"

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.sm}"
    padding: "8px 18px"
    height: "40px"
    border: "1px solid {colors.primary}"
  button-primary-hover:
    backgroundColor: "{colors.primary-deep}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.sm}"
    padding: "8px 18px"
    height: "40px"
    border: "1px solid {colors.primary-deep}"
  button-secondary:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.button-md}"
    rounded: "{rounded.sm}"
    padding: "8px 18px"
    height: "40px"
    border: "1px solid {colors.ink}"
  button-ghost:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.primary-deep}"
    typography: "{typography.button-md}"
    rounded: "{rounded.sm}"
    padding: "8px 18px"
    height: "40px"
    border: "0"
  button-payday:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.sm}"
    padding: "9px 30px"
    height: "40px"
    border: "0"
  text-input:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.body-md}"
    rounded: "{rounded.xs}"
    padding: "12px"
    height: "44px"
    border: "1px solid {colors.hairline-light}"
  top-nav:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.body-md}"
    rounded: "{rounded.none}"
    padding: "12px 40px"
    height: "72px"
    border: "0"
  nav-link:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.primary-deep}"
    typography: "{typography.body-md}"
    rounded: "{rounded.none}"
    padding: "12px"
    height: "24px"
    border: "0"
  card-feature:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.body-md}"
    rounded: "{rounded.lg}"
    padding: "20px"
    border: "1px solid {colors.hairline-light}"
  card-product-mockup:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.body-md}"
    rounded: "{rounded.md}"
    padding: "20px"
    border: "1px solid {colors.hairline-light}"
  card-payday:
    backgroundColor: "{colors.aubergine}"
    textColor: "{colors.on-dark}"
    typography: "{typography.body-md}"
    rounded: "{rounded.lg}"
    padding: "30px"
    border: "0"
  hero-heading:
    backgroundColor: "{colors.aubergine}"
    textColor: "{colors.on-dark}"
    typography: "{typography.display-hero}"
    rounded: "{rounded.none}"
    padding: "0"
    border: "0"
  section-heading:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.display-lg}"
    rounded: "{rounded.none}"
    padding: "0"
    border: "0"
  pill-tag:
    backgroundColor: "{colors.canvas-mist}"
    textColor: "{colors.ink}"
    typography: "{typography.caption-bold}"
    rounded: "{rounded.xs}"
    padding: "4px 8px"
    border: "0"
  link-inline:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.primary-deep}"
    typography: "{typography.body-md}"
    rounded: "{rounded.none}"
    padding: "0"
    border: "0"
  disclosure-footer:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink-faint}"
    typography: "{typography.caption}"
    rounded: "{rounded.none}"
    padding: "80px 40px 40px"
    border: "0"
  faq-row:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink}"
    typography: "{typography.label-bold}"
    rounded: "{rounded.none}"
    padding: "20px 0"
    border: "1px solid {colors.hairline-light}"
  app-download-tile:
    backgroundColor: "{colors.ink}"
    textColor: "{colors.on-dark}"
    typography: "{typography.button-md}"
    rounded: "{rounded.xl}"
    padding: "12px 30px"
    height: "48px"
    border: "0"
  logo-strip-cell:
    backgroundColor: "{colors.canvas-light}"
    textColor: "{colors.ink-mute}"
    typography: "{typography.body-md}"
    rounded: "{rounded.none}"
    padding: "20px"
    border: "0"
---

## Overview

SoFi's marketing surface opens on a near-white "#ffffff" canvas — the literal `theme-color` meta value — carrying "#212121" body text at frequency 666 and a deep aubergine "#211747" (frequency 337) doing the secondary structural work on payday bands and dark feature cards. The single brand voltage, teal "#00a2c7", appears on exactly one place at a time: the `Get Started` CTA in the top nav (`a#main-nav-cta`), rendered as a 127px × 40px pill at 12px radius with white text. A deeper teal "#00819d" (frequency 76, layer:structural) carries link text and the nav-link register including the `Sofi homepage` logo anchor. Display type runs Larsseit at the single workhorse weight 800 — a heavyweight grotesque — scaling from a 28px section opener up to a 50px hero with tight negative tracking. Body type runs TT Norms 14/21 at weight 400, with weight 700 reserved for button labels and `h3` headings.

**Split voltage as discipline**: Where most consumer-fintech brands (Chime, Cash App, Acorns) run a single voltage that fills CTAs and inline links alike, SoFi splits its teal into two registers — bright "#00a2c7" reserved for the click-the-button moments, deeper "#00819d" reserved for the click-the-link moments. The split keeps the voltage from carpeting the page and preserves the CTA's pull. **Weight 800 as the only display register**: Where Mercury runs Arcadia Display at weight 480 and Stripe runs Sohne at weight 300, SoFi runs Larsseit at a single committed weight 800 across every display tier from 28 to 50px — no medium, no semibold, no italic. The system signals confidence through heavyweight typographic uniformity. **Negative tracking on the heavy weights**: Larsseit 800 at 50px tracks -1.4px, at 36px tracks -0.5px, at 28px tracks -0.784px — the heavier the weight, the tighter the leading, which is the inverse of the looser-tracked display convention that Mercury and Monzo follow.

**Key Characteristics:**
- Two-teal split — "#00a2c7" reserved for CTA fills, "#00819d" reserved for link text and nav anchors, never crossed.
- Larsseit 800 as the only display weight — every heading 20-50px renders at the same heavyweight grotesque.
- Negative tracking scales with weight — -1.4px at 50px down to -0.5px at 36px, locked to display sizes only.
- Two-mode rhythm — white "#ffffff" catalogue bands slam against the aubergine "#211747" payday band with no soft transition.
- 12px CTA radius on a 20px card scale — the button pill is tighter than the card it sits inside.
- TT Norms 14/21 as the body workhorse — frequency 98, weight 400, never bolded for body prose.
- One filled CTA per band — the `Get Started` pill repeats but the cyan voltage never doubles within a single hero.

## Colors

> **Source pages:** home (`/`), top nav with the `Get Started` CTA, the aubergine payday hero band, the white product feature grid (Banking / Loans / Invest / Credit Card), the logo strip, and the disclosure footer.

### Brand & Accent
- **Teal** (`{colors.primary}` — "#00a2c7") — frequency 37. Used as text (10), bg (14), border (12), gradient (1). The brand's load-bearing voltage. Reserved for filled CTAs — `a#main-nav-cta` `Get Started` at 12px radius, white text, 127px wide. Tagged `layer: brand` in the extraction, the only color so tagged.
- **Teal Deep** (`{colors.primary-deep}` — "#00819d") — frequency 76. Used as text (38), border (38). The link register: `Sofi homepage` logo anchor, inline nav links, body-prose hyperlinks. Tagged `layer: structural` because it never fills a button. The two teals are the same family, two stops apart, and the brand keeps them off each other's territory.
- **Accent Butter** (`{colors.accent-butter}` — "#fbd974") — frequency 4. Used as text (2), border (2). A pale yellow scoped to illustrated product-mockup highlights and accent dots inside product feature cards. Decoration-only, never on buttons.
- **Accent Salmon** (`{colors.accent-salmon}` — "#f2817d") — frequency 2. Used as text (1), border (1). A warm coral-pink scoped to illustration art and seasonal-promotion accents.
- **Accent Sky** (`{colors.accent-sky}` — "#6699cc") — frequency 1. A pale blue used in illustrated product mockups only.

### Surface
- **Canvas Light** (`{colors.canvas-light}` — "#ffffff") — frequency 1082. The marketing default. Used as text (551 — for white-on-dark text inside aubergine bands), bg (24), border (504). Pure white, with a meta `theme-color` token to match.
- **Canvas Mist** (`{colors.canvas-mist}` — "#eae9e9") — frequency 1 (bg). A pale gray scoped to soft pill-tag fills and the rare second-step interlude card on the light track.
- **Surface Payday** (`{colors.surface-payday}` — "#211747") — frequency 337. Used as text (148), bg (23), border (166). The aubergine band fill, dark feature card background, and dark-mode text token on inverted-light surfaces.

### Text
- **Ink** (`{colors.ink}` — "#212121") — frequency 666. Used as text (347), border (319). The workhorse body color, carries every catalogue paragraph and section opener on the light canvas. Off-black, never pure "#000000".
- **Ink Mute** (`{colors.ink-mute}` — "#424242") — frequency 42. Used as text (21), border (21). Secondary text — captions, footer columns, table labels.
- **Ink Faint** (`{colors.ink-faint}` — "#575757") — frequency 10 (shadow only). A shadow color, scoped to drop shadows on elevated cards and floating panels rather than text. The brand's shadow color isn't gray-on-white — it's a mid-gray scoped to depth specifically.

### Hairlines
- **Hairline Light** (`{colors.hairline-light}` — "#b9b9b9") — frequency 10 (border). The 1px border on form inputs, FAQ row dividers, and the rare light-track card outline. WordPress preset `--wp--preset--color--cyan-bluish-gray`.
- **Hairline Deep** (`{colors.hairline-deep}` — "#211747") — frequency 166 (border). The aubergine doubles as the 1px border color on payday-card chrome.

### Semantic
- **Scrim** (`{colors.scrim}` — "#000000") — frequency 22 (17 of which are shadow). Used as shadow color on box-shadows. Pure black is reserved for shadow only — never used as a text or fill color anywhere on the captured surface.

## Typography

### Font Family

SoFi runs two families: **Larsseit** for every display tier (28-50px) and the section-heading register at 20px / 700, and **TT Norms** for body, nav, inputs, button labels, and captions. Larsseit ships as a heavyweight grotesque at the single workhorse weight 800; the brand never drops to 600 or steps up to a 900. TT Norms runs at weights 400 (body), 500 (the nav-link `Sofi homepage` anchor), and 700 (button labels, `h3` headings, strong emphasis).

When Larsseit is unavailable, Inter at weight 800 is the closest open-source path; alternatively Gilroy, Greycliff CF, or General Sans render the same blocky-grotesque silhouette. For TT Norms substitutes, Inter at 400/500/700 lands close, or Roobert if a slightly humanist alternative is preferred. Clamp display line-height to roughly 1.2× (60px on the 50px hero, 33.6px on the 28px scene heading) and keep negative tracking on the heavy weights.

### Hierarchy

| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| `{typography.display-hero}` | 50px | 800 | 1.2 | -1.4px | Hero `h2` ("Save on summer stays. Splurge on summer fun.") |
| `{typography.display-lg}` | 36px | 800 | 1.0 | -0.5px | Section opener ("Bank, borrow, and invest.") |
| `{typography.display-md}` | 28px | 800 | 1.2 | -0.784px | Scene heading inside product feature card |
| `{typography.heading-sm}` | 20px | 700 | 1.2 | -0.56px | Card title, FAQ row label |
| `{typography.label-bold}` | 16px | 700 | 1.2 | 0 | Section eyebrow, callout label |
| `{typography.body-lg}` | 16px | 400 | 1.5 | 0 | Hero supporting copy, marketing paragraph lead |
| `{typography.body-md}` | 14px | 400 | 1.5 | 0 | Body workhorse — frequency 98 across `<a>`, `<p>`, `<span>` |
| `{typography.body-sm}` | 12.8px | 400 | 1.5 | 0 | Compact paragraph register — frequency 75 |
| `{typography.button-md}` | 16px | 700 | 1.25 | 0 | Button text, `Get Started` CTA, payday `Apply now` |
| `{typography.caption}` | 12px | 400 | 1.5 | 0 | Footer disclosure, fine print — frequency 45 |
| `{typography.caption-bold}` | 12px | 700 | 1.5 | 0 | Pill-tag text, table header `<th>` |

### Principles

- **Larsseit 800 across every display tier.** No medium-weight display variant exists in the captured stylesheet. The brand commits to one heavy weight for the entire display register.
- **Negative tracking scales with size.** The 50px hero tracks -1.4px; the 36px section opener tracks -0.5px; the 28px scene heading tracks -0.784px. Drop tracking to zero at 20px and below.
- **TT Norms 14/21 carries body.** The workhorse body token is 14px / 400 / 21px line-height, never bolded for body prose. Bold weight 700 is reserved for button labels and `h3` headings.
- **Two families, no overlap.** Larsseit never appears at body sizes; TT Norms never appears at display sizes 28px and up.

### Note on Font Substitutes
Larsseit is a commercial license (Type Dynamic). Inter at weight 800 with `letter-spacing: -1.4px` at 50px is the closest open-source analogue. TT Norms (TypeType) substitutes well to Inter at 400/500/700 with zero tracking. Avoid Helvetica or Roboto — both lack Larsseit's slightly squared grotesque silhouette.

## Layout

### Spacing System
- **Base unit**: a non-conventional 5px micro (frequency 81), with 12px (frequency 54) doing the mid-range work and 20px (frequency 14) carrying section-internal rhythm.
- **Tokens**: `{spacing.xxs}` 5px · `{spacing.xs}` 8px · `{spacing.sm}` 9px · `{spacing.md}` 12px · `{spacing.base}` 18px · `{spacing.lg}` 20px · `{spacing.xl}` 30px · `{spacing.2xl}` 40px · `{spacing.3xl}` 80px.
- **Section padding**: `80px 40px 40px` is the dominant section-wrapper shorthand (frequency 13) — generous 80px above, tight 40px sides, 40px below.
- **CTA padding**: `8px 18px` on the `Get Started` pill, `9px 30px` on the wider payday `Apply now` button.
- **Inline pill padding**: `6px 8px` on small tags (frequency 10).

### Grid & Container
- The brand's WordPress-preset spacing scale runs at `0.44rem / 0.67rem / 1rem / 1.5rem / 2.25rem / 3.38rem / 5.06rem`, which maps to roughly 7 / 11 / 16 / 24 / 36 / 54 / 81px on a 16px root.
- Section bands run full-bleed; content max-width is held by the `80px 40px` horizontal padding shorthand and an implicit inner container.

### Whitespace Philosophy
SoFi runs a non-conventional 5px micro spacing as the dominant value (frequency 81) — the brand favors tight inner gaps inside cards and pill chrome rather than the customary 4 or 8px atomic unit. Section padding climbs to 80px vertical, so the rhythm is "tight inside, loose outside" — generous air between bands, compact spacing within them.

## Elevation & Depth

| Level | Treatment | Use |
|---|---|---|
| 0 | Flat white canvas | Default surface "#ffffff" |
| 1 | 1px "#b9b9b9" hairline | Form inputs, FAQ rows, light-track card outlines |
| 2 | `box-shadow` with "#575757" or "#000000" at low alpha | Floating product feature cards, elevated tiles |
| 3 | Aubergine band "#211747" | The two-mode break — payday cards and dark hero overlay sit on this fill |

### Decorative Depth
The captured page declares `--wp--preset--shadow--natural: 6px 6px 9px rgba(0,0,0,0.2)`, `--wp--preset--shadow--sharp: 6px 6px 0px rgba(0,0,0,0.2)`, `--wp--preset--shadow--crisp: 6px 6px 0px rgb(0,0,0)`, and `--wp--preset--shadow--deep: 12px 12px 50px rgba(0,0,0,0.4)`. SoFi prefers the offset-only shadows (`sharp` and `crisp`) for the hand-drawn-card feel on illustrated product tiles, and reserves the blur-heavy `natural` and `deep` for floating panels above the aubergine band.

## Shapes

### Border Radius Scale

| Token | Value | Use |
|---|---|---|
| `{rounded.none}` | 0px | Top nav, body text, hero copy — flat geometry |
| `{rounded.xs}` | 4px | Pill tags, inline chips, table chrome (frequency 10) |
| `{rounded.sm}` | 12px | The `Get Started` CTA, mid-size cards (frequency 8) |
| `{rounded.md}` | 15px | Product mockup card chrome — the oddly specific mid-step (frequency 8) |
| `{rounded.lg}` | 20px | The workhorse card corner — feature cards, payday cards (frequency 18) |
| `{rounded.xl}` | 100px | Soft-corner CTA on the app download band (frequency 2) |
| `{rounded.pill}` | 500px | The rare maximally-rounded pill — circle indicators and avatar dots (frequency 1) |

### Geometry Note
The 15px radius is the unusual one. Most systems collapse mid-range corners to a single value (Mercury runs 12px, Monzo runs 24px); SoFi runs 12px and 15px side by side, with 12px on buttons and the smaller cards and 15px on product mockup chrome. Keep the two values segregated when porting the system.

## Components

### Buttons

**`button-primary`** — the system-wide CTA, exactly one filled pill per band.
- Background `{colors.primary}` ("#00a2c7"), text `{colors.on-primary}` ("#ffffff"), type `{typography.button-md}` (16px / 700), padding `8px 18px`, height 40px, rounded `{rounded.sm}` 12px, 1px `{colors.primary}` border.
- Hover state `button-primary-hover` shifts background to `{colors.primary-deep}` ("#00819d") — the deeper teal does double duty as the CTA hover.

**`button-secondary`** — outline-style alternative on the white canvas.
- Background `{colors.canvas-light}` ("#ffffff"), text `{colors.ink}` ("#212121"), 1px `{colors.ink}` border, same 12px radius and 40px height.

**`button-ghost`** — text-only nav-style action.
- Background transparent on `{colors.canvas-light}`, text `{colors.primary-deep}` ("#00819d"), no border. Used for `Log in` and inline nav anchors.

**`button-payday`** — the wider CTA on aubergine bands ("Apply now").
- Background `{colors.primary}` ("#00a2c7"), white text, padding `9px 30px` — the only place the brand widens the CTA horizontally.

### Inputs & Forms

**`text-input`** — standard form field.
- Background `{colors.canvas-light}`, text `{colors.ink}`, 1px `{colors.hairline-light}` ("#b9b9b9") border, padding 12px, height 44px, rounded `{rounded.xs}` 4px. The input component was extracted as null on the home surface — these values are inferred from the form-field treatment elsewhere on the marketing surface.

### Navigation

**`top-nav`** — full-width nav floating above the hero.
- Background `{colors.canvas-light}` ("#ffffff"), text `{colors.ink}`, padding `12px 40px`, height 72px. The `Sofi homepage` logo anchor sits on the left at `{colors.primary-deep}` text color; the primary nav (Banking, Loans, Invest, Credit Card, Insights) sits center; the `Log in` link and the filled `Get Started` CTA sit on the right.

**`nav-link`** — individual nav cell.
- Background `{colors.canvas-light}`, text `{colors.primary-deep}` ("#00819d") at type `{typography.body-md}` (16px / 500 / 24 line-height), padding 12px, height 24px. The brand uses weight 500 for the logo anchor specifically — between regular and bold.

### Cards & Containers

**`card-feature`** — product feature card on the white canvas.
- Background `{colors.canvas-light}`, text `{colors.ink}`, padding 20px, rounded `{rounded.lg}` 20px, 1px `{colors.hairline-light}` border. Contains an illustrated product mockup, a 1-line title at `{typography.heading-sm}`, and a 2-3 line description at `{typography.body-md}`.

**`card-product-mockup`** — compact product feature card (Banking, Loans, Invest, Credit Card).
- Background `{colors.canvas-light}`, padding 20px, rounded `{rounded.md}` 15px. Renders a single product screenshot above the label.

**`card-payday`** — dark feature card on the aubergine band.
- Background `{colors.aubergine}` ("#211747"), text `{colors.on-dark}` ("#ffffff"), padding 30px, rounded `{rounded.lg}` 20px. The white-on-aubergine inversion carries the storytelling band.

### Hero & Headings

**`hero-heading`** — the 50px Larsseit 800 hero `h2`.
- Type `{typography.display-hero}` (50px / 800 / -1.4px tracking), color `{colors.on-dark}` ("#ffffff") on the aubergine overlay. Width capped at 610px in the extracted hero.

**`section-heading`** — section opener.
- Type `{typography.display-lg}` (36px / 800 / -0.5px), color `{colors.ink}` ("#212121") on the white canvas.

### Pills, Tags, and Chips

**`pill-tag`** — soft mist tag for category labels.
- Background `{colors.canvas-mist}` ("#eae9e9"), text `{colors.ink}`, type `{typography.caption-bold}`, padding `4px 8px`, rounded `{rounded.xs}` 4px. The brand keeps tags on a neutral fill — the teal voltage never doubles into chip territory.

### Signature Components

**`link-inline`** — inline link emphasis on the white canvas.
- Text `{colors.primary-deep}` ("#00819d") rendered in `{typography.body-md}`, no underline by default; underline on hover. The deeper teal is the link register, never the brighter `#00a2c7`.

**`disclosure-footer`** — the regulatory disclosure footer with FDIC text.
- Background `{colors.canvas-light}`, text `{colors.ink-faint}` ("#575757") at type `{typography.caption}`, padding `80px 40px 40px` — the dominant section-wrapper shorthand. Holds product / company / legal columns plus the FDIC and member-disclosure block.

**`faq-row`** — single FAQ accordion row.
- Background `{colors.canvas-light}`, text `{colors.ink}`, type `{typography.label-bold}` (16px / 700), padding `20px 0`, 1px `{colors.hairline-light}` border. Click expands a 14px / 400 answer paragraph.

**`app-download-tile`** — the dark `Download the app` tile.
- Background `{colors.ink}` ("#212121"), white text, type `{typography.button-md}`, padding `12px 30px`, height 48px, rounded `{rounded.xl}` 100px — the soft-corner large-pill variant. The brand uses 100px specifically here, not 500px.

**`logo-strip-cell`** — customer-logo strip cell.
- Background `{colors.canvas-light}`, padding 20px, no card chrome. Each wordmark sits flat against white at roughly equal optical weight.

## Do's and Don'ts

### Do
- Reserve `{colors.primary}` ("#00a2c7") for filled CTAs only — one filled pill per band, never two.
- Reserve `{colors.primary-deep}` ("#00819d") for link text, nav anchors, and the `Sofi homepage` logo anchor — never apply it to a button fill.
- Render every display tier at Larsseit weight 800 — the brand commits to the single heavyweight across 28-50px.
- Apply negative tracking that scales with size: -1.4px at 50px, -0.5px at 36px, -0.784px at 28px, zero at 20px and below.
- Use the 12px CTA radius on every primary button — the corner is tighter than the 20px card chrome it sits inside, on purpose.
- Pair white catalogue bands with the aubergine `{colors.aubergine}` ("#211747") payday band at hard edges — no gradient transitions between the two modes.

### Don't
- Don't use "#00a2c7" for link text or inline emphasis — that work belongs to `{colors.primary-deep}` ("#00819d"). Crossing the two teals dilutes the CTA's pull.
- Don't use "#000000" anywhere as a text or fill color — pure black is reserved for `box-shadow` declarations only (17 of 22 occurrences). Body text lives at `{colors.ink}` ("#212121"), off-black, never pure.
- Don't render display copy at weight 700 or 600 — the brand specifically uses Larsseit 800. Dropping to a lighter weight removes the heavyweight typographic tell.
- Don't apply positive letter-spacing to display sizes — every Larsseit display tier tracks negative (-1.4px to -0.5px). Positive tracking reads as Mercury or editorial-serif, not SoFi.
- Don't fill `{colors.accent-butter}` ("#fbd974") or `{colors.accent-salmon}` ("#f2817d") on buttons or interactive surfaces — they are decoration-only, scoped to illustrated product-mockup highlights. Frequencies of 4 and 2 respectively confirm the scarcity.
- Don't use a 16px or 8px corner radius on cards — the brand's scale collapses to 4 / 12 / 15 / 20 / 100 / 500, with 20px doing all the mid-range card work and 15px reserved for product mockup chrome specifically.
- Don't apply the WordPress-preset gradient tokens (`--wp--preset--gradient--midnight`, `--wp--preset--gradient--blush-bordeaux`, the cool-to-warm spectrum) to marketing surfaces — they ship in the stylesheet because the site is built on WordPress block themes, but the captured surface uses zero of them. The brand prefers flat fills over CSS gradients.

## Responsive Behavior

### Breakpoints

| Name | Width | Key Changes |
|---|---|---|
| Wide | ≥ 1440px | Default content max-width; hero display at 50px / -1.4px |
| Desktop | 1024-1440px | Hero display steps to 42px on the WordPress `--x-large` preset |
| Tablet | 768-1023px | Product grid 2-up; nav collapses sub-menus; hero display at 36px |
| Mobile | < 768px | Product grid 1-up; hamburger nav; hero display at 28px |

### Touch Targets
- The `Get Started` CTA at 40px height hits `40 × 127px` on desktop; on mobile the pill bumps to 44px to maintain comfortable thumb-targets.
- Form fields stay at 44px minimum height across all breakpoints.

### Collapsing Strategy
- Display tiers stair-step 50 → 42 → 36 → 28 → 20px through the breakpoints, with the WordPress font-size presets (`--large` 36px, `--x-large` 42px) acting as intermediate landings.
- Product mockup grid stair-steps 4-up → 2-up → 1-up.
- Top-nav inline links collapse into a hamburger drawer at <768px; the `Get Started` CTA stays visible at the top right.

## Known Gaps

- **Input state colors:** the extractor flagged the `input` component as null on the captured home surface. The `text-input` token here is inferred from the form-field treatment elsewhere on the marketing canvas; focus, hover, and error states are not directly documented.
- **Authenticated dashboard palette:** transaction tables, account balance displays, investing portfolio surfaces, lending dashboards, and credit-card statement UI live inside the authenticated app and are not part of this marketing-system spec.
- **Hover, pressed, and focus states:** only the base CTA color and an inferred hover (`button-primary-hover` at the deeper teal) are documented. Card hover lifts, link underline transitions, and FAQ row expand animations are not tokenized.
- **Illustration art direction:** the yellow `#fbd974`, salmon `#f2817d`, and sky `#6699cc` accents appear inside illustrated product-mockup tiles as raster art rather than CSS-rendered color. They are listed as accent tokens but not assigned to interactive surfaces.
- **WordPress preset bloat:** the captured `:root` declares ~50 WordPress block-theme color and gradient presets (`--wp--preset--color--vivid-cyan-blue`, `--wp--preset--gradient--midnight`, etc.) at frequency zero on the marketing surface. Those tokens ship in the stylesheet but the brand uses zero of them — the system is built on top of the WordPress block theme, not within it.
- **Motion specs:** the hero band transition, FAQ row expand, and mobile-app download tile hover use unknown easing curves and durations not captured by the extraction.
- **Regulatory disclosure typography:** the FDIC and member-disclosure block at the bottom of the footer uses 12px / TT Norms / 400 with weight 700 callouts for "Member FDIC" — the precise hierarchy of italicized regulatory phrases is described in prose but not enumerated as separate tokens.
