Cash App Design System
Overview
Cash App's visual identity is an exercise in confident minimalism backed by maximalist brand expression. The system centers on a striking {colors.canvas} — a high-voltage green (#00e013) that saturates the entire viewport in its default state, creating an almost aggressive sense of energy and approachability. Against this electric field, the brand deploys near-black {colors.ink} (#000000) for its primary typographic voice and crisp white {colors.surface} for content containers, creating a three-color foundation that feels both playful and serious — fintech that doesn't take itself too seriously while handling real money.
The single typography move that defines Cash App is its exclusive use of Cash Sans across every role, from 56px display headlines down to 12px captions, never exceeding weight 400 for editorial text and reserving weight 500 only for button labels. This creates a remarkably even tonal field where hierarchy comes from scale alone — not from weight contrast. Letter-spacing is consistently negative (around -0.03em at larger sizes), pulling characters tighter than typical web defaults to create a dense, modern feel reminiscent of Swiss design but with Silicon Valley irreverence. The type never shouts; it states.
Shape language is aggressively rounded. Every interactive element uses either {rounded.pill} (100px radius, effectively infinite) or {rounded.full} (9999px), creating buttons that are pure capsules, menu toggles that are perfect circles, and input fields with only the gentlest suggestion of corners. This pill vocabulary extends to the phone mockup itself, whose screen carries {rounded.xl} (24px) corner rounding — softer than hardware but still distinctly device-shaped. The only sharp edges in the system belong to the logo mark (a square with {rounded.md} rounding) and certain status indicators.
Two sub-systems emerge: the marketing surface (green-canvas hero bands, white CTA cards, phone-as-product-demo) and the app-preview surface (white card bodies with subtle {shadows.phone} elevation, dark headers mimicking the app's native chrome). These coexist in the same layout grid but operate under different color rules — marketing lives on green; app preview lives on white with black accents.
Key Characteristics:
- Voltage-green
{colors.canvas}(#00e013) as the dominant hero background — not an accent, but the stage itself - Exclusive use of
Cash Sansat weight{typography.display-lg.fontWeight}(400) for all editorial text;{typography.button.fontWeight}(500) reserved solely for button labels - Negative letter-spacing (
{typography.display-lg.letterSpacing}of-0.03em) creating tight, modern character density - Pill-shaped everything:
{rounded.pill}for buttons,{rounded.circle}for toggles,{rounded.full}for nav CTAs - Three-surface model:
{colors.canvas}(marketing backgrounds),{colors.surface}(content cards),{colors.surface-dark}(app chrome) - Centered 1440px container with generous
{spacing.hero}(90px) vertical rhythm in hero sections - Phone mockup with
{shadows.phone}depth, serving as the primary product visualization pattern - Zero decorative shadows on flat elements; elevation reserved exclusively for the floating device
Colors
Brand & Accent
- Primary Green (
{colors.primary}— #00e013): The defining brand color — used as full-bleed background for hero sections, status indicators, and accent elements. This is not a subtle tint; it is the canvas itself. - Primary Hover (
{colors.primary-hover}— #00c510): Darkened variant for hover/active states on green-tinted surfaces. - Black Accent (
{colors.accent}— #000000): Used as solid background for login buttons, menu toggles, and app header bars. Serves as the "dark mode" surface within the otherwise light/green system. - White Secondary (
{colors.secondary}— #ffffff): Button backgrounds, text-on-dark surfaces, and card interiors. Provides the breathing room against green and black.
Surface
- Canvas (
{colors.canvas}— #00e013): The marketing page's default background — covers hero bands, footer areas, and any section meant to feel "branded." Extracted from the dominant viewport fill. - Surface White (
{colors.surface}— #ffffff): Content card backgrounds, button fills, cookie banners, and the phone mockup's body area. - Surface Dark (
{colors.surface-dark}— #000000): App header simulation inside the phone mockup, login button backgrounds, and menu toggle backgrounds. - Card Surface (
{colors.surface-card}— #ffffff): Specifically the interior of the phone mockup where balance and actions live.
Text & Ink
- Ink (
{colors.ink}— #000000): Primary text color for headlines, body copy, and UI labels on light backgrounds. Near-black for maximum contrast without harshness. - Body Muted (
{colors.body}— #999999): Secondary text — captions, metadata, helper text, and de-emphasized UI strings. Medium gray providing clear hierarchy below ink. - Muted Dark (
{colors.muted}— #555555): Tertiary text for cookie banner legal copy and very low-emphasis labels. - On Primary (
{colors.on-primary}— #000000): Text color when rendering atop{colors.canvas}— always black since the green is luminous enough to support it. - On Dark (
{colors.on-dark}— #ffffff): Text color for anything rendered on{colors.surface-dark}— always white for AA+ contrast. - On Surface (
{colors.on-surface}— #000000): Default readable text on{colors.surface}— identical to{colors.ink}in practice.
Hairlines & Borders
- Hairline (
{colors.hairline}— rgba(0, 0, 0, 0.15)): Subtle dividers between list items, card borders at rest state. - Border Strong (
{colors.border-strong}— #000000): Outlined button strokes, focus rings, and high-contrast borders. - Border Light (
{colors.border-light}— rgba(0, 0, 0, 0.08)): Very subtle separators, barely visible card outlines.
Semantic
- Error Red (
{colors.error}— #ff3b30): Form validation failures, alert states. - Success Green (
{colors.success}— #00e013): Matches brand primary; used for confirmation states. - Warning Amber (
{colors.warning}— #ffb800): Cautionary notices. - Info Blue (
{colors.info}— #0000ee): Standard link blue, informational callouts. - Link (
{colors.link}— #0000ee): Hyperlink color — traditional web blue, distinct from brand palette. - Link Active (
{colors.link-active}— #000099): Visited or active link state.
Typography
Font Family
The entire Cash App ecosystem runs on Cash Sans, a proprietary geometric-humanist sans-serif designed specifically for Square/Cash App. It ships in five weights (Regular 400, Medium 500, Semibold 600, Bold 700, Black 900) plus a companion "Cash Sans Wide" extended variant, though the marketing site restricts itself almost entirely to Regular (400) for editorial text and Medium (500) for interactive elements. The fallback stack is "Helvetica Neue", helvetica, sans-serif — a safe, widely-available fallback that preserves the geometric character of the original. No serif or monospace faces appear in the marketing surface; the app preview's numerical displays use Cash Sans at larger sizes with tabular spacing implied by the font's OpenType features.
Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| {typography.display-xl} | 64px | 400 | 1.0 | -0.03em | Oversized hero moments (rare) |
| {typography.display-lg} | 55.9998px | 400 | 0.95 | -0.03em | Main hero headline ("The way money should work") |
| {typography.title-md} | 39.9999px | 400 | 1.1 | -0.03em | Section headings, feature titles |
| {typography.title-sm} | 23.9999px | 400 | 1.1 | -0.03em | Card titles, sub-section headings |
| {typography.body-lg} | 17.9999px | 400 | 1.5 | 0 | Hero descriptive paragraph |
| {typography.body-md} | 15.9999px | 400 | 1.2 | 0 | Body copy, app preview text |
| {typography.body-sm} | 14px | 400 | 1.4 | 0 | Secondary body, smaller UI |
| {typography.caption} | 12px | 400 | 1.2 | -0.02em | Metadata, timestamps, cookie text |
| {typography.button} | 14px | 500 | 1.0 | 0 | Primary button labels |
| {typography.button-small} | 12px | 500 | 1.0 | 0 | Nav buttons (Sign up, Log in) |
| {typography.label} | 13.3333px | 400 | 1.4 | 0 | Form labels, checkbox text |
| {typography.mono} | 16px | 400 | 1.4 | 0.02em | Numerical/balance displays |
Principles
The typography system trusts scale above all else. From 56px headlines to 12px captions, every role uses weight 400 — there is no bold, no semibold, no black in editorial contexts. This is a deliberate choice: by keeping weight constant, Cash App forces hierarchy through size differential alone, which produces a quieter, more confident reading experience. The eye moves from large to small without being yanked by weight changes. Only interactive elements break this rule: buttons use weight 500 (Medium), a barely-perceptible thickening that signals tappability without shouting.
Letter-spacing is uniformly negative at sizes above 16px, typically -0.03em (approximately -1.68px at 56px). This tight tracking creates a compact, contemporary feel — characters nestle together rather than float apart. At caption sizes (12px), tracking tightens slightly to -0.02em to maintain legibility. Monospace-style numerals (balances, amounts) use positive spacing (+0.02em) to give figures room to breathe, preventing the crowded look that plagues tightly-tracked numbers.
There are no italic or uppercase conventions in the marketing surface. Headline case follows sentence case (capitalized first word only), and the brand voice reads conversational rather than institutional. This lowercase friendliness, combined with tight tracking and uniform weight, gives Cash App its distinctive "text-message-meets-bank-statement" tone.
Note on Font Substitutes
Cash Sans is proprietary to Square, Inc. and served via their CDN (cash-f.squarecdn.com). For open-source reimplementation, substitute Inter (Google Fonts, Rasmus Andersson) as the closest available match: it shares the geometric skeleton, similar x-height, and supports negative tracking gracefully. Define the substitution at the CSS variable level:
:root {
--font-family-base: "Inter", "Helvetica Neue", helvetica, sans-serif;
}
For numerical displays requiring tabular figure support, Inter's font-feature-settings: "tnum" provides the aligned-digit behavior Cash Sans offers natively.
Layout
Spacing System
- Base unit: 4px (implied by the 2px/8px/12px/16px progression), though the most frequently occurring value is
{spacing.xl}(20px). - Tokens:
{spacing.xxs}(2px — hairline gaps),{spacing.xs}(4px — icon padding),{spacing.sm}(8px — internal component gaps),{spacing.md}(11px — form spacing),{spacing.base}(16px — card internal padding),{spacing.lg}(18px — medium gaps),{spacing.xl}(20px — standard gap, most common),{spacing.xxl}(24px — section-internal spacing),{spacing.xxxl}(32px — major vertical gaps),{spacing.section}(40px — band padding),{spacing.wide}(80px — extended breaks),{spacing.hero}(90px — hero bottom padding). - Section padding (vertical):
{spacing.hero}(90px) — applied to the bottom of the{component.hero-band}, creating substantial clearance before subsequent content. - Card internal padding:
{component.phone-screen-body}uses{spacing.xl}(20px);{component.cookie-banner}uses{spacing.lg}horizontal +{spacing.xl}vertical. - Gutters: Horizontal padding of 20px on
{component.top-nav}; no explicit gutter token detected — the system uses percentage-based flex/grid gutters within the 1440px container.
Grid & Container
- Max content width: 1440px (hard-coded on
<main>and<section>elements). - Density choice: Editorial-sparse — the hero band contains at most two columns (headline left, phone right) with ~60/40 split implied by the visual weight distribution. No multi-column marketplaces or dashboards visible in the marketing surface.
- Grid behavior: The layout appears to use CSS Grid or Flexbox with implicit column definitions. The hero arranges children in a row with the phone mockup taking roughly 45% width and the headline block taking the remaining space, both vertically centered within the
{component.hero-band}'s 90px-bottom-padded area. - Hero column split: Left column holds
{component.hero-headline}+{component.hero-subheadline}+ optional CTA; right column holds{component.phone-mockup-container}(the floating device). On desktop, these sit side-by-side with the phone slightly elevated via shadow.
Whitespace Philosophy
Cash App practices generous asymmetrical whitespace: the green canvas breathes freely, with the headline positioned in the lower-left quadrant of the hero band (not centered), and the phone mockup floating in the upper-right. Vertical rhythm is loose — 90px between the nav baseline and hero bottom edge, 40px between major sections internally. The system refuses density; each element (headline, phone, CTA) gets its own "room" without crowding. This spaciousness reinforces the brand promise: money management can be effortless, uncluttered.
Header Architecture
[Logo □] [Sign up →] [Log In] [≡]
← 1440px max-width, transparent background, 64px height →
The {component.top-nav} is transparently overlaid on the {colors.canvas} green. Logo (black square with $ in green) sits flush-left. Utility buttons sit flush-right: {component.button-signup} (white pill, black text), then {component.button-login} (black pill, white text), then {component.button-menu-toggle} (black circle, hamburger icon).
Hero Section
┌─────────────────────────────────────────────┐
│ [GREEN CANVAS - full bleed] │
│ │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ │ │ ╭──────────╮ │ │
│ │ The way │ │ │ Money │ │ │
│ │ money │ │ │ $789.13 │ │ │
│ │ should work │ │ ╰──────────╯ │ │
│ │ │ │ │ │
│ │ Subhead... │ │ (phone mockup) │ │
│ │ │ │ │ │
│ └──────────────┘ └────────────────┘ │
│ │
│ [Get started →] │
└─────────────────────────────────────────────┘
↑ 90px bottom padding
Left block: {component.hero-headline} (56px, black) followed by {component.hero-subheadline} (~18px, black). Right block: {component.phone-mockup-container} with {shadows.phone} elevation, containing {component.phone-screen-header} (dark bar) and {component.phone-screen-body} (white card showing balance). CTA ({component.button-get-started}) floats bottom-right of the hero, outside the phone but within the green field.
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| Flat | No shadow, solid {colors.canvas} or {colors.surface} | Background bands, flat buttons |
| Hairline outline | 1px {colors.border-strong} or {colors.hairline} | {component.outlined-button}, subtle card borders |
| Soft drop | {shadows.soft} (0 2px 8px rgba(0,0,0,0.06)) | Cookie banner, minor lift |
| Modal drop | {shadows.modal} (0 16px 48px rgba(0,0,0,0.2)) | Potential overlay panels |
| Device shadow | {shadows.phone} (0 24px 64px rgba(0,0,0,0.25)) | Phone mockup — the deepest element in the system |
Philosophy: Cash App's marketing surface is overwhelmingly flat-by-default with elevation reserved for exactly one element: the phone mockup. This device shadow is the singular depth cue — a deliberate choice that says "this is a real thing you hold" while keeping everything else (buttons, cards, nav) firmly two-dimensional. When shadows do appear, they are neutral-black (no cool/warm tinting) and relatively soft-edged, avoiding the hard-cut "material" look in favor of a gentler lift. Buttons have zero shadow regardless of state; depth communicates only through the phone's presence.
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
| {rounded.sm} | 6px | Input fields, minor containers |
| {rounded.DEFAULT} | 12px | Cookie banner, general cards |
| {rounded.md} | 16px | Logo mark container |
| {rounded.lg} | 20px | Phone mockup outer frame |
| {rounded.xl} | 24px | Phone screen top corners |
| {rounded.pill} | 100px | Primary CTAs, action buttons |
| {rounded.full} | 9999px | Nav utility buttons (Sign up, Log in) |
| {rounded.circle} | 50% | Menu toggle, avatars, status dots |
Photography Geometry
No photography is present in the marketing hero — the sole imagery is the phone mockup screenshot, which occupies a portrait aspect ratio (roughly 9:19.5, matching iPhone dimensions). The mockup has {rounded.xl} (24px) corner rounding on its outer frame and slightly less on the inner screen area. Avatars within the app preview use {rounded.circle} (perfect circles). No full-bleed image treatments, no gradient overlays on photos, no cropped-to-edge layouts exist in this view.
Components
No hover states documented. Hover behavior is unreliable to extract from a single screenshot. State variants live as separate entries in the
components:frontmatter (e.g.{component.button-signup}-hover,{component.input-field}-focus); add hover styling at implementation time per your stack's conventions.
Navigation
{component.top-nav} — Fixed-position header bar overlaid on the green canvas. Transparent background, 64px height, 20px horizontal padding. Contains {component.nav-logo} (left), {component.button-signup} + {component.button-login} + {component.button-menu-toggle} (right, in that order). No border, no shadow.
{component.nav-logo} — Square black container ({rounded.md}) holding the white $ symbol on green background (or inverse depending on context). 44×44px clickable area linking to home.
{component.button-signup} — White pill-shaped button ({rounded.full}) with black text ("Sign up →") at {typography.button-small} size. Padding 10px horizontal, 20px vertical. No border, no shadow.
{component.button-login} — Black pill-shaped button ({rounded.full}) with white text ("Log in") at {typography.button-small} size. Same dimensions as Sign up, creating a paired visual weight.
{component.button-menu-toggle} — Perfect circle ({rounded.circle}), 40×40px, black background, white hamburger icon (three lines). No label text; icon-only interaction.
Hero & Marketing Surfaces
{component.hero-band} — Full-width section with {colors.canvas} (green) background. 86px top padding (clearing the nav), 90px bottom padding. Contains the two-column hero layout described in Layout > Hero Section.
{component.hero-headline} — The main H1 ("The way money should work"). Uses {typography.display-lg} (56px, weight 400, -1.68px tracking), {colors.ink} (black). No max-width constraint observed — spans its column naturally.
{component.hero-subheadline} — Descriptive paragraph below headline. Uses {typography.body-lg} (~18px, weight 400), {colors.ink}. Line length constrained by parent column width (~50-60ch ideal).
{component.button-get-started} — Primary conversion CTA. White background ({colors.surface}), black text ({colors.ink}) reading "Get started →", pill shape ({rounded.pill}). Padding 14px vertical, 20px horizontal. Positioned in the hero's lower-right area, visually associated with the phone mockup.
{component.footer-band} — Bottom-of-page section returning to {colors.canvas} background. Contains footer links/copy in {typography.body-md}. 40px vertical padding.
Product Preview (Phone Mockup)
{component.phone-mockup-container} — Outer wrapper for the device image. Rounded rectangle ({rounded.lg}, 20px) with {shadows.phone}` elevation (0 24px 64px rgba(0,0,0,0.25)). Contains the simulated app interface.
{component.phone-screen-header} — Dark bar simulating iOS/status area. {colors.surface-dark} (black) background, {colors.on-dark} (white) text showing time ("9:41"), signal icons, and app title ("Money") plus search/avatar controls. Height 52px, top corners rounded ({rounded.xl}, 24px) to match phone frame.
{component.phone-screen-body} — White card area below header. {colors.surface-card} (white) background, {colors.ink} (black) text. 20px internal padding. Contains {component.balance-display}, action buttons, status rows, and savings preview.
{component.balance-display} — Large numerical readout ("$789.13"). Uses {typography.display-xl} (64px implied by scale) or {typography.mono} for tabular alignment. Black text, no background. Label "Cash balance •• 4465" sits above in smaller type.
{component.action-button-pair} — Two side-by-side pill buttons inside the phone: "Add money" and "Withdraw". White background, black text, {rounded.pill} shape. 16px vertical, 32px horizontal padding. These simulate in-app actions.
{component.status-row} — Single-line item showing "Green status" with amount "$440 to renew". Includes {component.icon-circle} (small green circle with icon) as leading visual. No background, just text and icon inline.
{component.savings-section} — Section header "Savings" with amount "$080.00" below. Uses {typography.title-md} for label, larger size for value.
Forms & Inputs
{component.cookie-banner} — Floating notification in bottom-left corner. White background, {rounded.DEFAULT} (12px), {shadows.soft} elevation. Contains legal text in {typography.caption} (12px, gray). Close "X" icon in top-right. Max-width ~380px.
{component.input-field} — Standard text input (observed in hidden/form contexts). White background, {rounded.sm} (6px), 12px vertical + 16px horizontal padding. Border likely {colors.hairline} on focus (not visible in static screenshot).
{component.checkbox-input} — Native checkbox replacement area. Transparent background, {typography.label} (13.3333px) for label text. Custom checkmark likely rendered via pseudo-element or SVG (not extracted from static state).
{component.outlined-button} — Ghost/outlined variant (observed in secondary contexts). Transparent background, 1px {colors.border-strong} (black) border, {rounded.pill} shape. Black text. 16px vertical, 20px horizontal padding. Used for secondary actions like "Learn about Green".
Iconography & Indicators
{component.icon-circle} — Small circular badge (28×28px, {rounded.circle}) with {colors.primary} (green) background. Holds a simple line icon (checkmark, dot, etc.) in {colors.on-primary} (black). Used for status indicators.
{component.avatar} — User profile picture placeholder. 40×40px, {rounded.circle}, gray background ({colors.muted}`) when no photo loaded.
Do's and Don'ts
Do
- Use
{colors.canvas}(#00e013) as full-bleed section backgrounds for branded impact — this green is the stage, not an accent color. - Set all editorial type to weight 400 using
{typography.display-lg.fontWeight}— never use bold (700) for headings. - Apply negative letter-spacing (
{typography.display-lg.letterSpacing}of-0.03em) to any text 24px or larger to match the tight Cash App character density. - Use
{rounded.pill}(100px) for all primary action buttons and{rounded.full}(9999px) for navigation utilities — the capsule vocabulary is non-negotiable. - Reserve weight 500 (
{typography.button.fontWeight}) exclusively for button labels — body copy, headings, and captions remain at 400. - Apply
{shadows.phone}(0 24px 64px rgba(0,0,0,0.25)) only to the phone mockup — all other elements stay flat with no box-shadow. - Pair
{component.button-signup}(white pill) and{component.button-login}(black pill)` side-by-side in the nav — they are a visual unit. - Let the headline sit in the lower-left quadrant of the hero rather than centering it — the asymmetric placement is intentional.
- Use
{colors.body}(#999999) for secondary/metadata text — never use black for timestamps or helper copy. - Keep the container max-width at 1440px and center it — the layout does not stretch edge-to-edge at ultra-wide resolutions.
Don't
- Don't apply gradients or texture overlays to the
{colors.canvas}green background — it is always a flat, solid hex fill. - Don't introduce a serif or monospace font into the marketing surface — Cash Sans handles every role including numbers.
- Don't add box-shadow to buttons, cards, or nav items (except the cookie banner's soft shadow and the phone's deep shadow) — flatness is the default.
- Don't use
{colors.link}(#0000ee) as a brand color — it exists only for traditional hyperlink semantics, not for UI chrome. - Don't round corners less than
{rounded.sm}(6px) on any visible element — the system has no sharp rectangles. - Don't place the CTA button directly under the headline text — it belongs in the lower-right, spatially near the phone mockup.
- Don't capitalize headlines beyond sentence case ("The way money should work", not "THE WAY MONEY SHOULD WORK").
- Don't expand the radius vocabulary beyond the defined tokens — if you need something rounder than
{rounded.pill}, you're looking for{rounded.full}or{rounded.circle}. - Don't use white text on the green canvas for body copy — always use
{colors.ink}(black) on{colors.canvas}(green passes WCAG contrast for black text).
Motion & Animation
Transition Tokens
--transition-bg: background-color 0.6s ease-in-out;
--transition-fill: fill 0.3s ease-in-out;
--transition-opacity-fast: opacity 0.1s linear;
--transition-opacity-slow: opacity 0.6s ease-in-out;
--transform-fade: opacity 0.6s, transform 0.6s;
--transition-generic: all 0.3s ease-in-out;
--transition-complex: opacity 0.1s linear, background-color 0.6s ease-in-out;
Keyframe Animations
modal-module__fadein— Opacity 0→1 reveal for modal/dialog entrances.image-module__fadein— Opacity 0→1 fade for lazy-loaded images.campaign-form__pulse— Subtle scale pulse (likely 1→1.02→1) for attention-drawing form elements.gallery-content-toggle__fadein— Crossfade between content tabs in gallery/carousel views.my-first-stock__introAnimation— Multi-stage entrance animation for the "first stock" splash screen (likely staggered reveals).fall-release-floating-cta__ctaSlideIn— Translate-Y entrance for the floating CTA button sliding up from bottom.fall-release-floating-cta__ctaSlideOut— Translate-Y exit for the floating CTA sliding downward.onetrust-fade-in— Cookie consent widget fade-in (third-party script).slide-down-custom— Generic Y-axis slide-down for dropdowns or expandable panels.
Interaction Patterns
- Floating CTA slide-up: The "Get started" equivalent button animates upward into view (
ctaSlideIn) after a delay or scroll threshold, then exits viactaSlideOutwhen dismissed or scrolled past. - Modal fade-ins: All overlays (cookie consent, modals) use opacity-only transitions over 0.1–0.3s — no scale or translate to avoid jarring motion.
- Form pulse: Campaign/lead-gen forms include a subtle pulse on the submit button to draw attention without being aggressive.
- Gallery crossfades: Tabbed content switches use opacity crossfades (no slide transitions), maintaining position while swapping visibility.
- Image lazy-load: Below-fold images fade in once scrolled into viewport (0.3s ease-in-out).
- Background color shifts: Any surface color change (e.g., theme toggle, state change) animates over 0.6s ease-in-out — noticeably slow for a polished, unhurried feel.
- SVG fill transitions: Icon color changes animate via the
fillproperty over 0.3s, ensuring smooth recoloring on hover/state.
Note: The motion level is moderate — animations exist but are restrained in amplitude. Nothing bounces, nothing spins, nothing uses spring physics. The 0.6s duration for background changes is unusually long by web standards, reinforcing the "unhurried" brand personality.
Imagery Style
- Primary imagery type: UI screenshot/mockup (photorealistic phone device rendering) — not illustration, not photography, not 3D render.
- Subject matter: The Cash App mobile interface itself — balance screens, action buttons, status indicators. The product IS the image.
- Color treatment: The phone screen shows realistic app UI with white cards, dark headers, and green accent dots — matching the brand palette exactly. No filters, no duotones, no color grading.
- Composition: Phone is angled slightly (3D perspective transform implied), floating above the green canvas with heavy drop shadow, positioned right-of-center.
- Role: Supporting — the image illustrates the verbal headline rather than replacing it. Users see what "managing money" looks like concretely.
- Signature technique: The floating device with deep shadow is Cash App's recurring visual motif — every marketing surface features a phone hovering in green space.
- No photography: No lifestyle photos, no human faces (except tiny avatar in app), no environment shots. Pure product UI.
- No illustration: No custom icons, patterns, or drawn elements beyond the UI itself.
- Aspect ratio: Portrait (9:19.5 iPhone ratio) for the mockup; the containing layout uses a rough golden-ratio split (headline narrower, phone wider).
- Background integration: The phone casts no colored reflection onto the green canvas — clean compositing with no ambient color bleed.
Icon System
- Library: Custom SVG (inline SVG or sprite-based, no external icon font detected). The system does not use Lucide, Heroicons, Material Icons, or Font Awesome.
- Specific icons observed:
- Hamburger menu (three horizontal lines) —
{component.button-menu-toggle} - Search magnifying glass — phone header
- Arrow-right (→) — button suffixes ("Sign up →", "Get started →")
- Close/X — cookie banner dismiss
- Dollar sign ($) — logo mark, balance prefix
- Checkmark/tick — implied in
{component.icon-circle}status indicators - Avatar placeholder — generic user silhouette
- Hamburger menu (three horizontal lines) —
- Treatment: Predominantly stroke-based (outline style) with consistent 1.5–2px stroke weight. Color set to
currentColor, inheriting from parent text color (black on light, white on dark). - Size alignment:
- Nav icons (hamburger): 18–20px, centered in 40×40px touch target
- Button arrows: 12–14px, inline with 12–14px button text
- Status icons inside circles: 14–16px, centered in 28×28px
{component.icon-circle} - Header icons (search): 20px, aligned with 16px header text baseline
- Grid alignment: Icons sit on the same baseline as adjacent text with optical adjustment (icons appear 1–2px smaller than cap height for visual balance).
Recommended Frontend Stack
- Framework: Next.js 14+ (React-based SSR/SSG, matches Square's infrastructure)
- Styling: SCSS Modules (BEM-ish naming detected: `gallery-nav-header-module-sass-module__`)
- Fonts: Self-hosted Cash Sans via @font-face (CDN: cash-f.squarecdn.com)
Fallback: Inter (Google Fonts) for open-source implementations
- Animation: CSS keyframes + JS IntersectionObserver for scroll triggers
Framer Motion acceptable for complex sequences
- Icons: Custom SVG components (inline, no external library)
- Component lib: None (bespoke component architecture)
- Build tool: Webpack 5+ or Vite (based on module naming convention)
Responsive Behavior
Breakpoints
| Name | Width | Key Changes | |---|---|---| | Mobile | < 768px | Single-column hero, stacked nav, phone mockup scales down to ~280px width, CTA becomes full-width below headline | | Tablet | 768px – 1024px | Two-column hero maintained but with reduced padding (hero padding drops from 90px to ~48px), phone mockup shrinks to ~320px | | Desktop | 1025px – 1440px | Full layout as documented: 1440px container, 90px hero padding, 56px headline, phone mockup ~375px width | | Wide | > 1440px | Container remains 1440px centered; green canvas extends edge-to-edge beyond container bounds |
Touch Targets
{component.button-signup}/{component.button.login}: ~40px height × variable width (min 88px recommended for WCAG AAA) — currently ~38px tall based on 10px padding + 12px font; may need increase to 44px for mobile compliance.{component.button-menu-toggle}: 40×40px circle — meets WCAG AAA minimum (44×44px) by 4px margin; acceptable.{component.button-get-started}: ~48px height (14px padding × 2 + 14px font + line-height) — exceeds 44px minimum, fully compliant.{component.action-button-pair}(inside phone): ~52px height — well above minimum; these are simulated UI anyway.{component.cookie-banner}close button: estimated 24×24px tap area — fails WCAG AAA on mobile; requires invisible expansion to 44×44px.
Collapsing Strategy
- Navigation: At mobile (< 768px), the
{component.button-menu-toggle}becomes the sole nav entry point;{component.button-signup}and{component.button.login}move into a slide-down menu panel triggered by the hamburger. - Hero columns: Stacks vertically on mobile — headline/subheadline occupy full width above the phone mockup, which centers horizontally at reduced scale (~80% of viewport width, max 340px).
- Phone mockup: Scales proportionally from ~375px (desktop) down to ~280px (mobile), maintaining aspect ratio. Shadow depth reduces proportionally to avoid overwhelming small screens.
- CTA positioning: Moves from hero lower-right (desktop) to immediately below the headline block (mobile), becoming a full-width pill button centered in the column.
- Cookie banner: Shifts from bottom-left floating position to fixed bottom-bar spanning full width with centered content, increased touch targets.
- Typography scaling:
{typography.display-lg}(56px) likely reduces to ~40px on mobile via fluid typography or breakpoint override;{typography.title-md}(40px) reduces to ~28px.
Image Behavior
- Phone mockup: Uses responsive images (
srcsetor<picture>) serving 1x/2x/3x variants. On mobile, the image width is capped at ~340px withheight: auto. The perspective angle may flatten slightly on small screens to reduce perceived distortion. - Avatars: Remain circular at all sizes, scaling from 40px (desktop) to 32px (mobile) within the phone preview.
- No art direction: The same phone composition serves all breakpoints (no alternative angles or crops for mobile).
Iteration Guide
- Start with the color foundation: Define CSS custom properties for every token in the
colors:frontmatter. Begin implementation by painting a full-bleed{colors.canvas}green section to verify the hex renders correctly — this color is the brand's heartbeat. - Import Cash Sans correctly: Use the provided
@font-facedeclarations pointing tocash-f.squarecdn.comfor production; substitute Inter via Google Fonts for development/open-source builds. Ensurefont-display: swapis set to prevent FOIT. - Build the hero first: Implement
{component.hero-band}with 1440px max-width container, 86px top padding, 90px bottom padding, and the two-column grid (headline left, phone right). Get the phone mockup's{shadows.phone}elevation working early — it's the hardest visual element to calibrate. - Implement the pill button system: Create a base
.btn-pillclass withborder-radius: 100px, then extend it for{component.button-get-started}(white/bg),{component.button-signup}(white/bg),{component.button-login}(black/bg), and{component.outlined-button}(transparent/bg + border). Ensure all use weight 500. - Set type scale with negative tracking: Apply
{typography.display-lg}(56px, -1.68px letter-spacing) to the H1. Verify the tight character spacing renders identically across Chrome/Safari/Firefox — some browsers clamp negative values differently. - Layer the nav overlay: Position
{component.top-nav}absolutely or fixed over the green canvas with transparent background. Ensure z-index stacking places it above content but below any potential modal layer. - Add motion last: Once static layout is pixel-match, implement the
ctaSlideIn/ctaSlideOutkeyframes for the floating CTA and the 0.6sbackground-colortransitions for surface changes. Test withprefers-reduced-motion: reducemedia query to disable or simplify. - Validate accessibility: Run contrast checks on
{colors.ink}(black) on{colors.canvas}(green) — this pair should pass WCAG AA for large text. Verify all touch targets hit 44×44px minimum; expand the cookie close button if needed. - Test responsive breakpoints: Shrink viewport to 375px width and verify the hero stacks, the phone mockup scales down, and the nav collapses to hamburger-only. Ensure no horizontal overflow occurs.
- Lint the spec: After implementation, run
npx @google/design.md lint DESIGN.mdto catch broken token references, orphaned components, or missing entries. Every{token.path}in your code must resolve to the YAML frontmatter.
Font Setup for Open Source Implementation:
<!-- In <head>, replace Cash Sans CDN with: -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root {
--font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
</style>
Define CSS variables mapping to every frontmatter token (e.g., --color-canvas: #00e013;, --radius-pill: 100px;, --spacing-hero: 90px;). Never hard-code values — always reference variables so the system stays synchronized with this spec.
Known Gaps
- Hover states: Not extractable from static screenshot. The frontmatter documents Default and Active/Pressed states where inferred (e.g.,
{component.button-get-started-active}would darken or shift), but hover-specific styles (subtle bg lighten, cursor change) must be added at implementation time. - Loading/skeleton states: No loading spinners, skeleton placeholders, or pending-state UI were visible. Fintech apps typically show shimmer effects on balance loading — these need design decisions.
- Form validation states: Beyond the basic
{component.input-field}structure, error messages, red borders ({colors.error}), and success checkmarks are not depicted. - Authenticated/dark-mode surfaces: The screenshot shows the public marketing landing page only. Dashboard views, transaction histories, settings panels, and authenticated flows (which may use darker themes) are not represented.
- Sub-brand palettes: Cash App has product variants (Afterpay, Bitcoin investing, Stock trading) that may introduce accent colors beyond the core green/black/white palette shown here.
- Exact shadow values on phone: The
{shadows.phone}token is inferred from typical device mockup patterns; the exact blur-radius and spread may vary by 10-20% from the stated 64px blur. - Responsive typography scale: While desktop sizes are precise, the mobile breakpoints' font-size reductions (e.g., 56px → ? on 375px) are estimated based on industry patterns, not extracted from media queries.
- Third-party cookie banner styling: The cookie consent widget (OneTrust) uses vendor-specific class names and may not reflect Cash App's own design language — treat it as a third-party injection, not a canonical component.
- Animation trigger points: Scroll thresholds for
ctaSlideInand image fade-ins are JavaScript-dependent and not visible in CSS alone; implement via Intersection Observer with reasonable defaults (e.g., 20% viewport intersection). - Accessibility focus indicators: No visible focus rings or outlines on interactive elements in the screenshot; ensureWCAG 2.4.7 compliant visible focus indicators are added during implementation (recommend 2px solid
{colors.border-strong}with 2px offset).