Design System · v1.0

The Kashew
design system.

The visual language behind Kashew — a native iOS money app for young adults. Restraint over decoration, greys over color, one warm accent. Every token here maps one-to-one to SwiftUI and Figma.

SwiftUI-nativeApple HIGLight + DarkFigma Variables
01 — Foundation

The mark

The Kashew glyph is an abstract K built from two leaf-like strokes — a quiet nod to growth. It is the primary identity: confident on its own, never crowded.

Mark on neutral · on ink · on gold. App icon pairs the gold mark on the ink background (or the reverse).

Clear space & sizing

Maintain clear space equal to the width of one stroke (≈ 25% of the mark height) on all sides. Minimum sizes: 20pt in a tab bar, 17pt inline, 1024px for the App Store icon. The mark always uses continuous, not stepped, scaling.

Wordmark

The written name “Kashew” is set in Bricolage Grotesque — reserved for marketing surfaces, landing headers and the splash. It is not used for in-app UI text.

Kashew
Do
Keep the mark monochrome — ink, white or gold. Give it room. Let it sit quietly.
Don't
Recolor with gradients, add shadows, rotate, stretch, or place the gold mark on light backgrounds where it loses contrast.
02 — Color

Mostly grey, deliberately gold

Kashew is a greyscale system with a single warm accent. Greys carry structure and hierarchy; gold appears only where attention is earned — a primary action, a selected state, a positive moment. Color is never decoration.

Brand core

Kashew Gold
#FFD379 · accent
Kashew Ink
#212021 · grey-900

Neutral ramp

50
100
200
300
400
500
600
700
800
900
950

A near-neutral, faintly-warm grey scale. grey-900 is the brand ink; everything in the UI is built from these eleven steps.

Semantic tokens

Mapped to Apple's roles (systemBackground, label, separator, fill …). Always reference the semantic token in code — never the raw ramp.

Token
Light
Dark
bg/primary
#FFFFFF
#161515
bg/secondary
#F7F7F5
#212021
bg/tertiary
#EFEEEC
#2D2C2B
surface
#FFFFFF
#212021
surface/raised
#FFFFFF
#2D2C2B
label/primary
#212021
#F7F7F5
label/secondary
#61605C
#A6A5A0
label/tertiary
#A6A5A0
#6E6D68
separator
#DEDDDA
#322F2F
accent
#FFD379
#FFD379
on-accent
#212021
#212021

The gold rule

Gold is a fill, not a text color.

#FFD379 is light — it passes contrast only against the ink, not against white. Use it as a background with ink text on top (primary buttons, badges) or as an accent on dark surfaces. Never use gold for body text, links, or small icons on light backgrounds.

AAA 11.5:1Ink on Goldprimary button · correct
FAIL 1.4:1Gold on Whiteunreadable · avoid

Functional accents (used sparingly)

+ income
Positive
L #2F8F5B / D #4FBE86
! alert
Critical
L #C0473B / D #E0796D

Color is reinforcement, never the only signal — pair with an icon, sign, or label so the meaning survives color-blindness and grayscale.

03 — Typography

Two voices: words & numbers

Three typefaces, three jobs. Bricolage Grotesque speaks the brand. SF Pro carries every word in the product. A monospaced face owns the numbers, so money always lines up.

Display · brand onlyBricolage Grotesque — wordmark, marketing
Kashew
Text · all product UISF Pro (system) · Dynamic Type · –0.01em
Your spending this week is calm. Move money, split a bill, tuck a little away.
Numbers · amountsSF Mono · tabular figures · .monospacedDigit()
€ 4,820.17

Recommendation for the text font

SF Pro — it is free, ships on every device, supports Dynamic Type and accessibility sizing out of the box, and is the strongest possible HIG alignment. If you want cross-platform brand parity later (web + Android), Inter is the closest neighbour. For numbers, SF Mono is the native pick; Geist Mono or JetBrains Mono are warmer contemporary alternatives. The non-negotiable is tabular figures — see below.

Compare the candidates

Text — one face for all product UI.

SF ProRecommended · Native
Move money calmly
Your spending this week is calm. Split a bill, tuck a little away, and keep an eye on the month ahead.
AaBbGg 0123456789 €£$ & @ ?!
InterAlternative · Webfont
Move money calmly
Your spending this week is calm. Split a bill, tuck a little away, and keep an eye on the month ahead.
AaBbGg 0123456789 €£$ & @ ?!

Numbers — one face for monetary figures (all three support tabular figures).

SF MonoNative
€ 4,820.17
0123456789
+ 2,400.00   − 42.18
Geist MonoWebfont
€ 4,820.17
0123456789
+ 2,400.00   − 42.18
JetBrains MonoWebfont
€ 4,820.17
0123456789
+ 2,400.00   − 42.18

SF Pro and SF Mono are Apple system fonts — they render true on Apple hardware and fall back to a system face elsewhere. Inter, Geist Mono and JetBrains Mono are loaded as webfonts, so they look identical on every device.

Why a separate number font

Proportional — digits drift ✗
Groceries1,118.40
Rent980.00
Transfer11,341.11
Tabular — digits align ✓
Groceries1,118.40
Rent980.00
Transfer11,341.11

