Cash App
MIT
Bold, high-contrast fintech design system built on Cash App's signature neon green and black palette, optimised for mobile payment interfaces and developer implementation
Layout StudioImport this kit into a Studio project and start editing.
CLI installRun it in any project. No account needed.
npx @layoutdesign/context install cash-app# layout.md — Cash App Design System
---
## 0. Quick Reference
**Stack:** Next.js · CSS Modules (Sass) · Custom font system · Token source: reconstructed-from-computed (low confidence, 1 CSS custom property found)
**How to apply:** Use as `var(--cash-*)` in CSS, `style={{ prop: 'var(--cash-*)' }}` in JSX, or `bg-[var(--cash-*)]` in Tailwind.
```css
:root {
/* BRAND */
--cash-green: rgb(0, 224, 19); /* Cash App signature green — CTAs, brand accents */
--cash-black: rgb(0, 0, 0); /* Primary text, nav background */
--cash-white: rgb(255, 255, 255); /* Button fill on dark bg, body text on dark surface */
/* TYPOGRAPHY — composite (Cash Sans is the ONLY permitted font) */
--cash-font-stack: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-font-stack-wide: "Cash Sans Wide", "Helvetica Neue", helvetica, sans-serif;
--cash-font-stack-mono: "Cash Sans Mono", monospace;
/* TYPE SCALE */
--cash-font-size-xs: 12px;
--cash-font-size-sm: 14px;
--cash-font-size-md: 16px; /* body — rounds 15.9999px */
--cash-font-size-lg: 18px; /* large body / subheads */
--cash-font-size-xl: 24px; /* section labels */
--cash-font-size-2xl: 40px; /* h2/h3 */
--cash-font-size-3xl: 56px; /* h1 hero */
/* SPACING */
--cash-space-xs: 8px; /* tight gaps (rounded from 10.5px) */
--cash-space-sm: 16px; /* standard inline padding */
--cash-space-md: 20px; /* card gap, section rhythm */
--cash-space-lg: 24px; /* component breathing room */
--cash-space-xl: 32px; /* section inner padding */
--cash-space-2xl: 64px; /* section vertical spacing */
--cash-space-3xl: 96px; /* hero/footer spacing */
/* RADIUS */
--cash-radius-sm: 2px; /* small UI chrome */
--cash-radius-pill: 100px; /* primary buttons — pill shaped */
/* MOTION */
--cash-duration-fast: 0.3s;
--cash-ease-default: ease;
}
```
```tsx
// Primary pill button — correct token usage
<button style={{
fontFamily: 'var(--cash-font-stack)',
fontSize: 'var(--cash-font-size-sm)',
backgroundColor: 'var(--cash-white)',
color: 'var(--cash-black)',
borderRadius: 'var(--cash-radius-pill)',
padding: '14px var(--cash-space-sm)',
transition: `opacity var(--cash-duration-fast) var(--cash-ease-default)`,
border: 'none', cursor: 'pointer',
}}>Get started</button>
```
**NEVER rules:**
- NEVER use Inter, Roboto, Arial, or any font other than Cash Sans / Cash Sans Wide / Cash Sans Mono
- NEVER use a button border-radius other than `100px` (pill) for primary CTAs
- NEVER hardcode `#00e013` or `rgb(0,224,19)` — always use `var(--cash-green)`
- NEVER use spacing values outside the `--cash-space-*` scale
- NEVER omit hover state opacity (`0.7`) on interactive elements — it is the universal hover pattern
- NEVER use `!important` to override token values
- NEVER construct dynamic Tailwind class strings like `` `bg-[${color}]` `` — values won't be tree-shaken
**Full design system → see layout.md**
---
## 1. Design Direction & Philosophy
### Character & Mood
Cash App presents a **bold, minimal, high-contrast** aesthetic rooted in financial confidence. The design is dark-first (black backgrounds, white text) with a single electric accent — **Cash App Green (`rgb(0, 224, 19)`)** — used sparingly for brand recognition and CTAs. The visual language is clean and assertive: large typographic headlines at low font-weight (400), generous whitespace, and pill-shaped CTAs.
### What This Design IS
- **Dark-field dominant:** The page background is black. Content appears on black. White and green are accent.
- **Typography-forward:** Headlines run at `56px` weight `400` — the type carries the visual hierarchy, not decoration.
- **Radically simple interaction model:** Hover = `opacity: 0.7` or `opacity: 0.8`. No complex transform choreography except on image cards (scale 1.05).
- **Brand-owned typeface:** Cash Sans (Regular 400, Medium 500, Semibold 600, Bold 700, Black 900) + Cash Sans Wide + Cash Sans Mono. This typeface is the primary brand differentiator.
### What This Design Explicitly REJECTS
- Warm colour palettes, gradients, or decorative illustration styles
- Rounded corners on non-button elements (cards have `0px` radius)
- Serif or geometric sans fonts (no Inter, Roboto, Helvetica as primary)
- Heavy drop shadows or layered elevation effects on content cards
- Busy layouts — whitespace is structural, not incidental
---
## 2. Colour System
### Tier 1 — Primitive Values
```css
:root {
/* Primitive palette */
--cash-primitive-green: rgb(0, 224, 19); /* Cash App Green — brand signature */
--cash-primitive-black: rgb(0, 0, 0); /* Pure black */
--cash-primitive-white: rgb(255, 255, 255); /* Pure white */
--cash-primitive-gray-100: rgb(244, 244, 244); /* Lightest gray — nav item hover bg */
--cash-primitive-gray-200: rgb(240, 240, 240); /* Light gray — pill/tag hover */
--cash-primitive-gray-300: rgb(229, 229, 229); /* Medium-light — dropdown item hover */
--cash-primitive-gray-400: rgb(184, 184, 184); /* Medium — scrollbar thumb hover */
--cash-primitive-gray-500: rgb(153, 153, 153); /* Disabled locale option text */
--cash-primitive-gray-600: rgb(115, 115, 115); /* Article tag border hover */
--cash-primitive-gray-700: rgb(102, 102, 102); /* Footer link hover */
--cash-primitive-gray-800: rgb(75, 75, 75); /* Disabled menu item text */
--cash-primitive-purple: rgb(84, 32, 194); /* Presale secondary hover */
--cash-primitive-link-blue: rgb(0, 0, 238); /* Default browser link — avoid using */
}
```
### Tier 2 — Semantic Aliases
```css
:root {
/* Surface */
--cash-bg-surface: var(--cash-primitive-green); /* Page brand surface / CTA background */
/* reconstructed: medium confidence — from --brand-surface-1 on 2 elements */
--cash-color-page-bg: var(--cash-primitive-black); /* Default page background */
--cash-color-surface-nav: var(--cash-primitive-black); /* Navigation bar background */
--cash-color-surface-elevated: var(--cash-primitive-white); /* Cards on dark bg, modal surfaces */
/* Text */
--cash-color-text-primary: var(--cash-primitive-white); /* Body text on dark backgrounds */
--cash-color-text-inverted: var(--cash-primitive-black); /* Text on white/green surfaces */
--cash-color-text-heading: var(--cash-primitive-black); /* h1–h3 (these render on white sections) */
--cash-color-text-muted: var(--cash-primitive-gray-700); /* Secondary/footer text */
--cash-color-text-disabled: var(--cash-primitive-gray-500); /* Disabled state text */
/* Interactive */
--cash-color-action-primary-bg: var(--cash-primitive-white); /* Primary button bg (on dark surfaces) */
--cash-color-action-primary-text: var(--cash-primitive-black); /* Primary button label */
--cash-color-action-brand: var(--cash-primitive-green); /* Brand CTA, sign-up */
--cash-color-hover-overlay: 0.7; /* Opacity value for hover states */
/* Borders */
--cash-color-border-input: rgb(112, 112, 112); /* Input field border */
--cash-color-border-tag: var(--cash-primitive-gray-600); /* Article tag border hover */
/* Focus */
--cash-color-focus-ring: var(--cash-primitive-black); /* Focus outline — 2px solid */
}
```
### Tier 3 — Component Tokens
```css
:root {
/* Button */
--cash-btn-primary-bg: var(--cash-color-action-primary-bg);
--cash-btn-primary-text: var(--cash-color-action-primary-text);
--cash-btn-brand-bg: var(--cash-color-action-brand);
--cash-btn-brand-text: var(--cash-primitive-black);
/* Nav */
--cash-nav-bg: var(--cash-color-surface-nav);
--cash-nav-text: var(--cash-primitive-white);
/* Input */
--cash-input-bg: var(--cash-primitive-white);
--cash-input-border: var(--cash-color-border-input);
--cash-input-text: var(--cash-primitive-black);
--cash-input-radius: 50px; /* pill-shaped input */
/* Card */
--cash-card-bg: transparent;
--cash-card-text: var(--cash-primitive-black);
--cash-card-radius: 0px; /* cards have NO border-radius in base design */
}
```
### Colour Usage Table
| Token | Value | Usage |
|---|---|---|
| `--cash-green` | `rgb(0, 224, 19)` | **Brand signature** — CTAs, brand moments |
| `--cash-black` | `rgb(0, 0, 0)` | Page bg, nav bg, heading text |
| `--cash-white` | `rgb(255, 255, 255)` | Button fill, body text on dark |
| `--cash-primitive-gray-300` | `rgb(229, 229, 229)` | Dropdown hover states |
| `--cash-primitive-purple` | `rgb(84, 32, 194)` | Presale secondary only |
---
## 3. Typography System
### Font Faces
```css
/* Cash Sans — primary brand typeface */
@font-face {
font-family: "Cash Sans";
src: url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff2/CashSans-Regular.woff2") format("woff2"),
url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff/CashSans-Regular.woff") format("woff");
font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
font-family: "Cash Sans";
src: url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff2/CashSans-Medium.woff2") format("woff2"),
url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff/CashSans-Medium.woff") format("woff");
font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
font-family: "Cash Sans";
src: url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff2/CashSans-Semibold.woff2") format("woff2"),
url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff/CashSans-Semibold.woff") format("woff");
font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
font-family: "Cash Sans";
src: url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff2/CashSans-Bold.woff2") format("woff2"),
url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff/CashSans-Bold.woff") format("woff");
font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
font-family: "Cash Sans";
src: url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff2/CashSans-Black.woff2") format("woff2"),
url("https://cash-f.squarecdn.com/static/fonts/cashsans/woff/CashSans-Black.woff") format("woff");
font-weight: 900; font-style: normal; font-display: swap;
}
/* Cash Sans Wide — expanded variant for display use */
/* Cash Sans Mono — monospaced for financial data */
/* (repeat @font-face pattern for Wide 400–900 and Mono 400) */
```
### Composite Type Tokens
```css
:root {
/* ── HERO HEADING (h1) ── */
/* font: 400 56px/53.2px "Cash Sans", "Helvetica Neue", helvetica, sans-serif */
--cash-type-h1-family: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-type-h1-size: 56px; /* rounds 55.9998px */
--cash-type-h1-weight: 400; /* extracted: high confidence */
--cash-type-h1-line-height: 53.2px; /* tight — 0.95 ratio */
--cash-type-h1-letter-spacing: -1.68px; /* extracted: high confidence */
/* ── SECTION HEADING (h2, h3) ── */
/* font: 400 40px/44px "Cash Sans", "Helvetica Neue", helvetica, sans-serif */
--cash-type-h2-family: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-type-h2-size: 40px; /* rounds 39.9999px */
--cash-type-h2-weight: 400; /* extracted: high confidence */
--cash-type-h2-line-height: 44px; /* 1.1 ratio */
--cash-type-h2-letter-spacing: -1.2px; /* extracted: high confidence */
/* ── SUBHEADING / CARD TITLE (h4) ── */
/* font: 400 24px/normal "Cash Sans", sans-serif */
--cash-type-h4-family: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-type-h4-size: 24px; /* rounds 23.9999px */
--cash-type-h4-weight: 400;
--cash-type-h4-line-height: normal;
/* ── BODY LARGE ── */
/* font: 400 18px/25.2px "Cash Sans", "Helvetica Neue", helvetica, sans-serif */
--cash-type-body-lg-family: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-type-body-lg-size: 18px; /* rounds 17.9999px */
--cash-type-body-lg-weight: 400;
--cash-type-body-lg-line-height: 25.2px; /* reconstructed: moderate confidence */
/* ── BODY DEFAULT ── */
/* font: 400 16px/19.2px "Cash Sans", "Helvetica Neue", helvetica, sans-serif */
--cash-type-body-family: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-type-body-size: 16px;
--cash-type-body-weight: 400; /* extracted: high confidence */
--cash-type-body-line-height: 19.2px; /* extracted: high confidence */
/* ── LABEL / UI TEXT ── */
/* font: 600 16px/normal "Cash Sans", sans-serif */
--cash-type-label-family: "Cash Sans", sans-serif;
--cash-type-label-size: 16px;
--cash-type-label-weight: 600; /* extracted from label element */
--cash-type-label-line-height: normal;
/* ── BUTTON TEXT ── */
/* font: 400 14px/14px "Cash Sans", sans-serif */
--cash-type-button-family: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-type-button-size: 14px; /* extracted: high confidence */
--cash-type-button-weight: 400;
--cash-type-button-line-height: 14px; /* 1:1 line-height = cap-height aligned */
--cash-type-button-letter-spacing: -0.28px;
/* ── CAPTION / XS ── */
/* font: 500 12px/normal "Cash Sans", sans-serif */
--cash-type-caption-family: "Cash Sans", sans-serif;
--cash-type-caption-size: 12px;
--cash-type-caption-weight: 500; /* reconstructed: moderate confidence */
--cash-type-caption-line-height: normal;
/* ── MONOSPACE (financial data, amounts) ── */
--cash-type-mono-family: "Cash Sans Mono", monospace;
--cash-type-mono-size: 16px; /* [TBD - extract manually] */
--cash-type-mono-weight: 400;
}
```
### Type Scale Table
| Role | Size | Weight | Line Height | Letter Spacing |
|---|---|---|---|---|
| Hero H1 | `56px` | `400` | `53.2px` | `-1.68px` |
| Section H2/H3 | `40px` | `400` | `44px` | `-1.2px` |
| Card H4 | `24px` | `400` | `normal` | — |
| Body Large | `18px` | `400` | `25.2px` | — |
| Body | `16px` | `400` | `19.2px` | — |
| Button | `14px` | `400` | `14px` | `-0.28px` |
| Caption/XS | `12px` | `500` | `normal` | — |
**Key rule:** Headings use weight `400` — NOT bold. Cash App's hierarchy comes from **size**, not weight.
### Pairing Rules
- **Cash Sans** — all UI text, body copy, navigation, buttons
- **Cash Sans Wide** — display/hero moments only, never body text
- **Cash Sans Mono** — financial amounts, account numbers, codes only
- NEVER mix with system fonts except as declared fallbacks
---
## 4. Spacing & Layout
```css
:root {
/* ── BASE UNIT: 8px grid ── */
/* Note: source has off-grid values (10.5px, 15.99px, 19.88px).
These are normalised to the nearest 4px multiple for the token system.
The original computed values are preserved in component documentation. */
--cash-space-1: 4px; /* micro — icon gaps, border offsets */
--cash-space-2: 8px; /* tight — inline element spacing, gap in buttons */
--cash-space-3: 12px; /* small — compact padding */
--cash-space-4: 16px; /* base — standard padding, sm spacing */
--cash-space-5: 20px; /* medium — card grid gap (matches cls_card gap:20px) */
--cash-space-6: 24px; /* large — component breathing room */
--cash-space-8: 32px; /* xl — section inner padding */
--cash-space-12: 48px; /* 2xl — between components */
--cash-space-16: 64px; /* section vertical rhythm */
--cash-space-24: 96px; /* hero-scale — footer spacing */
/* ── LEGACY ALIASES (map to scale) ── */
--cash-space-xs: var(--cash-space-2); /* reconstructed from 10.5px → 8px */
--cash-space-sm: var(--cash-space-4); /* reconstructed from 15.99px → 16px */
--cash-space-md: var(--cash-space-5); /* reconstructed from 19.88px → 20px */
--cash-space-lg: var(--cash-space-5); /* source value: 20px exact */
--cash-space-xl: var(--cash-space-6); /* source value: 24px exact */
--cash-space-2xl: var(--cash-space-8); /* source value: 32px exact */
--cash-space-3xl: var(--cash-space-24); /* reconstructed from 90px → 96px */
/* ── FOOTER SPACING ── */
--ot-footer-space: 160px; /* extracted: high confidence — preserved original name */
/* ── BUTTON PADDING (exact computed values) ── */
--cash-btn-padding-v: 14px; /* vertical — exact from computed */
--cash-btn-padding-h: var(--cash-space-sm); /* horizontal ≈ 16px (source: 19.88px) */
--cash-btn-gap: var(--cash-space-2); /* icon-to-label gap (source: 10.5px) */
/* ── RADIUS SCALE ── */
--cash-radius-none: 0px; /* cards, sections, headings */
--cash-radius-sm: 2px; /* small chrome, close buttons — extracted: high confidence */
--cash-radius-pill: 100px; /* PRIMARY BUTTONS — pill shaped, extracted from button_primary */
--cash-radius-input: 50px; /* inputs — pill shaped */
--cash-radius-image: 14.3%; /* responsive images, footer text cards — extracted: high confidence */
/* Note: 15.9%/13% (elliptical) appears on video/image containers — reconstructed: moderate confidence */
/* ── NAVIGATION ── */
--cash-nav-padding-top: 86px; /* extracted from role_navigation computed style */
/* ── GRID ── */
--cash-container-max: 1440px; /* inferred from 1440px breakpoint — reconstructed: moderate confidence */
--cash-container-padding: var(--cash-space-8); /* [TBD - extract manually] */
}
```
### Breakpoint Scale
| Name | Value | Notes |
|---|---|---|
| `xs` | `391px` | Small phones |
| `sm` | `500px` | Mid-range mobile |
| `md` | `760px` | Tablet portrait |
| `lg` | `1024px` | Desktop baseline |
| `xl` | `1400px` | Wide desktop |
| `2xl` | `1680px` | Ultra-wide |
Key pairs: `759px`/`760px` and `1023px`/`1024px` are mobile/desktop breakpoints (below/above logic).
---
## 5. Page Structure & Layout Patterns
> Token source is layout digest only — no screenshots provided. All section rows marked **"(inferred)"** are derived from component inventory + computed styles. Rows marked **"(extracted)"** are anchored to digest values.
### 5.1 Section Map
| # | Section | Layout Type | Key Elements | Source |
|---|---|---|---|---|
| 1 | Nav/Header | Flex column, centered | Logo, nav links, Sign up CTA (green), Log in | extracted |
| 2 | Hero | Full-width, block | H1 at 56px/400, arrow `→` glyph at 56px, body copy | inferred |
| 3 | Feature/Card Grid | CSS Grid, gap 20px | Stat cards (h4 + body), imagery with 14.3% radius | extracted |
| 4 | Product Features | Alternating block | H2 + body large + pill CTA, app imagery | inferred |
| 5 | App Store Badges | Flex row | "Editor's Choice", "9.9m+ Apple App Store", "4.5★" cards | extracted |
| 6 | FAQ / Accordion | Block, full-width | H3 question rows, expand/collapse, opacity hover | inferred |
| 7 | Press / Archive | Flex row, pill filters | Year pill filters, press logos | inferred |
| 8 | Footer | Flex column/row | Links, locale switcher, legal text | inferred |
### 5.2 Layout Patterns
**Navigation** (extracted from `role_navigation` computed styles):
```
display: flex
flex-direction: column
justify-content: center
align-items: center
padding-top: 86px /* --cash-nav-padding-top */
background: rgb(0,0,0) /* --cash-black */
```
**Card Grid** (extracted from `cls_card` computed styles):
```
display: grid
gap: 20px /* --cash-space-5 */
/* column count: [TBD - extract manually] — likely 2–3 col at desktop */
```
**Primary Button** (extracted from `button_primary` computed styles):
```
display: flex
flex-direction: row
justify-content: center
align-items: center
gap: 10.5px /* use --cash-btn-gap (8px normalised) */
padding: 14px 19.88px /* use --cash-btn-padding-v / -h */
border-radius: 100px /* --cash-radius-pill */
background: rgb(255,255,255) on dark bg; rgb(0,224,19) for brand CTA
```
**Image/Video Containers:**
- Responsive images: `border-radius: 14.3%` (aspect-ratio-relative, creates organic rounding)
- Background video containers: `border-radius: 15.9% / 13%` (elliptical)
- Cards: `border-radius: 0px` — sharp corners
### 5.3 Visual Hierarchy
- **H1 at 56px/400 weight** is the dominant visual element in the hero — size alone creates hierarchy
- **Cash App Green** (`rgb(0, 224, 19)`) appears on the primary sign-up CTA ("Sign up now→") and brand surface moments only — it is the single most visually distinct element
- **Arrow glyph `→`** rendered at `56px` creates a kinetic call-to-action alongside the hero headline
- White pill buttons on black backgrounds are the secondary CTA pattern
- App store social proof cards (Editor's Choice, ratings) use `14.3%` border-radius, appearing as "squircle" frames
- Hover universally = `opacity: 0.7` (buttons) or `opacity: 0.8` (cards, links, media)
### 5.4 Content Patterns
**Stat/Badge Card** (repeating):
```
[Squircle-framed image or icon]
[H4 — feature label]
[Body copy — 16–18px, 400 weight]
[Optional: pill CTA]
```
**Feature Row** (alternating, inferred):
```
[H2 at 40px] + [Body Large at 18px] — left column
[App screenshot or video] — right column
Alternates L/R on subsequent sections
```
**FAQ Item** (extracted from hover states):
```
[H3 question — opacity 0.7 on hover]
[Body answer — revealed on expand]
```
---
## 6. Component Patterns
### 6.1 Primary Button
**Anatomy:** `<button>` → `[optional icon]` + `[label text]`
**Token mappings:**
| State | background | color | opacity | border-radius |
|---|---|---|---|---|
| Default | `--cash-white` | `--cash-black` | `1` | `--cash-radius-pill` |
| Hover | `--cash-white` | `--cash-black` | `0.7` | `--cash-radius-pill` |
| Focus | `--cash-white` | `--cash-black` | `1` | `--cash-radius-pill` |
| Active | `--cash-white` | `--cash-black` | `0.85` | `--cash-radius-pill` |
| Disabled | `--cash-white` | `--cash-black` | `0.3` | `--cash-radius-pill` |
| Brand/CTA | `--cash-green` | `--cash-black` | `1` | `--cash-radius-pill` |
```tsx
import { ButtonHTMLAttributes, ReactNode } from 'react';
interface CashButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'brand';
icon?: ReactNode;
children: ReactNode;
}
export function CashButton({
variant = 'primary',
icon,
children,
disabled,
style,
...props
}: CashButtonProps) {
const bg = variant === 'brand'
? 'var(--cash-green)'
: 'var(--cash-white)';
return (
<button
disabled={disabled}
style={{
fontFamily: 'var(--cash-font-stack)',
fontSize: 'var(--cash-font-size-sm)', /* 14px */
fontWeight: 400,
lineHeight: 'var(--cash-font-size-sm)', /* 1:1 ratio */
letterSpacing: '-0.28px',
color: 'var(--cash-black)',
backgroundColor: bg,
borderRadius: 'var(--cash-radius-pill)', /* 100px */
padding: '14px var(--cash-space-sm)',
border: 'none',
cursor: disabled ? 'not-allowed' : 'pointer',
opacity: disabled ? 0.3 : 1,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 'var(--cash-space-2)', /* 8px */
transition: `opacity var(--cash-duration-fast) var(--cash-ease-default)`,
textDecoration: 'none',
...style,
}}
onMouseEnter={e => !disabled && ((e.currentTarget as HTMLElement).style.opacity = '0.7')}
onMouseLeave={e => !disabled && ((e.currentTarget as HTMLElement).style.opacity = disabled ? '0.3' : '1')}
onFocus={e => {
(e.currentTarget as HTMLElement).style.outlineOffset = '2px';
(e.currentTarget as HTMLElement).style.outline = '2px solid var(--cash-black)';
}}
onBlur={e => {
(e.currentTarget as HTMLElement).style.outline = 'none';
}}
{...props}
>
{icon && <span aria-hidden="true">{icon}</span>}
{children}
</button>
);
}
```
---
### 6.2 Navigation
**Anatomy:** `<nav>` → `[logo]` + `[nav links]` + `[auth CTAs: Sign up | Log in]`
| State | color | opacity | bg |
|---|---|---|---|
| Default | `--cash-white` | `1` | `--cash-black` |
| Hover | `--cash-white` | `0.7` | `--cash-black` |
| Focus | — | `1` | — |
| Disabled | `rgb(75,75,75)` | `0.6` | — |
**Layout:**
- `display: flex; flex-direction: column; justify-content: center; align-items: center`
- `padding-top: 86px` (from computed `role_navigation`)
- Background: `rgb(0, 0, 0)`
---
### 6.3 Card
**Anatomy:** `<article>` → `[image with 14.3% radius]` + `[heading]` + `[body]` + `[optional CTA]`
| State | bg | border-radius | transform | box-shadow |
|---|---|---|---|---|
| Default | `transparent` | `0px` | none | none |
| Hover (store tile) | — | — | `translateY(-2px)` | `rgba(0,0,0,0.12) 0px 8px 24px` |
| Hover (article/image link) | — | — | — | `opacity: 0.8` |
| Hover (image inside) | — | — | `scale(1.05)` | — |
```tsx
interface CashCardProps {
image?: string;
imageAlt?: string;
heading: string;
body: string;
cta?: { label: string; href: string };
}
export function CashCard({ image, imageAlt, heading, body, cta }: CashCardProps) {
return (
<article style={{
display: 'block',
backgroundColor: 'transparent',
borderRadius: '0px',
overflow: 'hidden',
color: 'var(--cash-black)',
fontFamily: 'var(--cash-font-stack)',
}}>
{image && (
<div style={{ overflow: 'hidden', borderRadius: '14.3%' }}>
<img
src={image}
alt={imageAlt ?? ''}
style={{
width: '100%',
display: 'block',
transition: `transform var(--cash-duration-fast) var(--cash-ease-default)`,
}}
onMouseEnter={e => (e.currentTarget.style.transform = 'scale(1.05)')}
onMouseLeave={e => (e.currentTarget.style.transform = 'scale(1)')}
/>
</div>
)}
<h4 style={{
fontSize: 'var(--cash-font-size-xl)', /* 24px */
fontWeight: 400,
lineHeight: 'normal',
marginTop: 'var(--cash-space-4)',
}}>
{heading}
</h4>
<p style={{
fontSize: 'var(--cash-font-size-lg)', /* 18px */
lineHeight: '25.2px',
fontWeight: 400,
marginTop: 'var(--cash-space-2)',
}}>
{body}
</p>
{cta && (
<a
href={cta.href}
style={{
display: 'inline-block',
marginTop: 'var(--cash-space-4)',
fontSize: 'var(--cash-font-size-sm)',
fontWeight: 400,
color: 'var(--cash-black)',
textDecoration: 'none',
transition: `opacity var(--cash-duration-fast) var(--cash-ease-default)`,
}}
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.8')}
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
>
{cta.label}
</a>
)}
</article>
);
}
```
---
### 6.4 Input Field
**Anatomy:** `<label>` + `<input>` (pill-shaped)
| State | border | outline | bg |
|---|---|---|---|
| Default | `1px solid rgb(112,112,112)` | none | `--cash-white` |
| Focus | `1px solid rgb(112,112,112)` | `2px solid --cash-black` | `--cash-white` |
| Disabled | — | — | `[TBD]` |
| Error | `[TBD - extract manually]` | — | — |
```tsx
export function CashInput({ label, id, ...props }: { label: string; id: string } & React.InputHTMLAttributes<HTMLInputElement>) {
return (
<div>
<label htmlFor={id} style={{
fontFamily: 'var(--cash-font-stack)',
fontSize: '16px',
fontWeight: 600,
display: 'block',
marginBottom: 'var(--cash-space-2)',
color: 'var(--cash-black)',
}}>
{label}
</label>
<input
id={id}
style={{
fontFamily: 'var(--cash-font-stack)',
fontSize: 'var(--cash-font-size-xs)', /* 12px — from computed input */
fontWeight: 400,
color: 'var(--cash-black)',
backgroundColor: 'var(--cash-white)',
borderRadius: 'var(--cash-radius-input)', /* 50px pill */
border: '1px solid var(--cash-color-border-input)',
padding: '6px 35px 6px 15px',
display: 'block',
width: '100%',
boxSizing: 'border-box',
transition: `all var(--cash-duration-fast) var(--cash-ease-default)`,
outline: 'none',
}}
onFocus={e => {
e.currentTarget.style.outline = '2px solid var(--cash-black)';
e.currentTarget.style.outlineOffset = '2px';
}}
onBlur={e => {
e.currentTarget.style.outline = 'none';
}}
{...props}
/>
</div>
);
}
```
---
### 6.5 FAQ / Accordion Item
**Anatomy:** `<div>` → `<button> [H3 question]` + `[body answer, collapsible]`
| State | heading opacity | cursor |
|---|---|---|
| Default | `1` | `pointer` |
| Hover | `0.7` | `pointer` |
| Open | `1` | `pointer` |
```tsx
import { useState } from 'react';
export function CashFAQItem({ question, answer }: { question: string; answer: string }) {
const [open, setOpen] = useState(false);
return (
<div style={{ borderBottom: '1px solid var(--cash-black)', padding: 'var(--cash-space-5) 0' }}>
<button
onClick={() => setOpen(!open)}
style={{
background: 'none', border: 'none', padding: 0,
width: '100%', textAlign: 'left', cursor: 'pointer',
fontFamily: 'var(--cash-font-stack)',
}}
>
<h3
style={{
fontSize: 'var(--cash-font-size-2xl)', /* 40px */
fontWeight: 400,
letterSpacing: '-1.2px',
lineHeight: '44px',
margin: 0,
transition: `opacity var(--cash-duration-fast) var(--cash-ease-default)`,
}}
onMouseEnter={e => (e.currentTarget.style.opacity = '0.7')}
onMouseLeave={e => (e.currentTarget.style.opacity = '1')}
>
{question}
</h3>
</button>
{open && (
<p style={{
fontSize: 'var(--cash-font-size-lg)', /* 18px */
fontWeight: 400,
lineHeight: '25.2px',
marginTop: 'var(--cash-space-4)',
fontFamily: 'var(--cash-font-stack)',
}}>
{answer}
</p>
)}
</div>
);
}
```
---
### 6.6 Badge / Stat Card
**Anatomy:** `<div>` → `[star/rating icon]` + `[label text]` + `[source text]`
Uses `border-radius: 14.3%` (squircle) extracted from footer text cards ("Editor's Choice", "9.9m+", "4.5★").
| State | opacity | transform |
|---|---|---|
| Default | `1` | none |
| Hover (if clickable) | `0.8` | none |
---
## 7. Elevation & Depth
```css
:root {
/* ── SHADOWS ── */
/* Base design: NO shadows on most elements (boxShadow: none across card, button, nav, modal) */
--cash-shadow-none: none;
/* Store tile hover — only shadow found in extraction */
--cash-shadow-card-hover: rgba(0, 0, 0, 0.12) 0px 8px 24px;
/* extracted: high confidence — from .store-tile:hover computed state */
/* Scrollbar thumb hover (internal) */
--cash-shadow-scrollbar: rgb(184, 184, 184); /* bg-color only, no box-shadow */
/* ── Z-INDEX SCALE ── */
--cash-z-base: 0; /* page content */
--cash-z-card: 1; /* elevated cards */
--cash-z-nav: 100; /* navigation bar */
--cash-z-modal: 200; /* modal overlays */
--cash-z-toast: 300; /* transient alerts */
/* reconstructed: moderate confidence — no explicit z-index values extracted */
/* ── BORDERS ── */
--cash-border-input: 1px solid rgb(112, 112, 112); /* Input fields */
--cash-border-tag: 1px solid var(--cash-primitive-gray-600); /* Article tags on hover */
--cash-border-focus: 2px solid rgb(0, 0, 0); /* Focus ring — extracted from modal close button */
}
```
### Layering Principles
- **Default state:** No shadows. Cash App uses **opacity reduction** as the depth/de-emphasis tool, not shadows.
- **Card hover only:** `rgba(0,0,0,0.12) 0px 8px 24px` — used for store tile lift effect with `translateY(-2px)`
- **Modals:** Use `fadein` keyframe animation (opacity 0→1), not drop shadows for emphasis
- NEVER add box shadows to buttons — the design uses opacity not elevation for button feedback
---
## 8. Motion
```css
:root {
/* ── DURATION ── */
--cash-duration-fast: 0.3s; /* universal transition — extracted: high confidence */
/* All interactive elements use 0.3s. No slow (0.5s+) transitions found. */
/* ── EASING ── */
--cash-ease-default: ease; /* universal easing — extracted: high confidence */
/* ── TRANSITION SHORTHAND ── */
--cash-transition-default: all var(--cash-duration-fast) var(--cash-ease-default);
--cash-transition-opacity: opacity var(--cash-duration-fast) var(--cash-ease-default);
--cash-transition-transform: transform var(--cash-duration-fast) var(--cash-ease-default);
}
/* ── KEYFRAMES ── */
/* Fade in — used for modals and image lazy-load */
@keyframes cash-fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}
/* Intro animation — used for feature/splash screens */
@keyframes cash-introAnimation {
0% { opacity: 0; transform: scale(1.05); }
100% { opacity: 1; transform: scale(1); }
}
/* Pulse — used for campaign form elements */
@keyframes cash-pulse {
0% { opacity: 1; transform: scale(0.4); }
100% { opacity: 0.1; transform: scale(1.1); }
}
/* Floating CTA slide-in (mobile) */
@keyframes cash-ctaSlideIn {
100% { width: 90vw; left: 5vw; transform: translateY(0px); }
}
/* Floating CTA slide-out (mobile) */
@keyframes cash-ctaSlideOut {
100% { width: 90vw; left: 5vw; transform: translateY(calc(100% + 20px)); }
}
```
### Motion Rules
- **ANIMATE:** opacity changes on hover (0.3s ease), modal entrance (fadein), image lazy-load (fadein), image card hover scale (0.3s ease), floating CTA enter/exit
- **DO NOT ANIMATE:** layout shifts, font changes, colour swaps (use instant transitions for these)
- **Hover pattern is uniform:** `opacity: 0.7` for interactive text/buttons, `opacity: 0.8` for cards and media links
- Respect `prefers-reduced-motion` — wrap non-essential keyframe animations in `@media (prefers-reduced-motion: no-preference)`
---
## 9. Anti-Patterns & Constraints
1. **NEVER use Inter, Roboto, Arial, or any web-safe font as primary.**
→ Why it fails: AI coding agents default to `font-family: 'Inter', sans-serif` or `font-family: system-ui` when no font context is provided. This completely erases the Cash Sans brand identity — the typeface is the #1 visual differentiator.
→ What to do instead: Always declare `font-family: 'Cash Sans', 'Helvetica Neue', helvetica, sans-serif` on the root element. Load fonts from the CDN paths in Section 3.
2. **NEVER use hardcoded hex or rgb values for the brand green (`#00e013`, `rgb(0,224,19)`).**
→ Why it fails: If the brand green is hardcoded, a single brand update requires a global search-and-replace across hundreds of files. Agents also tend to use nearby approximations like `#00ff00` or `lime` which are perceptually wrong.
→ What to do instead: Use `var(--cash-green)` exclusively. Define the token once in `:root`.
3. **NEVER apply border-radius other than `100px` to primary CTA buttons.**
→ Why it fails: Agents trained on generic design systems default to `border-radius: 8px` or `border-radius: 0.375rem`. Cash App uses fully pill-shaped buttons (`100px`). Using 8px creates a fundamentally different visual language.
→ What to do instead: Apply `border-radius: var(--cash-radius-pill)` (`100px`) to all primary and brand buttons. Use `0px` for cards and sections.
4. **NEVER use spacing values outside the `--cash-space-*` token scale.**
→ Why it fails: 4 off-grid values were found in extraction (10.5px, 15.99px, 19.88px, 90px). Agents that copy these exact computed values will perpetuate broken rhythm. Meanwhile agents that invent arbitrary values like `margin: 13px` introduce new inconsistencies.
→ What to do instead: Round to the nearest 4px multiple and use the corresponding `--cash-space-*` token. Document the original computed value in a comment if exact fidelity is needed for a specific component.
5. **NEVER add box-shadow to buttons or standard cards.**
→ Why it fails: Agents trained on Material Design or Bootstrap patterns auto-apply `box-shadow: 0 2px 4px rgba(0,0,0,0.2)` to buttons. Cash App's depth language is opacity-based, not shadow-based. Shadows appear ONLY on store tile hover.
→ What to do instead: Use `opacity: 0.7` on hover (buttons) or `opacity: 0.8` (card links). Reserve `--cash-shadow-card-hover` exclusively for store tile hover with the matching `translateY(-2px)` transform.
6. **NEVER construct dynamic Tailwind class strings.**
→ Why it fails: Tailwind's JIT compiler only includes classes present as complete strings at build time. Writing `` `bg-[${brandColor}]` `` causes the class to be tree-shaken and the style never applies — the element renders unstyled.
→ What to do instead: Use `style={{ backgroundColor: 'var(--cash-green)' }}` for dynamic values, or define complete static class strings in a variant map.
7. **NEVER omit hover, focus, and disabled states on interactive elements.**
→ Why it fails: Agents frequently generate only the default state. Cash App uses a universal but specific pattern: hover = `opacity: 0.7` for buttons, `opacity: 0.8` for card links. Without these, the UI feels broken — users get no affordance feedback.
→ What to do instead: Every `<button>`, `<a>`, and interactive `<div>` must handle: default → hover (opacity change) → focus (2px solid black outline, 2px offset) → disabled (opacity 0.3, cursor not-allowed). See component patterns in Section 6.
8. **NEVER use `font-weight: 700` or `bold` on headings.**
→ Why it fails: H1 through H3 are all `font-weight: 400` on cash.app. Agents defaulting to bold headings create a visual hierarchy that contradicts the brand — Cash App uses SIZE (56px/40px) not weight to establish heading hierarchy.
→ What to do instead: Set headings to `font-weight: 400`. Use `font-weight: 600` only for `<label>` elements and semibold UI text. Reserve 700+ for maximum emphasis only.
9. **NEVER use `position: absolute` to achieve layout alignment in nav or card grids.**
→ Why it fails: Absolute positioning breaks reflow — nav items and card grids collapse or overlap at breakpoints. The extraction confirms nav uses `display: flex; flex-direction: column` and card grids use `display: grid; gap: 20px`.
→ What to do instead: Use flexbox for navigation and single-axis alignment. Use CSS grid with `gap: var(--cash-space-5)` for card grids. Only use absolute positioning for genuinely overlapping elements (floating CTAs, tooltips, overlays).
10. **NEVER use `!important` to override design tokens.**
→ Why it fails: `!important` bypasses the token cascade entirely. When a brand update changes `--cash-green`, components with `!important` rules will not inherit the update — causing visual drift that's hard to debug.
→ What to do instead: Fix specificity at the selector level. If a third-party library (e.g., bootstrap, OneTrust) overrides your styles, increase selector specificity with a parent class, or use CSS Layers (`@layer`) to establish the correct cascade order.
11. **NEVER use placeholder text or `Lorem ipsum` in component examples.**
→ Why it fails: AI agents copy example content into production when refactoring. "Lorem ipsum" in a financial product creates trust issues and accessibility failures (screen readers announce it as content).
→ What to do instead: Use real Cash App content strings ("The way money should work", "Get started", "Send money for free") from the extracted element inventory.
---
## Appendix A: Complete Token Reference
Every token extracted from the source. §0 CORE TOKENS is the primary AI signal; this appendix is reference material an AI can cross-check against when a curated role is missing.
```css
/* Colours (42) */
--brand-surface-1: rgb(0, 224, 19); /* Brand surface, dominant on 2 elements — e.g. "Sign up now→" /* mined from computed styles */ */
--cash-green: rgb(0, 224, 19);
--cash-black: rgb(0, 0, 0);
--cash-white: rgb(255, 255, 255);
--cash-primitive-green: rgb(0, 224, 19);
--cash-primitive-black: rgb(0, 0, 0);
--cash-primitive-white: rgb(255, 255, 255);
--cash-primitive-gray-100: rgb(244, 244, 244);
--cash-primitive-gray-200: rgb(240, 240, 240);
--cash-primitive-gray-300: rgb(229, 229, 229);
--cash-primitive-gray-400: rgb(184, 184, 184);
--cash-primitive-gray-500: rgb(153, 153, 153);
--cash-primitive-gray-600: rgb(115, 115, 115);
--cash-primitive-gray-700: rgb(102, 102, 102);
--cash-primitive-gray-800: rgb(75, 75, 75);
--cash-primitive-purple: rgb(84, 32, 194);
--cash-primitive-link-blue: rgb(0, 0, 238);
--cash-bg-surface: var(--cash-primitive-green);
--cash-color-page-bg: var(--cash-primitive-black);
--cash-color-surface-nav: var(--cash-primitive-black);
--cash-color-surface-elevated: var(--cash-primitive-white);
--cash-color-text-primary: var(--cash-primitive-white);
--cash-color-text-inverted: var(--cash-primitive-black);
--cash-color-text-heading: var(--cash-primitive-black);
--cash-color-text-muted: var(--cash-primitive-gray-700);
--cash-color-text-disabled: var(--cash-primitive-gray-500);
--cash-color-action-primary-bg: var(--cash-primitive-white);
--cash-color-action-primary-text: var(--cash-primitive-black);
--cash-color-action-brand: var(--cash-primitive-green);
--cash-color-hover-overlay: 0.7;
--cash-color-border-input: rgb(112, 112, 112);
--cash-color-border-tag: var(--cash-primitive-gray-600);
--cash-color-focus-ring: var(--cash-primitive-black);
--cash-btn-primary-bg: var(--cash-color-action-primary-bg);
--cash-btn-brand-bg: var(--cash-color-action-brand);
--cash-nav-bg: var(--cash-color-surface-nav);
--cash-input-bg: var(--cash-primitive-white);
--cash-input-border: var(--cash-color-border-input);
--cash-card-bg: transparent;
--cash-border-input: 1px solid rgb(112,112,112);
--cash-border-tag: 1px solid var(--cash-primitive-gray-600);
--cash-border-focus: 2px solid rgb(0,0,0);
/* Typography (44) */
--font-size-xs: 12px; /* 9 elements — e.g. span "Sign up", a "Sign up", a "Log in" /* mined from computed styles */ */
--font-size-sm: 14px; /* 9 elements — e.g. a "Get started", a "Learn about Green", a "Meet Cash App Card" /* mined from computed styles */ */
--font-size-md: 15.9999px; /* 88 elements — e.g. h6 "Learn more", h6 "Stay in Touch", p "Pay over time with C" /* mined from computed styles */ */
--font-size-lg: 17.9999px; /* 59 elements — e.g. p "From getting paid to", p "It's easier than eve", p "Explore our flexible" /* mined from computed styles */ */
--font-size-xl: 23.9999px; /* 6 elements — e.g. h4 "Bank* on your terms", h4 "Order a Cash App Car", h4 "Send money for free" /* mined from computed styles */ */
--font-size-2xl: 39.9999px; /* 12 elements — e.g. h2 "Earn, save, and do m", h2 "Cash App Card is the", h2 "Access cash when you" /* mined from computed styles */ */
--font-size-3xl: 55.9998px; /* 2 elements — e.g. h1 "The way money should", p "→" /* mined from computed styles */ */
--font-weight-regular: 400; /* 184 elements — e.g. h1 "The way money should", h2 "Earn, save, and do m", h2 "Cash App Card is the" /* mined from computed styles */ */
--font-weight-medium: 500; /* 3 elements — e.g. span "Sign up", a "Sign up", a "1 (800) 969-1940" /* mined from computed styles */ */
--line-height-normal: 21.5999px; /* 31 elements — e.g. p "Editor’s Choice on t", p "Apple App Store and ", p "Rated Excellent on T" /* mined from computed styles */ */
--line-height-loose: 25.1999px; /* 28 elements — e.g. p "From getting paid to", p "It's easier than eve", p "Explore our flexible" /* mined from computed styles */ */
--cash-font-stack: "Cash Sans", "Helvetica Neue", helvetica, sans-serif;
--cash-font-stack-wide: "Cash Sans Wide", "Helvetica Neue", helvetica, sans-serif;
--cash-font-stack-mono: "Cash Sans Mono", monospace;
--cash-font-size-xs: 12px;
--cash-font-size-sm: 14px;
--cash-font-size-md: 16px;
--cash-font-size-lg: 18px;
--cash-font-size-xl: 24px;
--cash-font-size-2xl: 40px;
--cash-font-size-3xl: 56px;
--cash-btn-primary-text: var(--cash-color-action-primary-text);
--cash-btn-brand-text: var(--cash-primitive-black);
--cash-nav-text: var(--cash-primitive-white);
--cash-input-text: var(--cash-primitive-black);
--cash-card-text: var(--cash-primitive-black);
--cash-type-h1-line-height: 53.2px;
--cash-type-h1-letter-spacing: -1.68px;
--cash-type-h2-line-height: 44px;
--cash-type-h2-letter-spacing: -1.2px;
--cash-type-h4-line-height: normal;
--cash-type-body-lg-line-height: 25.2px;
--cash-type-body-line-height: 19.2px;
--cash-type-label-line-height: normal;
--cash-type-button-line-height: 14px;
--cash-type-button-letter-spacing: -0.28px;
--cash-type-caption-line-height: normal;
--cash-font-weight-regular: 400;
--cash-font-weight-medium: 500;
--cash-font-weight-semibold: 600;
--cash-font-weight-bold: 700;
--cash-font-weight-black: 900;
--cash-line-height-normal: 21.6px;
--cash-line-height-loose: 25.2px;
/* Spacing (40) */
--ot-footer-space: 160px;
--space-xs: 10.5px; /* 27 elements — e.g. a .gallery-themed-button-module-sass-module, a .gallery-themed-button-module-sass-module, a .gallery-themed-button-module-sass-module /* mined from computed styles */ */
--space-sm: 15.99px; /* 18 elements — e.g. a .gallery-themed-button-module-sass-module, a .gallery-themed-button-module-sass-module, a .gallery-themed-button-module-sass-module /* mined from computed styles */ */
--space-md: 19.88px; /* 18 elements — e.g. a .gallery-themed-button-module-sass-module, a .gallery-themed-button-module-sass-module, a .gallery-themed-button-module-sass-module /* mined from computed styles */ */
--space-lg: 20px; /* 15 elements — e.g. main .home-fall-release-page-module-sass-modul, main .home-fall-release-page-module-sass-modul, header .gallery-nav-header-module-sass-module__- /* mined from computed styles */ */
--space-xl: 24px; /* 56 elements — e.g. section .three-column-grid-section-module-sass-mo, section .three-column-grid-section-module-sass-mo, section .three-column-grid-section-module-sass-mo /* mined from computed styles */ */
--space-2xl: 32px; /* 12 elements — e.g. div .card-grid-section-module-sass-module__u7, div .card-grid-section-module-sass-module__u7, div .card-grid-section-module-sass-module__u7 /* mined from computed styles */ */
--space-3xl: 90px; /* 42 elements — e.g. section .three-column-grid-section-module-sass-mo, section .three-column-grid-section-module-sass-mo, section .three-column-grid-section-module-sass-mo /* mined from computed styles */ */
--cash-space-xs: 8px;
--cash-space-sm: 16px;
--cash-space-md: 20px;
--cash-space-lg: 24px;
--cash-space-xl: 32px;
--cash-space-2xl: 64px;
--cash-space-3xl: 96px;
--cash-type-h1-size: 56px;
--cash-type-h2-size: 40px;
--cash-type-h4-size: 24px;
--cash-type-body-lg-size: 18px;
--cash-type-body-size: 16px;
--cash-type-label-size: 16px;
--cash-type-button-size: 14px;
--cash-type-caption-size: 12px;
--cash-type-mono-size: 16px;
--cash-space-1: 4px;
--cash-space-2: 8px;
--cash-space-3: 12px;
--cash-space-4: 16px;
--cash-space-5: 20px;
--cash-space-6: 24px;
--cash-space-8: 32px;
--cash-space-12: 48px;
--cash-space-16: 64px;
--cash-space-24: 96px;
--cash-btn-padding-v: 14px;
--cash-btn-padding-h: var(--cash-space-sm);
--cash-btn-gap: var(--cash-space-2);
--cash-nav-padding-top: 86px;
--cash-container-max: 1440px;
--cash-container-padding: var(--cash-space-8);
/* Radius (11) */
--radius-sm: 2px; /* 10 elements — e.g. button .ot-close-icon, button, button /* mined from computed styles */ */
--radius-md: 14.3%; /* 4 elements — e.g. div .footer-text-card-module-sass-module__j2duua__footerTextCard "5★Editor’s Choice on", div .footer-text-card-module-sass-module__j2duua__footerTextCard "9.9m+Apple App Store", div .footer-text-card-module-sass-module__j2duua__footerTextCard "4.5★Rated Excellent " /* mined from computed styles */ */
--radius-lg: 15.9% / 13%; /* 7 elements — e.g. div .background-video-module-sass-module__cXTqMG__backgroundVideo, img .responsive-image-module-sass-module__yuR0Wa__responsiveImage, img .responsive-image-module-sass-module__yuR0Wa__responsiveImage /* mined from computed styles */ */
--radius-full: 17px; /* 1 element — e.g. button "Filter Icon" /* mined from computed styles */ */
--cash-radius-sm: 2px;
--cash-radius-pill: 100px;
--cash-input-radius: 50px;
--cash-card-radius: 0px;
--cash-radius-none: 0px;
--cash-radius-input: 50px;
--cash-radius-image: 14.3%;
/* Effects (4) */
--cash-shadow-none: none;
--cash-shadow-card-hover: rgba(0,0,0,0.12) 0px 8px 24px;
--cash-shadow-scrollbar: rgb(184, 184, 184);
--cash-transition-opacity: opacity 0.3s ease;
/* Motion (9) */
----motion-modal-module-sass-module__HkZrsW__fadein: @keyframes modal-module-sass-module__HkZrsW__fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes modal-module-sass-module__HkZrsW__fadein */
----motion-image-module-sass-module__r2BKGa__fadein: @keyframes image-module-sass-module__r2BKGa__fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes image-module-sass-module__r2BKGa__fadein */
----motion-campaign-form-module-sass-module__B0Q0GW__pulse: @keyframes campaign-form-module-sass-module__B0Q0GW__pulse {
0% { opacity: 1; transform: scale(0.4); }
100% { opacity: 0.1; transform: scale(1.1); }
}; /* @keyframes campaign-form-module-sass-module__B0Q0GW__pulse */
----motion-gallery-content-toggle-section-module-sass-module__ogwTgG__fadein: @keyframes gallery-content-toggle-section-module-sass-module__ogwTgG__fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes gallery-content-toggle-section-module-sass-module__ogwTgG__fadein */
----motion-my-first-stock-splash-screen-module-sass-module__W6u6EG__introAnimation: @keyframes my-first-stock-splash-screen-module-sass-module__W6u6EG__introAnimation {
0% { opacity: 0; transform: scale(1.05); }
100% { opacity: 1; transform: scale(1); }
}; /* @keyframes my-first-stock-splash-screen-module-sass-module__W6u6EG__introAnimation */
----motion-fall-release-floating-cta-module-sass-module__dyHkFW__ctaSlideIn: @keyframes fall-release-floating-cta-module-sass-module__dyHkFW__ctaSlideIn {
100% { width: 90vw; left: 5vw; transform: translateY(0px); }
}; /* @keyframes fall-release-floating-cta-module-sass-module__dyHkFW__ctaSlideIn */
----motion-fall-release-floating-cta-module-sass-module__dyHkFW__ctaSlideOut: @keyframes fall-release-floating-cta-module-sass-module__dyHkFW__ctaSlideOut {
100% { width: 90vw; left: 5vw; transform: translateY(calc(100% + 20px)); }
}; /* @keyframes fall-release-floating-cta-module-sass-module__dyHkFW__ctaSlideOut */
--duration-fast: 0.3s; /* 10 elements — e.g. a, a, a /* mined from computed styles */ */
--ease-default: ease; /* 185 elements — e.g. button, button, button /* mined from computed styles */ */
```
## Appendix B: Token Source Metadata
```yaml
tokenSource: reconstructed-from-computed
site: cash.app
extractedAt: 2024
cssCustomPropertiesFound: 1
# Only --ot-footer-space (OneTrust third-party) and --brand-surface-1 (green) were found as actual CSS custom properties.
# All other tokens are synthesised from computed styles on key elements.
confidence: low
# Low confidence due to minimal CSS custom property usage. Cash App uses CSS Modules
# (Sass), meaning design tokens are compiled away at build time and not exposed as
# runtime CSS variables. The reconstructed token system represents the computed
# output, not necessarily the source Sass variables.
clusteringMethod:
colours: "Grouped by hue family (black cluster, white/gray cluster, green accent).
Gray scale clustered by usage context (hover states, disabled states, borders).
Only 2 truly distinct brand colours: black and Cash App Green."
spacing: "Clustered around 4px grid. Source values 10.5px, 15.99px, 19.88px, 90px
are off-grid — rounded to 8px, 16px, 20px, 96px respectively.
Exact source values preserved in component-level documentation."
radius: "Four distinct values extracted from page elements.
2px (small chrome), 50px/100px (pill forms/buttons), 14.3% (squircle images),
15.9%/13% (elliptical containers).
WARNING: 14.3% and 15.9%/13% are percentage-based (aspect-ratio-relative),
not fixed pixel values — must be applied to elements where aspect ratio is known."
typography: "High confidence. 5 discrete font sizes form a clear scale (12/14/16/18/24/40/56px).
Font family is uniquely identifiable (Cash Sans CDN paths extracted).
Letter-spacing values extracted directly from computed h1/h2/button styles."
motion: "High confidence. Single duration (0.3s) and single easing (ease) dominate all 185+
transition-bearing elements. Keyframe animations extracted from CSS rule names."
notes:
- "Cash Sans is a proprietary typeface served from cash-f.squarecdn.com CDN.
Do not substitute with any system or Google font."
- "The body element has color: rgb(255,255,255) — the page default is WHITE TEXT on BLACK bg.
Heading elements (h1-h3) show color: rgb(0,0,0) indicating section-level background inversions."
- "Modal element uses Arial as font-family — this appears to be a third-party overlay
(OneTrust cookie banner), NOT the Cash App design system. Do not replicate."
- "bootstrap detected as a library dependency — may contribute some utility classes,
but Cash App styles override via CSS Modules specificity."
- "nextJs detected — CSS Modules (Sass) is the styling approach, confirmed by
hashed classnames in extracted selectors (e.g. __6sJe3W__button, __yuR0Wa__responsiveImage)."
- "radius-md (14.3%) and radius-lg (15.9%/13%) are used on images and media containers,
NOT on UI chrome or buttons. Their percentage-based values create a consistent
'squircle' effect tied to the element's own dimensions."
```More from the gallery
Browse all kits →You may also like

Contra
MITPlayful yet professional design system with teal and purple accents, bold typography, and vibrant accent surfaces—built for modern SaaS platforms and landing pages
03
lightboldsaaslanding-page

DoorDash
MITClean, accessible food-delivery system with DoorDash's signature red accent, light neutral palette, and system-font typography—built for rapid product development
03
lightecommsaasmobile

Mercedes-Benz
MITLuxe, minimalist design system with sharp black-and-white contrast and serif typography, crafted for premium automotive and lifestyle brands
05
darkminimalboldecomm