Tabular figures keep decimal points in a column and stop balances from “jumping” when they animate. In SwiftUI: .monospacedDigit() or Font.system(.title, design: .monospaced).

Type scale → SwiftUI text styles

Large Title · 34 / 41 · BoldMove money calmly.font(.largeTitle)
Title 1 · 28 / 34Move money calmly.font(.title)
Title 2 · 22 / 28Move money calmly.font(.title2)
Title 3 · 20 / 25Move money calmly.font(.title3)
Headline · 17 / 22 · SemiboldMove money calmly.font(.headline)
Body · 17 / 22Move money calmly.font(.body)
Callout · 16 / 21Move money calmly.font(.callout)
Subheadline · 15 / 20Move money calmly.font(.subheadline)
Footnote · 13 / 18Move money calmly.font(.footnote)
Caption 1 · 12 / 16Move money calmly.font(.caption)
Caption 2 · 11 / 13Move money calmly.font(.caption2)

Sizes follow Apple's default Dynamic Type (Large). Always use the named text style so the app respects the user's accessibility size — avoid hard-coded point sizes for text.

04 — Layout & form

Space, radius, depth

An 8-point grid with 4-point half-steps. Generous margins. Soft, continuous corners. Depth comes from layered surfaces and materials — not heavy shadows.

Spacing scale (4 / 8 grid)

x1 · 4
x2 · 8
x3 · 12
x4 · 16
x5 · 20
x6 · 24
x8 · 32
x10 · 40
x12 · 48
x16 · 64

Default screen margin: 16pt (compact) / 20pt. Content row height ≥ 44pt for tap targets.

Corner radius — continuous

xs · 8px

sm · 10px

md · 12px

lg · 16px

xl · 20px

2xl · 28px

pill · 40px

Always the iOS “squircle”: RoundedRectangle(cornerRadius: 16, style: .continuous).

Elevation & materials

flat — fill / border

elevation-1 — cards

elevation-2 — sheets

Prefer .regularMaterial / .thinMaterial for tab bars, sheets and overlays. In dark mode, lift surfaces with lighter greys rather than shadow.

05 — Iconography

SF Symbols, weight-matched

Use SF Symbols throughout — they scale with text, support Dynamic Type, and offer hierarchical rendering. Match symbol weight to adjacent text. Tint with the label color; reserve gold for the active or selected symbol only.

Recents
Cards
Insights
Add
Home
Profile
Rewards
Transfer
Primary · default
Secondary · inactive
Active · gold

Illustrative glyphs shown — in-app, use the real SF Symbols set at scale .medium, weight .regular/.semibold.

06 — Components

The system, assembled

Tokens become UI. Every element is built only from the colors, type, spacing and radii defined above — here is a taste of the full library.

ButtonsButtonStyle
Account cardelevation-2
Total balance
€ 4,820.17
•••• 4291
Browse the full component library
07 — Tokens in practice

One source of truth

Token names are identical across Figma Variables and SwiftUI, so a value defined once reads the same in both worlds. Define colors in an Asset Catalog with Light/Dark appearances and reference them semantically.

SwiftUI — colors & theme

// Colors live in an Asset Catalog with Any/Dark appearances,
// named to match the design tokens exactly.
extension Color {
    static let bgPrimary     = Color("bg/primary")
    static let bgSecondary   = Color("bg/secondary")
    static let surface       = Color("surface")
    static let labelPrimary  = Color("label/primary")
    static let labelSecondary = Color("label/secondary")
    static let separator     = Color("separator")
    static let accent        = Color("accent")        // #FFD379
    static let onAccent      = Color("on-accent")     // #212021 ink
}

SwiftUI — type & numbers

extension Font {
    // Text uses the system face → free Dynamic Type
    static let bodyText = Font.system(.body)
    static let headline = Font.system(.headline)

    // Money: monospaced design + tabular digits
    static func amount(_ style: Font.TextStyle = .title) -> Font {
        .system(style, design: .monospaced).monospacedDigit()
    }
}

Text("€ 4,820.17")
    .font(.amount(.largeTitle))
    .foregroundStyle(.labelPrimary)

SwiftUI — spacing & radius

enum Space { static let x1=4.0, x2=8.0, x3=12.0, x4=16.0, x6=24.0, x8=32.0 }
enum Radius { static let sm=10.0, md=12.0, lg=16.0, xl=20.0 }

RoundedRectangle(cornerRadius: Radius.lg, style: .continuous)
    .fill(Color.surface)
    .padding(Space.x4)

Figma ↔ SwiftUI parity

Create one Figma Variable collection with two modes (Light, Dark). Name variables identically to the asset-catalog colors. Text styles mirror Apple's text styles; spacing & radius are number variables.

Figma
Token
SwiftUI
Color variable
color/accent
Color.accent
Color variable
color/label/primary
Color.labelPrimary
Text style
Body / 17·22
.font(.body)
Number variable
space/x4 = 16
Space.x4
Number variable
radius/lg = 16
Radius.lg
Effect style
elevation-1
shadow(.shadow1)