Wise
MIT
Clean, accessible financial design system with lime-green accents and Swiss typography, built for fintech products that prioritise clarity and trust
Layout StudioImport this kit into a Studio project and start editing.
CLI installRun it in any project. No account needed.
npx @layoutdesign/context install wise# layout.md — Wise.com Design System
---
## 0. Quick Reference
**Stack:** Next.js · Bootstrap + Tailwind · CSS custom properties (217 vars extracted, high confidence)
**Token source:** `extracted-css-vars` — use original names exactly as shown.
**How to apply:** Use as `var(--token-name)` in CSS, `style={{ prop: 'var(--token-name)' }}` in JSX, or `bg-[var(--token-name)]` in Tailwind.
```css
/* ── Core Colour Tokens ── */
--color-background-screen: #ffffff; /* Page background */
--color-background-neutral-solid: #edeeec; /* Section / card surface */
--color-core-contrast: #000000; /* Highest-contrast text */
--color-content-primary: #37517e; /* Body text, nav links */
--color-content-secondary: #5d7079; /* Subtext, captions */
--brand-primary-cta: rgb(159, 232, 112); /* PRIMARY button bg — lime green */
--brand-secondary-cta: rgb(22, 51, 0); /* Secondary button bg — dark green */
--color-content-positive: #008026; /* Success states */
--color-content-negative: #cf2929; /* Error states */
--color-content-warning: #9a6500; /* Warning states */
--color-border-neutral: rgba(0,0,0,0.10196);/* Default borders */
--ring-outline-color: var(--color-content-primary); /* Focus ring */
--ring-outline-width: 2px;
--ring-outline-offset: 2px;
/* ── Typography ── */
--font-family-display: "Wise Sans", "Inter", sans-serif; /* Headings */
--font-family-regular: "Inter", Helvetica, Arial, sans-serif; /* Body */
--font-weight-bold: 700;
--font-weight-semi-bold: 600;
--font-weight-medium: 500;
--font-weight-regular: 400;
/* ── Radius ── */
--radius-full: 9999px; /* Primary buttons — PILL shape */
--radius-large: 24px; /* Cards */
--radius-medium: 16px; /* Tags, chips */
--radius-small: 10px; /* Top-only radius on media (10px 10px 0 0) */
/* ── Motion ── */
--duration-fast: 0.15s;
--duration-base: 0.3s;
--duration-slow: 0.35s;
--navigation-transition-timing-function: cubic-bezier(0.8, 0.05, 0.2, 0.95);
```
```tsx
// Primary CTA Button — production-ready
function PrimaryButton({ children, disabled }: { children: React.ReactNode; disabled?: boolean }) {
return (
<button
disabled={disabled}
style={{
fontFamily: 'var(--font-family-regular)', fontSize: '20px', fontWeight: 600,
lineHeight: '32px', letterSpacing: '-0.22px',
color: 'var(--brand-secondary-cta)', backgroundColor: 'var(--brand-primary-cta)',
border: '1px solid var(--brand-primary-cta)', borderRadius: 'var(--radius-full)',
padding: '19px 24px', cursor: disabled ? 'not-allowed' : 'pointer',
opacity: disabled ? 0.45 : 1, filter: disabled ? 'grayscale(1)' : 'none',
transition: 'background-color var(--duration-fast) ease, color var(--duration-fast) ease',
}}
>
{children}
</button>
);
}
```
**NEVER rules:**
1. **NEVER** use a square or rounded-rect border-radius on the primary CTA — it is always `--radius-full` (9999px pill).
2. **NEVER** use white or blue as button text on the primary CTA — text colour is `--brand-secondary-cta` (dark green, `rgb(22,51,0)`).
3. **NEVER** use `Inter` for hero/display headings — use `"Wise Sans"` with Inter as fallback.
4. **NEVER** hardcode hex colours — always use the CSS custom property.
5. **NEVER** omit `:focus-visible` outline — use `--ring-outline-color`, `--ring-outline-width`, `--ring-outline-offset`.
6. **NEVER** use spacing values not derived from the `--size-*`, `--space-*`, or `--padding-*` scale.
7. **NEVER** apply `--radius-sm` (the `10px 10px 0 0` shorthand) as a full border-radius — it is top-only, for media within cards.
**Full design system → see layout.md**
<!-- Quick Reference truncated to fit the 75-line cap. See later sections for the full design system. -->
## 1. Design Direction & Philosophy
### Character & Mood
Wise presents as **trustworthy, modern, and transparent** — a fintech that has earned global credibility. The aesthetic is clean and light, with generous whitespace, confident typography, and a signature lime-green CTA that signals approachability rather than corporate stiffness. The dark-green body colour (`rgb(22,51,0)`) on lime creates a high-contrast, nature-adjacent palette that feels fresh and premium without being cold.
### What This Design Explicitly Does
- Uses **Wise Sans** (a custom display typeface) for hero headlines — large, heavy, and geometric.
- Uses **Inter** for body copy, labels, navigation, and all UI text — neutral, readable, and trustworthy.
- Employs **pill-shaped buttons** exclusively for primary CTAs — `border-radius: 9999px`.
- Keeps surfaces light (`#ffffff`, `#edeeec`) with subtle neutral borders (`rgba(0,0,0,0.10)`).
- Applies a **warm accent system** (lime green, gold, teal) for brand identity without sacrificing legibility.
- Uses **clamp()-based fluid spacing** (`--eds-space-*`, `--mw-space-*`) for responsive rhythm.
### What This Design Explicitly Rejects
- **No dark mode overrides** in the extracted system — surfaces are always light.
- **No warm-toned backgrounds** for general surfaces — warmth is reserved for accent/warning contexts.
- **No hard borders** on cards in default state — separation is achieved by background-colour difference and subtle `rgba(0,0,0,0.10)` borders.
- **No decorative serifs** anywhere in the type system.
- **No square buttons** — pill radius is a brand rule, not a preference.
- **No saturated blue as primary action** — blue (`--color-interactive-accent: #00a2dd`) is for secondary interactive elements only.
---
## 2. Colour System
### Tier 1 — Primitives (raw values)
```css
/* Brand primitives */
--brand-primary-cta: rgb(159, 232, 112); /* Lime green — primary action */
--brand-secondary-cta: rgb(22, 51, 0); /* Dark green — secondary action bg / CTA text */
--brand-mark-1: rgb(255, 211, 0); /* Gold — brand illustration accent */
--brand-mark-3: rgb(239, 37, 59); /* Red — brand illustration accent */
--brand-mark-4: rgb(34, 29, 154); /* Indigo — brand illustration accent */
--color-core-contrast: #000000; /* Pure black — max contrast */
--color-background-screen: #ffffff; /* Pure white — page background */
```
### Tier 2 — Semantic Aliases
```css
/* ── Backgrounds ── */
--color-background-screen: #ffffff; /* App/page root background */
--color-background-elevated: #ffffff; /* Modals, popovers, elevated surfaces */
--color-background-neutral: rgba(134,167,189,0.10196); /* Subtle tinted surface (info-adjacent) */
--color-background-neutral-solid: #edeeec; /* Solid neutral surface — section bg, cards */
--color-background-accent: rgba(56,200,255,0.10196); /* Tinted accent bg — info callouts */
--color-background-positive: rgba(54,199,151,0.10196); /* Tinted positive bg — success banners */
--color-background-negative: rgba(255,135,135,0.10196); /* Tinted negative bg — error banners */
--color-background-warning: rgba(255,172,0,0.10196); /* Tinted warning bg — warning banners */
--color-background-overlay: rgba(0,0,0,0.10196); /* Scrim / dimmer overlay */
--color-background-celebration: #ecf9f9; /* Special/celebratory surface */
/* ── Content (text, icons) ── */
--color-content-primary: #37517e; /* Primary body text, nav items, default text */
--color-content-secondary: #5d7079; /* Secondary text, placeholders, meta */
--color-content-tertiary: #768e9c; /* Tertiary text, disabled labels */
--color-content-accent: #0097c7; /* Accent text links */
--color-content-accent-hover: #0084b3; /* Accent text links — hover */
--color-content-accent-active: #0077a5; /* Accent text links — active/selected bg */
--color-content-positive: #008026; /* Success text/icons */
--color-content-positive-hover: #006d13; /* Success text — hover */
--color-content-positive-active: #006002; /* Success text — active */
--color-content-negative: #cf2929; /* Error text/icons */
--color-content-negative-hover: #b80419; /* Error text — hover */
--color-content-negative-active: #a7000d; /* Error text — active */
--color-content-warning: #9a6500; /* Warning text/icons */
--color-content-warning-hover: #855400; /* Warning text — hover */
--color-content-warning-active: #764700; /* Warning text — active */
--color-content-celebration: #0b4c72; /* Celebratory/special text */
/* ── Interactive (buttons, controls) ── */
--color-interactive-accent: #00a2dd; /* Secondary interactive bg */
--color-interactive-accent-hover: #008fc9; /* Secondary interactive bg — hover */
--color-interactive-accent-active: #0081ba; /* Secondary interactive bg — active */
--color-interactive-positive: #2ead4b; /* Positive action bg */
--color-interactive-positive-hover: #069939; /* Positive action bg — hover */
--color-interactive-positive-active: #008b2b; /* Positive action bg — active */
--color-interactive-negative: #e74848; /* Destructive action bg */
--color-interactive-negative-hover: #d03238; /* Destructive action bg — hover */
--color-interactive-negative-active: #bf1e2c; /* Destructive action bg — active */
--color-interactive-warning: #df8700; /* Warning action bg */
--color-interactive-warning-hover: #c97500; /* Warning action bg — hover */
--color-interactive-warning-active: #b86700; /* Warning action bg — active */
--color-interactive-secondary: #c9cbce; /* Secondary/ghost control bg */
--color-interactive-secondary-hover: #b5b7ba; /* Secondary control bg — hover */
--color-interactive-secondary-active: #a7a9ab; /* Secondary control bg — active */
/* ── Borders ── */
--color-border-neutral: rgba(0,0,0,0.10196); /* Default border on cards, inputs */
--color-border-overlay: rgba(0,0,0,0.10196); /* Overlay/modal border */
/* ── Focus ── */
--ring-outline-color: var(--color-content-primary); /* Focus ring colour (resolves to #37517e) */
--ring-outline-width: 2px; /* Focus ring width */
--ring-outline-offset: 2px; /* Focus ring offset */
/* ── Navigation-specific ── */
--navigation-color-background-interactive-hover: rgba(211,242,192,0.4); /* Nav hover bg — lime wash */
--navigation-box-shadow: 0px 4px 16px rgba(0,0,0,0.16); /* Nav bar shadow */
```
### Tier 3 — Component Tokens (where they diverge from semantic)
```css
/* Primary CTA button */
--btn-bg-primary: var(--brand-primary-cta); /* rgb(159, 232, 112) */
--btn-text-primary: var(--brand-secondary-cta); /* rgb(22, 51, 0) */
--btn-border-primary: var(--brand-primary-cta);
/* Disabled state (applied globally) */
--disabled-filter: grayscale(1);
--disabled-opacity: 0.45;
```
### Brand / Decorative Accent Palette
| Token | Value | Usage |
|---|---|---|
| `--brand-primary-cta` | `rgb(159, 232, 112)` | Primary CTA background (17+ buttons) |
| `--brand-secondary-cta` | `rgb(22, 51, 0)` | Secondary CTA bg / CTA text colour |
| `--brand-mark-1` | `rgb(255, 211, 0)` | Gold — illustration/icon fills |
| `--brand-mark-3` | `rgb(239, 37, 59)` | Red — illustration/icon fills |
| `--brand-mark-4` | `rgb(34, 29, 154)` | Indigo — illustration/icon fills |
| `--coin-colour` | `#1c3108` | Coin animation fill |
---
## 3. Typography System
### Font Stacks
```css
--font-family-display: "Wise Sans", "Inter", sans-serif;
/* Usage: h1, h2 (hero/marketing), prominent numerics */
--font-family-regular: "Inter", Helvetica, Arial, sans-serif;
/* Usage: body, labels, nav, buttons, inputs, captions */
```
**Note:** "Averta" is loaded as a web font but is a legacy font (Bootstrap-era). Prefer `--font-family-regular` (Inter) for all new UI. "Wise Sans" is display-only.
### Composite Typography Scale
```css
/* ── Display / Hero ── */
/* h1: Wise Sans, heavy, ultra-large hero heading */
.type-display-hero {
font-family: var(--font-family-display); /* "Wise Sans", Inter */
font-size: 105.428px; /* Computed from h1 — fluid via clamp at implementation */
font-weight: var(--font-weight-black); /* 900 */
line-height: 0.85; /* 89.6 / 105.4 — tight display leading */
letter-spacing: normal;
color: var(--color-core-contrast); /* #000000 */
}
/* ── Display / Section Heading ── */
/* h2: Inter semi-bold, large section titles */
.type-display-section {
font-family: var(--font-family-regular); /* Inter */
font-size: var(--font-size-3xl); /* 45.4572px / ~2.84rem fluid */
font-weight: var(--font-weight-semi-bold); /* 600 */
line-height: 57px; /* ~1.25 ratio */
letter-spacing: -0.03em; /* Approx --letter-spacing-negative-xxl */
color: rgb(22, 51, 0); /* Computed brand dark green on hero bg */
}
/* ── Display / Subsection Heading ── */
/* h3: Wise Sans regular, accented green */
.type-display-sub {
font-family: var(--font-family-display); /* "Wise Sans", Inter */
font-size: 40px; /* Computed h3 */
font-weight: var(--font-weight-regular); /* 400 */
line-height: 34px; /* 0.85 — tight */
letter-spacing: normal;
color: var(--brand-primary-cta); /* rgb(159, 232, 112) — accent heading */
}
/* ── Body / Lead ── */
/* Navigation / prominent body text */
.type-body-lead {
font-family: var(--font-family-regular);
font-size: var(--font-size-18); /* 1.125rem = 18px */
font-weight: var(--font-weight-semi-bold); /* 600 */
line-height: 26px; /* ~1.44 */
letter-spacing: var(--letter-spacing-negative-xs); /* -0.01em */
color: var(--color-content-primary);
}
/* ── Body / Default ── */
/* Standard paragraph text */
.type-body-default {
font-family: var(--font-family-regular);
font-size: var(--font-size-16); /* 1rem = 16px */
font-weight: var(--font-weight-semi-bold); /* 600 — Wise uses semi-bold body */
line-height: var(--line-height-24); /* 1.5rem = 24px */
letter-spacing: var(--letter-spacing-negative-xs); /* -0.01em */
color: rgb(22, 51, 0);
}
/* ── Body / Small ── */
/* Captions, metadata, secondary info */
.type-body-small {
font-family: var(--font-family-regular);
font-size: var(--font-size-14); /* 0.875rem = 14px */
font-weight: var(--font-weight-medium); /* 500 */
line-height: var(--line-height-22); /* 1.375rem ≈ 21px */
letter-spacing: var(--letter-spacing-negative-xxs); /* -0.005em */
color: var(--color-content-secondary);
}
/* ── Label ── */
/* Form labels, chip text */
.type-label {
font-family: var(--font-family-regular);
font-size: var(--font-size-14); /* 0.875rem */
font-weight: var(--font-weight-semi-bold); /* 600 */
line-height: 21.7px; /* --line-height-tight */
letter-spacing: var(--letter-spacing-negative-xxs); /* -0.005em (-0.084px at 14px) */
color: var(--color-core-contrast);
}
/* ── Button ── */
/* Primary/secondary button label */
.type-button {
font-family: var(--font-family-regular);
font-size: var(--font-size-20); /* 1.25rem = 20px */
font-weight: var(--font-weight-semi-bold); /* 600 */
line-height: 32px;
letter-spacing: -0.22px; /* ~--letter-spacing-negative-xxs at 20px */
text-transform: none;
}
/* ── Caption / XS ── */
.type-caption {
font-family: var(--font-family-regular);
font-size: var(--font-size-12); /* 0.75rem = 12px */
font-weight: var(--font-weight-regular); /* 400 */
line-height: var(--line-height-18); /* 1.125rem */
letter-spacing: var(--letter-spacing-xs); /* 0.01em */
color: var(--color-content-tertiary);
}
```
### Font Weight Scale
| Token | Value | Usage |
|---|---|---|
| `--font-weight-light` | 300 | Rarely used; decorative only |
| `--font-weight-regular` | 400 | H3 display, body alt, dropdown options |
| `--font-weight-medium` | 500 | Small body, badges, metadata |
| `--font-weight-semi-bold` | 600 | **Default body weight**, H2, buttons, labels, nav |
| `--font-weight-bold` | 700 | Emphasis within copy |
| `--font-weight-black` | 900 | H1 hero only |
### Letter Spacing Scale
```css
/* Positive (expanded) */
--letter-spacing-xxs: 0.005em;
--letter-spacing-xs: 0.01em;
--letter-spacing-sm: 0.0125em;
--letter-spacing-md: 0.015em;
--letter-spacing-lg: 0.02em;
--letter-spacing-xl: 0.025em;
/* Negative (condensed — preferred for large type) */
--letter-spacing-negative-xxs: -0.005em;
--letter-spacing-negative-xs: -0.01em;
--letter-spacing-negative-sm: -0.0125em;
--letter-spacing-negative-md: -0.015em;
--letter-spacing-negative-lg: -0.02em;
--letter-spacing-negative-xl: -0.025em;
--letter-spacing-negative-xxl: -0.03em; /* H2 sections */
--letter-spacing-negative-xxxl: -0.04em;
--letter-spacing-negative-xxxxl: -0.05em; /* Hero h1 at very large sizes */
```
---
## 4. Spacing & Layout
### Base Unit
`--base-font-size: 16px` — all rem values resolve against this.
### Fixed Spacing Scale
```css
/* Named padding tokens */
--padding-x-small: 8px; /* Dense UI — compact inputs, icon gaps */
--padding-small: 16px; /* Default horizontal content padding */
--padding-medium: 24px; /* Section internal padding */
--padding-large: 32px; /* Card padding, section gaps */
/* Named space tokens */
--space-small: 16px;
--space-medium: 32px;
--space-large: 40px;
--space-x-large: 56px;
--space-content-horizontal: 16px; /* Mobile horizontal gutter */
```
### Numeric Size Scale (Component sizing)
```css
--size-4: 4px; /* Minimum gap, hairline spacing */
--size-5: 5px;
--size-8: 8px; /* Dense internal spacing */
--size-10: 10px;
--size-12: 12px;
--size-14: 14px;
--size-16: 16px; /* Base unit */
--size-24: 24px;
--size-32: 32px;
--size-40: 40px; /* Default button height */
--size-48: 48px; /* Large button / nav item height */
--size-52: 52px;
--size-56: 56px;
--size-60: 60px;
--size-64: 64px;
--size-72: 72px;
--size-80: 80px;
--size-88: 88px;
--size-96: 96px;
--size-104: 104px;
--size-112: 112px;
--size-120: 120px;
--size-128: 128px;
--size-160: 160px;
```
### Fluid Spacing Scale (clamp-based — use for marketing/editorial sections)
```css
/* --eds-space-* and --mw-space-* are identical. Prefer --eds-space-* in new code. */
--eds-space-1: clamp(0.25rem, calc(0.23558rem + 0.0641vw), 0.3125rem); /* ~4–5px */
--eds-space-2: clamp(0.5rem, calc(0.47115rem + 0.12821vw), 0.625rem); /* ~8–10px */
--eds-space-3: clamp(0.75rem, calc(0.70673rem + 0.19231vw), 0.9375rem); /* ~12–15px */
--eds-space-4: clamp(1rem, calc(0.94231rem + 0.25641vw), 1.25rem); /* ~16–20px */
--eds-space-6: clamp(1.5rem, calc(1.41346rem + 0.38462vw), 1.875rem); /* ~24–30px */
--eds-space-8: clamp(2rem, calc(1.88462rem + 0.51282vw), 2.5rem); /* ~32–40px */
--eds-space-12: clamp(3rem, calc(2.82692rem + 0.76923vw), 3.75rem); /* ~48–60px */
--eds-space-16: clamp(4rem, calc(3.76923rem + 1.02564vw), 5rem); /* ~64–80px */
--eds-space-24: clamp(6rem, calc(5.65385rem + 1.53846vw), 7.5rem); /* ~96–120px */
--eds-space-32: clamp(8rem, calc(7.53846rem + 2.05128vw), 10rem); /* ~128–160px */
```
### Fluid Radius Scale
```css
--mw-radius-1: clamp(0.625rem, calc(0.58894rem + 0.16026vw), 0.78125rem); /* ~10–12.5px */
--mw-radius-2: clamp(1rem, calc(0.94231rem + 0.25641vw), 1.25rem); /* ~16–20px */
--mw-radius-3: clamp(1.5rem, calc(1.41346rem + 0.38462vw), 1.875rem); /* ~24–30px */
--mw-radius-4: clamp(2rem, calc(1.88462rem + 0.51282vw), 2.5rem); /* ~32–40px */
--mw-radius-6: clamp(3rem, calc(2.82692rem + 0.76923vw), 3.75rem); /* ~48–60px */
--mw-radius-full: 50%; /* Circle avatars, coin elements */
--radius-full: 9999px; /* Pill buttons, tags */
```
### Grid & Breakpoints
**Container max-width:** `--navigation-container: 1440px`
**Canonical breakpoints (from media query census — use these; ignore the rest):**
| Name | Value | Usage |
|---|---|---|
| xs | 320px | Minimum supported mobile |
| sm | 576px | Small mobile → tablet |
| md | 768px | Tablet |
| lg | 992px | Desktop |
| xl | 1200px | Wide desktop |
| 2xl | 1440px | Max content width |
**Navigation heights:**
```css
--navigation-desktop-primary-height: 76px;
--navigation-desktop-secondary-height: 58px;
--navigation-mobile-tertiary-height: 66px;
```
**Layout decisions:**
- **Flex** for component-level layout (buttons, nav items, form rows, badge rows).
- **Grid** for section-level card grids and feature columns.
- Full-width sections with max-width container centred at 1440px.
- Mobile: single column, `--space-content-horizontal: 16px` gutters.
- Tablet (768px+): 2-column grids.
- Desktop (992px+): 3–4 column grids for product cards.
---
## 5. Page Structure & Layout Patterns
> **Note:** No page screenshots provided. Section map inferred from component inventory, layout digest, and computed styles. Rows marked **(inferred)** are probable, not visually confirmed.
### 5.1 Section Map
| # | Section | Layout Type | Approx. Height | Key Elements |
|---|---|---|---|---|
| 1 | **Navigation / Header** | Flex row, fixed, `76px` (desktop) | 76px desktop / 66px mobile | Logo, primary nav links, "Log in" + primary CTA pill button |
| 2 | **Hero / Currency Converter** | Flex column (centred), full-width | ~600–800px (inferred) | H1 (105px, Wise Sans, weight 900), currency input widget (52px font), primary CTA pill (`19px 24px` padding) |
| 3 | **Trust Signals Bar** (inferred) | Flex row, contained | ~80px (inferred) | "Trusted by millions", "Regulated", "24/7 support" — H4, `--font-size-lg: 20px`, semi-bold |
| 4 | **Product Cards Grid** (inferred) | CSS Grid, 3–4 col desktop, 1 col mobile | ~400–600px (inferred) | Cards with `--radius-large: 24px`, bg `rgb(226,246,213)`, feature titles at `--font-size-xl: 24.6px` |
| 5 | **"Send money globally"** section (inferred) | 2-col flex / grid | ~500px (inferred) | H2 at `45.4572px`, body copy at `18px`, secondary CTA (`--brand-secondary-cta` bg) |
| 6 | **"Do more with Wise"** feature section (inferred) | 2-col or alternating, contained | ~600px (inferred) | Feature cards (`--radius-lg: 28.1539px`), badge components, 91+ badge instances |
| 7 | **"Move your money worldwide"** section (inferred) | 2-col, full-width with accent bg | ~500px (inferred) | H2 at `45.4572px`, region/flag imagery, CTA pill |
| 8 | **Footer** (inferred) | Multi-column grid, contained | ~300–400px (inferred) | Nav links at `18px`, small caption text at `12px`, `--color-background-neutral-solid` bg |
### 5.2 Layout Patterns
**Navigation (confirmed from computed styles):**
- `display: block` at root; inner items `display: flex; flex-direction: row`
- Desktop: `height: 76px`, `padding: 22px 0` vertical, horizontal space via `--navigation-desktop-primary-button-height: var(--size-32)`
- Nav links: `font-size: 18px`, `font-weight: 400`, `color: rgb(69,71,69)` (muted, not primary)
- Hover: `background-color: rgba(211,242,192,0.4)` — lime wash on hover
- Box shadow on scroll: `0px 4px 16px rgba(0,0,0,0.16)`
**Primary Button (confirmed):**
- `display: block; padding: 19px 24px; border-radius: 9999px`
- `font-size: 20px; font-weight: 600; line-height: 32px`
- `background-color: rgb(159,232,112); color: rgb(22,51,0); border: 1px solid rgb(159,232,112)`
**Product Cards (confirmed from radius census):**
- Outer card: `border-radius: 28.1539px` (`--radius-lg`), 2 instances on product list items
- Inner card: `border-radius: 18.7693px` (`--radius-md`), 13 instances on CTA buttons within cards
- Media/image top: `border-radius: 10px 10px 0 0` (`--radius-sm`), 3 instances
- Card bg: `rgb(226,246,213)` — pale lime green tint
**Section containers:** Max-width `1440px`, centred, `padding: 0 var(--padding-large)` (32px) desktop, `0 var(--space-content-horizontal)` (16px) mobile.
### 5.3 Visual Hierarchy
1. **Primary CTA** (`rgb(159,232,112)` pill) is the dominant action — placed in the hero and likely repeated per section. It is the single most visually distinct element.
2. **H1** at 105px / weight 900 in Wise Sans dominates the hero — everything else is subordinate to it and the converter widget.
3. **H2 sections** (`45.4572px`, Inter semi-bold, dark green) anchor marketing sections with strong typographic presence.
4. **H3 accented headings** (`40px`, Wise Sans, `rgb(159,232,112)`) create coloured section openers that signal product categories.
5. Cards use **background colour differentiation** (`rgb(226,246,213)` pale lime) rather than shadows to create depth.
6. **Whitespace is generous** — `--eds-space-8` to `--eds-space-16` between sections.
### 5.4 Content Patterns
**Repeating feature block pattern (inferred from component census):**
```
[Accent H3 in lime green]
[H2 or H4 in dark green, semi-bold]
[Body paragraph, Inter semi-bold 18px]
[Pill CTA button or secondary dark-green button]
```
**Product card pattern (confirmed from computed styles):**
```
[Card container: border-radius 28px, bg rgb(226,246,213)]
[Media: border-radius 10px 10px 0 0]
[Card body: padding 16–24px]
[Badge/tag: border-radius 9999px or 16px]
[H3 at ~24.6px]
[Body text at 18px]
[CTA button: border-radius 18.77px — inner card variant]
```
**Trust badge row (inferred from badge census — 91 instances):**
```
[Flex row, gap --size-16]
[Badge: font-size 14px, font-weight 500, color rgb(11,76,114)]
[Badge: ...]
[Badge: ...]
```
---
## 6. Component Patterns
### 6.1 Primary Button
**Anatomy:** `<button>` → text label (+ optional leading icon)
**Token-to-property mapping:**
| State | `background-color` | `color` | `border` | `opacity` | `filter` |
|---|---|---|---|---|---|
| default | `rgb(159,232,112)` | `rgb(22,51,0)` | `1px solid rgb(159,232,112)` | 1 | none |
| hover | `var(--color-interactive-accent-hover)` | `white` | — | 1 | none |
| focus | unchanged | unchanged | outline `2px var(--ring-outline-color)` offset `2px` | 1 | none |
| active | `var(--color-interactive-accent-active)` | `white` | — | 1 | none |
| disabled | unchanged | unchanged | unchanged | 0.45 | `grayscale(1)` |
| loading | unchanged | unchanged | unchanged | 0.7 | none |
```tsx
import { useState } from 'react';
type ButtonVariant = 'primary' | 'secondary';
type ButtonState = 'idle' | 'loading' | 'error';
interface PrimaryButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: ButtonVariant;
state?: ButtonState;
children: React.ReactNode;
}
export function WiseButton({
variant = 'primary',
state = 'idle',
disabled,
children,
...rest
}: PrimaryButtonProps) {
const [isHovered, setIsHovered] = useState(false);
const isDisabled = disabled || state === 'loading';
const isPrimary = variant === 'primary';
const baseStyle: React.CSSProperties = {
display: 'inline-block',
fontFamily: 'var(--font-family-regular)',
fontSize: 'var(--font-size-20)',
fontWeight: 600,
lineHeight: '32px',
letterSpacing: '-0.22px',
borderRadius: 'var(--radius-full)', /* 9999px — ALWAYS pill */
padding: '19px 24px',
border: '1px solid',
cursor: isDisabled ? 'not-allowed' : 'pointer',
opacity: isDisabled ? 0.45 : 1,
filter: isDisabled ? 'grayscale(1)' : 'none',
transition: `background-color var(--duration-fast) ease, color var(--duration-fast) ease`,
textAlign: 'center',
textDecoration: 'none',
/* focus ring handled via CSS :focus-visible */
};
const primaryStyle: React.CSSProperties = {
...baseStyle,
backgroundColor: isHovered && !isDisabled
? 'var(--color-interactive-accent-hover)'
: 'var(--brand-primary-cta)',
color: isHovered && !isDisabled ? '#ffffff' : 'var(--brand-secondary-cta)',
borderColor: isHovered && !isDisabled
? 'var(--color-interactive-accent-hover)'
: 'var(--brand-primary-cta)',
};
const secondaryStyle: React.CSSProperties = {
...baseStyle,
backgroundColor: isHovered && !isDisabled
? 'var(--color-interactive-accent-hover)'
: 'var(--brand-secondary-cta)',
color: '#ffffff',
borderColor: isHovered && !isDisabled
? 'var(--color-interactive-accent-hover)'
: 'var(--brand-secondary-cta)',
};
return (
<button
{...rest}
disabled={isDisabled}
style={isPrimary ? primaryStyle : secondaryStyle}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
{state === 'loading' ? (
<span aria-label="Loading…" role="status">
<span aria-hidden="true">Loading…</span>
</span>
) : (
children
)}
</button>
);
}
/* CSS companion — add to global stylesheet */
/*
.wise-btn:focus-visible {
outline: var(--ring-outline-width) solid var(--ring-outline-color);
outline-offset: var(--ring-outline-offset);
}
*/
```
---
### 6.2 Card
**Anatomy:** Container → [optional media (top)] → Body → [Title] → [Description] → [CTA button]
| State | `background-color` | `border-radius` | `box-shadow` |
|---|---|---|---|
| default | `rgb(226,246,213)` | `var(--radius-large)` 28px | none |
| hover | `var(--color-background-elevated)` | `var(--radius-large)` 28px | `var(--navigation-box-shadow)` |
| focus-within | unchanged | unchanged | outline on inner focusable |
| disabled | — | — | `filter: grayscale(1); opacity: 0.45` |
```tsx
interface WiseCardProps {
title: string;
description: string;
media?: React.ReactNode;
cta?: string;
href?: string;
disabled?: boolean;
}
export function WiseCard({ title, description, media, cta, href, disabled }: WiseCardProps) {
return (
<div
style={{
backgroundColor: 'rgb(226,246,213)',
borderRadius: 'var(--radius-large)', /* 28.1539px */
overflow: 'hidden',
opacity: disabled ? 0.45 : 1,
filter: disabled ? 'grayscale(1)' : 'none',
transition: `box-shadow var(--duration-base) ease`,
}}
>
{media && (
<div style={{ borderRadius: '10px 10px 0 0', overflow: 'hidden' }}>
{media}
</div>
)}
<div style={{ padding: 'var(--padding-medium)' /* 24px */ }}>
<h3
style={{
fontFamily: 'var(--font-family-display)',
fontSize: 'var(--font-size-3xl)', /* 45.4572px for section card titles */
fontWeight: 'var(--font-weight-regular)',
lineHeight: '1.2',
marginBottom: 'var(--size-16)',
}}
>
{title}
</h3>
<p
style={{
fontFamily: 'var(--font-family-regular)',
fontSize: 'var(--font-size-18)',
fontWeight: 600,
lineHeight: '26px',
color: 'var(--color-content-primary)',
marginBottom: 'var(--size-24)',
}}
>
{description}
</p>
{cta && (
<a
href={href}
style={{
display: 'inline-block',
fontFamily: 'var(--font-family-regular)',
fontSize: 'var(--font-size-18)',
fontWeight: 600,
borderRadius: '18.7693px', /* Inner card button radius — NOT radius-full */
padding: '12px 24px',
backgroundColor: 'var(--brand-primary-cta)',
color: 'var(--brand-secondary-cta)',
border: '1px solid var(--brand-primary-cta)',
textDecoration: 'none',
}}
>
{cta}
</a>
)}
</div>
</div>
);
}
```
---
### 6.3 Input (Currency / Form)
**Anatomy:** `<label>` (flex column) → `<input>` → optional helper/error text
| State | `border` / `box-shadow` | `color` | Notes |
|---|---|---|---|
| default | `--shadow-sm` (`rgb(134,134,133) 0 0 0 1px inset`) | `rgb(22,51,0)` | — |
| hover | `1px solid var(--color-content-primary)` | — | Slightly stronger border |
| focus | outline `var(--ring-outline-color)` 2px / 2px offset | — | Standard ring |
| error | `1px solid var(--color-content-negative)` | `--color-content-negative` on helper | `#cf2929` |
| disabled | `filter: grayscale(1); opacity: 0.45` | — | `cursor: not-allowed` |
```tsx
interface WiseInputProps {
label: string;
value: string;
onChange: (v: string) => void;
error?: string;
disabled?: boolean;
placeholder?: string;
}
export function WiseInput({ label, value, onChange, error, disabled, placeholder }: WiseInputProps) {
return (
<label
style={{
display: 'flex',
flexDirection: 'column',
fontFamily: 'var(--font-family-regular)',
fontSize: 'var(--font-size-14)',
fontWeight: 600,
lineHeight: '21.7px',
color: 'var(--color-core-contrast)',
gap: 'var(--size-8)',
opacity: disabled ? 0.45 : 1,
filter: disabled ? 'grayscale(1)' : 'none',
}}
>
{label}
<input
value={value}
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
placeholder={placeholder}
style={{
fontFamily: 'var(--font-family-display)', /* Wise Sans for currency input */
fontSize: '52px',
fontWeight: 'var(--font-weight-regular)',
lineHeight: '78px',
color: 'rgb(22,51,0)',
backgroundColor: 'transparent',
border: 'none',
boxShadow: error
? `0 0 0 1px var(--color-content-negative) inset`
: 'rgb(134,134,133) 0px 0px 0px 1px inset', /* --shadow-sm */
padding: 'var(--input-padding)', /* 12px 16px */
borderRadius: 'var(--radius-medium)', /* 16px */
textAlign: 'right',
cursor: disabled ? 'not-allowed' : 'text',
outline: 'none',
width: '100%',
}}
/>
{error && (
<span
role="alert"
style={{
fontSize: 'var(--font-size-14)',
fontWeight: 'var(--font-weight-regular)',
color: 'var(--color-content-negative)',
lineHeight: '21px',
}}
>
{error}
</span>
)}
</label>
);
}
```
---
### 6.4 Navigation Item
**Anatomy:** `<nav>` → `<a>` or `<button>` → text label [+ chevron for dropdown]
| State | `color` | `background-color` |
|---|---|---|
| default | `rgb(69,71,69)` | transparent |
| hover | unchanged | `rgba(211,242,192,0.4)` (`--navigation-color-background-interactive-hover`) |
| focus-visible | unchanged | unchanged + focus ring |
| active/current | `var(--color-content-accent-active)` (`#0077a5`) | transparent |
| disabled | `var(--color-content-tertiary)` | transparent |
```tsx
interface NavItemProps {
label: string;
href: string;
isActive?: boolean;
disabled?: boolean;
}
export function NavItem({ label, href, isActive, disabled }: NavItemProps) {
const [hovered, setHovered] = useState(false);
return (
<a
href={disabled ? undefined : href}
aria-current={isActive ? 'page' : undefined}
aria-disabled={disabled}
onMouseEnter={() => !disabled && setHovered(true)}
onMouseLeave={() => setHovered(false)}
style={{
fontFamily: 'var(--font-family-regular)',
fontSize: 'var(--font-size-18)',
fontWeight: 'var(--font-weight-regular)', /* 400 */
lineHeight: '26px',
letterSpacing: '-0.108px',
color: isActive
? 'var(--color-content-accent-active)'
: disabled
? 'var(--color-content-tertiary)'
: 'rgb(69,71,69)',
backgroundColor: hovered && !disabled
? 'var(--navigation-color-background-interactive-hover)'
: 'transparent',
padding: '8px 12px',
borderRadius: 'var(--radius-medium)', /* 16px — rounded nav items */
textDecoration: 'none',
cursor: disabled ? 'not-allowed' : 'pointer',
transition: `background-color var(--duration-fast) ease`,
display: 'block',
}}
>
{label}
</a>
);
}
```
---
### 6.5 Badge / Tag
**Anatomy:** `<span>` → text (+ optional leading icon)
| State | `color` | `background-color` | Notes |
|---|---|---|---|
| default | `rgb(11,76,114)` | transparent | From computed `badge` element |
| hover (link badge) | none text-decoration | `cursor: pointer` | `text-decoration: none` |
| disabled | `var(--color-content-tertiary)` | — | — |
```tsx
interface BadgeProps {
children: React.ReactNode;
variant?: 'neutral' | 'positive' | 'negative' | 'warning' | 'accent';
href?: string;
}
const badgeColours = {
neutral: { color: 'rgb(11,76,114)', bg: 'rgba(56,200,255,0.10196)' },
positive: { color: 'var(--color-content-positive)', bg: 'var(--color-background-positive)' },
negative: { color: 'var(--color-content-negative)', bg: 'var(--color-background-negative)' },
warning: { color: 'var(--color-content-warning)', bg: 'var(--color-background-warning)' },
accent: { color: 'var(--color-content-accent)', bg: 'var(--color-background-accent)' },
};
export function WiseBadge({ children, variant = 'neutral', href }: BadgeProps) {
const Tag = href ? 'a' : 'span';
const colours = badgeColours[variant];
return (
<Tag
href={href}
style={{
display: 'inline-block',
fontFamily: 'var(--font-family-regular)',
fontSize: 'var(--font-size-14)',
fontWeight: 'var(--font-weight-medium)', /* 500 */
lineHeight: '21px',
letterSpacing: '-0.108px',
color: colours.color,
backgroundColor: colours.bg,
borderRadius: 'var(--radius-medium)', /* 16px */
padding: '4px 12px',
textDecoration: 'none',
cursor: href ? 'pointer' : 'default',
whiteSpace: 'nowrap',
}}
>
{children}
</Tag>
);
}
```
---
## 7. Elevation & Depth
```css
/* ── Shadow Tokens ── */
--shadow-sm: rgb(134, 134, 133) 0px 0px 0px 1px inset;
/* Inset ring — used on inputs, form controls to simulate border with box-shadow */
--navigation-box-shadow: 0px 4px 16px rgba(0,0,0,0.16);
/* Navigation bar ambient shadow — appears on scroll or when nav is fixed */
/* ── Border Tokens ── */
--color-border-neutral: rgba(0,0,0,0.10196);
/* Standard card/panel borders — very subtle */
--color-border-overlay: rgba(0,0,0,0.10196);
/* Modal/popover borders */
```
### Z-Index Scale
```css
/* Navigation z-index ladder (extracted) */
--navigation-desktop-secondary-zindex: 990; /* Secondary nav bar */
--navigation-desktop-secondary-dropdown-zindex: 1000; /* Secondary dropdowns */
--navigation-desktop-dimmer-zindex: 1040; /* Backdrop dimmer */
--navigation-desktop-primary-zindex: 1050; /* Primary nav bar */
--navigation-mobile-primary-zindex: 1049; /* Mobile nav primary */
--navigation-mobile-secondary-zindex: 1047; /* Mobile nav secondary */
--navigation-mobile-secondary-dropdown-zindex: 1049; /* Mobile secondary dropdown */
--navigation-desktop-viewport-zindex: 1060; /* Dropdown viewport */
--navigation-desktop-primary-panel-zindex: 1070; /* Mega-menu panel */
--navigation-skiplink-zindex: 1080; /* Skip-to-content link */
```
### Layering Principles
- **No box-shadows on cards** in default state — separation uses `background-color` difference between `#ffffff` surface and `rgb(226,246,213)` / `#edeeec` card bg.
- **Navigation shadow** appears contextually (on scroll / when nav has a panel open).
- **Inputs use inset `box-shadow`** (`--shadow-sm`) rather than `border` to maintain consistent height across form rows.
- **Overlays/modals** use `rgba(0,0,0,0.10196)` backdrop — not a dark/opaque scrim.
---
## 8. Motion
```css
/* ── Duration Tokens ── */
--duration-fast: 0.15s; /* Buttons, badge state changes, label colour transitions */
--duration-base: 0.3s; /* Card hover shadows, colour-changing containers */
--duration-slow: 0.35s; /* Page-level transitions, body/background-color, nav animations */
/* ── Easing Tokens ── */
--ease-default: ease;
/* General-purpose — used on 238 elements */
--navigation-transition-timing-function: cubic-bezier(0.8, 0.05, 0.2, 0.95);
/* Navigation only — fast-out, slow-in: panels slide in decisively */
/* ── Navigation Animation Durations ── */
--navigation-animation-duration: 350ms; /* Primary panel transitions */
--navigation-animation-duration-short: 200ms; /* Quick reveals */
--navigation-animation-duration-long: 600ms; /* Full-page slide transitions */
```
### Named Animation Patterns
| Name | Behaviour | Usage |
|---|---|---|
| `MwFadeIn` / `MwFadeOut` | `opacity 0→1 / 1→0` | Section reveals, content fade |
| `MwTranslateTop` | `translateY(24px)→0, opacity 0→1` | Dropdown panels, toast notifications |
| `Animations_move-up` | `translateY(8px)→0, opacity 0→1` | Card/item entrance within lists |
| `Animations_shimmer` | `background-position-x` sweep | Loading skeleton shimmer |
| `NavigationDesktop_enterFromRight` | `translateX(-10px)→0, opacity 0→1` | Nav panel enter |
| `NavigationDesktop_exitToLeft` | `translateX(0)→10px, opacity 1→0` | Nav panel exit |
| `slideDown` / `slideUp` | `height 0 ↔ radix-accordion-content-height` | Accordion expand/collapse |
| `droppable-fade-in` | `opacity 0→1` | Drag-and-drop target reveal |
| `loaderStroke` / `loaderFill` | Circular progress draw + fill | Button loading spinner |
### Motion Rules
- **Always animate `color` and `background-color`** on interactive elements — use `var(--duration-fast) ease` or `var(--duration-slow) cubic-bezier(0.8,0.05,0.2,0.95)`.
- **Never animate `height` directly** — use `radix-accordion-content-height` via CSS custom property or `max-height` with sufficient overshoot.
- **Respect `prefers-reduced-motion`** — Wise ships a `swap-currencies-reduced-motion` keyframe variant; implement reduced-motion alternatives for all spinning/translating animations.
- **Navigation transitions use the custom cubic-bezier**, not `ease` — this is a brand motion signature.
---
## 9. Anti-Patterns & Constraints
1. **NEVER use a non-pill border-radius on the primary CTA button.**
→ *Why it fails:* AI agents default to `border-radius: 8px` or `--radius-md` for "rounded buttons". Wise's primary button is `border-radius: 9999px`. Any other value breaks brand identity and looks incorrect in context.
→ *What to do instead:* Always set `border-radius: var(--radius-full)` (9999px) for primary CTAs. Reserve `18.7693px` (computed `--radius-md`) for secondary/internal card buttons only.
2. **NEVER use `Inter` as the display/hero typeface.**
→ *Why it fails:* AI agents trained on generic Tailwind/Bootstrap UIs default to Inter for all text. Wise uses `"Wise Sans"` (a proprietary font, weight 900) for hero H1s and accent H3s. Falling back to Inter at 900 weight produces a visually incorrect hierarchy.
→ *What to do instead:* Always set `font-family: var(--font-family-display)` for H1 and accent H3 elements. Verify `"Wise Sans"` is loaded before rendering hero text.
3. **NEVER hardcode hex colours like `#9fe870` or `rgb(159,232,112)` directly in component styles.**
→ *Why it fails:* AI agents sometimes inline computed colour values directly, bypassing the token system. This breaks future theming and makes near-duplicate colour bugs invisible.
→ *What to do instead:* Always use `var(--brand-primary-cta)` for the CTA green, `var(--brand-secondary-cta)` for the dark-green text/bg. Reference the token, never the literal value.
4. **NEVER use `color: white` or `color: #ffffff` on the primary CTA button text.**
→ *Why it fails:* The lime-green CTA background (`rgb(159,232,112)`) has insufficient contrast with white text. The computed style explicitly uses `rgb(22,51,0)` (dark green) as the text colour — this is both a brand and accessibility requirement.
→ *What to do instead:* Always apply `color: var(--brand-secondary-cta)` (`rgb(22,51,0)`) to text inside the primary CTA. White text only appears on hover state when background shifts to `--color-interactive-accent-hover`.
5. **NEVER omit `:focus-visible` styling on interactive elements.**
→ *Why it fails:* AI agents often generate `outline: none` or omit focus styles entirely to "clean up" visual noise. Wise's design system includes `--ring-outline-color`, `--ring-outline-width: 2px`, and `--ring-outline-offset: 2px` as first-class tokens — removing them breaks accessibility and violates the system.
→ *What to do instead:* Add `outline: var(--ring-outline-width) solid var(--ring-outline-color); outline-offset: var(--ring-outline-offset);` to every `:focus-visible` rule.
6. **NEVER construct disabled states by only setting `opacity: 0.5`.**
→ *Why it fails:* Wise's extracted CSS rule for `.disabled, :disabled` applies both `opacity: 0.45` AND `filter: grayscale(1)`. Using opacity alone produces a coloured-but-dim state that looks unfinished, especially on the lime-green CTA.
→ *What to do instead:* Always apply both `opacity: 0.45` and `filter: grayscale(1)` together, plus `cursor: not-allowed`.
7. **NEVER use spacing values not on the extracted scale (e.g. `margin: 22px`, `gap: 15px`).**
→ *Why it fails:* The system has 8 off-grid values in its extraction. AI agents introduce further drift by defaulting to "nice" round numbers. This breaks the fluid spacing rhythm driven by `--eds-space-*` clamp tokens.
→ *What to do instead:* Map to the nearest `--size-*`, `--space-*`, or `--eds-space-*` token. When in doubt, use `--size-16` (16px) as the base unit.
8. **NEVER use `--radius-sm` (`10px 10px 0px 0px`) as a full border-radius.**
→ *Why it fails:* `--wise-radius-sm` is a shorthand for a **top-only** corner radius applied to media elements at the top of cards. AI agents may mistakenly apply it as a symmetrical 10px radius to buttons or chips, creating an off-brand appearance.
→ *What to do instead:* Use `--radius-small: 10px` (the scalar token) if you need a symmetric 10px radius. Use the `10px 10px 0 0` value only for top-of-card media.
9. **NEVER use dynamically constructed Tailwind class names (e.g. `` `bg-[${color}]` ``).**
→ *Why it fails:* Tailwind's JIT compiler cannot detect dynamic class names at build time, so the generated CSS is never included in the bundle. The component renders with no background.
→ *What to do instead:* Use `style={{ backgroundColor: 'var(--brand-primary-cta)' }}` for dynamic token application, or define a complete set of static Tailwind classes in a `variants` map.
10. **NEVER use `position: absolute` to horizontally or vertically centre layout content.**
→ *Why it fails:* The Wise layout is entirely flex/grid-based (confirmed by computed `display: flex; justify-content: center; align-items: center` on avatar and radio elements). Absolute-positioned centring breaks responsive reflow and collides with z-index stacking in the navigation system.
→ *What to do instead:* Use `display: flex; justify-content: center; align-items: center` for centring, or CSS Grid `place-items: center`.
11. **NEVER mix `--mw-space-*` and `--eds-space-*` tokens in the same component.**
→ *Why it fails:* The two scales are numerically identical but semantically different prefixes — `--eds-space-*` is the canonical design system scale, `--mw-space-*` is the marketing-web legacy alias. Mixing them makes intent unclear and creates confusion in future refactors.
→ *What to do instead:* Always use `--eds-space-*` for new component code. Reserve `--mw-space-*` only when maintaining existing marketing-web markup.
---
## 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 (59) */
--color-content-primary: #37517e;
--color-content-secondary: #5d7079;
--color-content-tertiary: #768e9c;
--color-content-accent: #0097c7;
--color-content-accent-hover: #0084b3;
--color-content-accent-active: #0077a5;
--color-content-positive: #008026;
--color-content-positive-hover: #006d13;
--color-content-positive-active: #006002;
--color-content-negative: #cf2929;
--color-content-negative-hover: #b80419;
--color-content-negative-active: #a7000d;
--color-content-warning: #9a6500;
--color-content-warning-hover: #855400;
--color-content-warning-active: #764700;
--color-interactive-accent: #00a2dd;
--color-interactive-accent-hover: #008fc9;
--color-interactive-accent-active: #0081ba;
--color-interactive-positive: #2ead4b;
--color-interactive-positive-hover: #069939;
--color-interactive-positive-active: #008b2b;
--color-interactive-negative: #e74848;
--color-interactive-negative-hover: #d03238;
--color-interactive-negative-active: #bf1e2c;
--color-interactive-warning: #df8700;
--color-interactive-warning-hover: #c97500;
--color-interactive-warning-active: #b86700;
--color-interactive-secondary: #c9cbce;
--color-interactive-secondary-hover: #b5b7ba;
--color-interactive-secondary-active: #a7a9ab;
--color-background-screen: #ffffff;
--color-background-neutral: rgba(134,167,189,0.10196);
--color-background-accent: rgba(56,200,255,0.10196);
--color-background-positive: rgba(54,199,151,0.10196);
--color-background-negative: rgba(255,135,135,0.10196);
--color-background-warning: rgba(255,172,0,0.10196);
--color-border-neutral: rgba(0,0,0,0.10196);
--color-core-contrast: #000000;
--ring-outline-color: var(--color-content-primary);
--coin-colour: #1c3108;
--color-background-neutral-solid: #edeeec;
--navigation-color-background-interactive-hover: rgba(211,242,192,0.4);
--color-background-celebration: #ecf9f9;
--color-content-celebration: #0b4c72;
--brand-primary-cta: rgb(159, 232, 112); /* Primary CTA background, dominant on 17 buttons — e.g. "Change" /* mined from computed styles */ */
--brand-secondary-cta: rgb(22, 51, 0); /* Secondary CTA background, dominant on 4 buttons — e.g. "Learn how to send money" /* mined from computed styles */ */
--brand-mark-1: rgb(255, 211, 0); /* Brand mark fill on 12 svg shapes — e.g. "path" /* mined from svg fill */ */
--brand-mark-3: rgb(239, 37, 59); /* Brand mark fill on 12 svg shapes — e.g. "path" /* mined from svg fill */ */
--brand-mark-4: rgb(34, 29, 154); /* Brand mark fill on 6 svg shapes — e.g. "path" /* mined from svg fill */ */
--brand-primary-cta: rgb(159, 232, 112);
--brand-secondary-cta: rgb(22, 51, 0);
--brand-mark-1: rgb(255, 211, 0);
--brand-mark-3: rgb(239, 37, 59);
--brand-mark-4: rgb(34, 29, 154);
--color-background-elevated: #ffffff;
--color-background-overlay: rgba(0,0,0,0.10196);
--color-border-overlay: rgba(0,0,0,0.10196);
--btn-bg-primary: var(--brand-primary-cta);
--btn-border-primary: var(--brand-primary-cta);
/* Typography (86) */
--size-4: 4px;
--size-5: 5px;
--size-8: 8px;
--size-10: 10px;
--size-12: 12px;
--size-14: 14px;
--base-font-size: 16px;
--size-x-small: 24px;
--size-small: 32px;
--size-medium: 40px;
--size-large: 48px;
--size-52: 52px;
--size-x-large: 56px;
--size-60: 60px;
--size-64: 64px;
--size-2x-large: 72px;
--size-80: 80px;
--size-88: 88px;
--size-96: 96px;
--size-104: 104px;
--size-112: 112px;
--size-120: 120px;
--size-126: 126px;
--size-128: 128px;
--size-146: 146px;
--size-154: 154px;
--size-160: 160px;
--font-size-12: 0.75rem;
--font-size-14: 0.875rem;
--font-size-16: 1rem;
--font-size-18: 1.125rem;
--font-size-20: 1.25rem;
--font-size-22: 1.375rem;
--font-size-24: 1.5rem;
--font-size-26: 1.625rem;
--font-size-28: 1.75rem;
--font-size-30: 1.875rem;
--font-size-32: 2rem;
--letter-spacing-xxs: 0.005em;
--letter-spacing-xs: 0.01em;
--letter-spacing-sm: 0.0125em;
--letter-spacing-md: 0.015em;
--letter-spacing-lg: 0.02em;
--letter-spacing-xl: 0.025em;
--letter-spacing-negative-xxs: -0.005em;
--letter-spacing-negative-xs: -0.01em;
--letter-spacing-negative-sm: -0.0125em;
--letter-spacing-negative-md: -0.015em;
--letter-spacing-negative-lg: -0.02em;
--letter-spacing-negative-xl: -0.025em;
--letter-spacing-negative-xxl: -0.03em;
--letter-spacing-negative-xxxl: -0.04em;
--letter-spacing-negative-xxxxl: -0.05em;
--line-height-34: 2.125rem;
--line-height-36: 2.25rem;
--line-height-42: 2.625rem;
--line-height-48: 3rem;
--line-height-title: 1.2;
--line-height-body: 1.5;
--font-weight-light: 300;
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semi-bold: 600;
--font-weight-bold: 700;
--font-weight-black: 900;
--font-family-display: "Wise Sans", "Inter", sans-serif;
--font-family-regular: "Inter", Helvetica, Arial, sans-serif;
--coin-size: 4.5rem;
--coins-image: url("data:image/png; <22.6KB elided>");
--navigation-box-shadow: 0px 4px 16px rgba(0,0,0,0.16);
--navigation-transition-timing-function: cubic-bezier(0.8,0.05,0.2,0.95);
--font-size-md: 18px; /* 99 elements — e.g. h2 "Products", h2 "Wise Personal", h2 "Resources" /* mined from computed styles */ */
--font-size-lg: 20px; /* 17 elements — e.g. h4 "Trusted by millions ", h4 "Regulated", h4 "24/7 customer suppor" /* mined from computed styles */ */
--font-size-xl: 24.6285px; /* 7 elements — e.g. h3 "Receive money fast", h3 "Save on spending abr", h3 "Earn returns" /* mined from computed styles */ */
--font-size-3xl: 45.4572px; /* 7 elements — e.g. h2 "Send money globally ", h2 "Do more with Wise in", h2 "Move your money worl" /* mined from computed styles */ */
--line-height-tight: 21.7px; /* 30 elements — e.g. a "Show more providers", a "How do we collect th", button "Change" /* mined from computed styles */ */
--line-height-loose: 26px; /* 107 elements — e.g. h2 "Products", h2 "Wise Personal", h2 "Resources" /* mined from computed styles */ */
--btn-text-primary: var(--brand-secondary-cta);
--line-height-control: 1.2;
--line-height-18: 1.125rem;
--line-height-20: 1.25rem;
--line-height-22: 1.375rem;
--line-height-24: 1.5rem;
--line-height-28: 1.75rem;
--line-height-30: 1.875rem;
--line-height-32: 2rem;
/* Spacing (77) */
--padding-x-small: 8px;
--padding-small: 16px;
--padding-medium: 24px;
--padding-large: 32px;
--space-large: 40px;
--space-x-large: 56px;
--input-group-addon-padding: 12px 16px calc(12px - 2px);
--btn-padding: 12px 24px calc(12px - 2px);
--btn-xs-padding: 2px 8px 0;
--btn-sm-padding: 4px 16px calc(4px - 2px);
--btn-lg-padding: 20px 24px calc(20px - 2px);
--input-padding-small: 4px 12px calc(4px - 2px);
--input-group-addon-sm-padding: calc(4px - 1px) 12px;
--dropdown-link-padding: calc(12px + 1px) 16px calc(12px - 1px);
--ring-outline-width: 2px;
--mw-space-1: clamp(0.25rem,calc(0.23558rem + 0.0641vw),0.3125rem);
--mw-space-2: clamp(0.5rem,calc(0.47115rem + 0.12821vw),0.625rem);
--mw-space-3: clamp(0.75rem,calc(0.70673rem + 0.19231vw),0.9375rem);
--mw-space-4: clamp(1rem,calc(0.94231rem + 0.25641vw),1.25rem);
--mw-space-6: clamp(1.5rem,calc(1.41346rem + 0.38462vw),1.875rem);
--mw-space-8: clamp(2rem,calc(1.88462rem + 0.51282vw),2.5rem);
--mw-space-12: clamp(3rem,calc(2.82692rem + 0.76923vw),3.75rem);
--mw-space-16: clamp(4rem,calc(3.76923rem + 1.02564vw),5rem);
--mw-space-24: clamp(6rem,calc(5.65385rem + 1.53846vw),7.5rem);
--mw-space-32: clamp(8rem,calc(7.53846rem + 2.05128vw),10rem);
--navigation-mobile-tertiary-height: 66px;
--navigation-container: 1440px;
--navigation-mobile-horizontal-space: var(--eds-space-8,var(--mw-space-8));
--navigation-mobile-dialog-margin: var(--eds-space-4,var(--mw-space-4));
--navigation-desktop-primary-height: 76px;
--navigation-desktop-secondary-height: 58px;
--navigation-desktop-primary-vertical-padding: 22px;
--radix-navigation-menu-viewport-height: 0px;
--space-xs: 4px; /* 17 elements — e.g. div .wds-list-item-gridWrapper, div .wds-list-item-gridWrapper, div .wds-list-item-gridWrapper /* mined from computed styles */ */
--space-md: 9.38px; /* 57 elements — e.g. button .wds-Button, button .wds-Button, a .btn /* mined from computed styles */ */
--space-lg: 12px; /* 30 elements — e.g. div .wds-list-item-gridWrapper, div .wds-list-item-gridWrapper, div .wds-list-item-gridWrapper /* mined from computed styles */ */
--space-xl: 28.15px; /* 38 elements — e.g. div .eds-cluster, div .eds-cluster, div .eds-cluster /* mined from computed styles */ */
--space-2xl: 37.54px; /* 44 elements — e.g. div .NavigationMobile_navigation_mobile__topb, div .NavigationMobile_navigation_mobile__topb, div .NavigationDesktop_navigation_primary__pa /* mined from computed styles */ */
--space-3xl: 56.31px; /* 19 elements — e.g. section .Section_root__wxCP6, section .Section_root__wxCP6, section .Section_root__wxCP6 /* mined from computed styles */ */
--ring-outline-offset: 2px;
--space-small: 16px;
--space-medium: 32px;
--space-content-horizontal: 16px;
--size-4: 4px;
--size-5: 5px;
--size-8: 8px;
--size-10: 10px;
--size-12: 12px;
--size-14: 14px;
--size-16: 16px;
--size-24: 24px;
--size-32: 32px;
--size-40: 40px;
--size-48: 48px;
--size-52: 52px;
--size-56: 56px;
--size-60: 60px;
--size-64: 64px;
--size-72: 72px;
--size-80: 80px;
--size-88: 88px;
--size-96: 96px;
--size-104: 104px;
--size-112: 112px;
--size-120: 120px;
--size-128: 128px;
--size-160: 160px;
--eds-space-1: clamp(0.25rem, calc(0.23558rem + 0.0641vw), 0.3125rem);
--eds-space-2: clamp(0.5rem, calc(0.47115rem + 0.12821vw), 0.625rem);
--eds-space-3: clamp(0.75rem, calc(0.70673rem + 0.19231vw), 0.9375rem);
--eds-space-4: clamp(1rem, calc(0.94231rem + 0.25641vw), 1.25rem);
--eds-space-6: clamp(1.5rem, calc(1.41346rem + 0.38462vw), 1.875rem);
--eds-space-8: clamp(2rem, calc(1.88462rem + 0.51282vw), 2.5rem);
--eds-space-12: clamp(3rem, calc(2.82692rem + 0.76923vw), 3.75rem);
--eds-space-16: clamp(4rem, calc(3.76923rem + 1.02564vw), 5rem);
--eds-space-24: clamp(6rem, calc(5.65385rem + 1.53846vw), 7.5rem);
--eds-space-32: clamp(8rem, calc(7.53846rem + 2.05128vw), 10rem);
/* Radius (16) */
--radius-full: 9999px;
--radius-small: 10px;
--radius-medium: 16px;
--radius-large: 24px;
--btn-radius-base: 3px;
--btn-sm-radius-base: 2px;
--mw-radius-full: 50%;
--mw-radius-1: clamp(0.625rem, calc(0.58894rem + 0.16026vw), 0.78125rem);
--mw-radius-2: clamp(1rem, calc(0.94231rem + 0.25641vw), 1.25rem);
--mw-radius-3: clamp(1.5rem, calc(1.41346rem + 0.38462vw), 1.875rem);
--mw-radius-4: clamp(2rem, calc(1.88462rem + 0.51282vw), 2.5rem);
--mw-radius-6: clamp(3rem, calc(2.82692rem + 0.76923vw), 3.75rem);
--radius-sm: 10px 10px 0px 0px; /* 3 elements — e.g. img .SegmentCard_segmentCard__media, img .SegmentCard_segmentCard__media, img .SegmentCard_segmentCard__media /* mined from computed styles */ */
--radius-md: 18.7693px; /* 13 elements — e.g. a .wds-Button "Send money", a .wds-Button "Send large amounts", a .wds-Button "Receive money" /* mined from computed styles */ */
--radius-lg: 28.1539px; /* 2 elements — e.g. li .mw-product-cards__item "Receive money fastGe", li .mw-product-cards__item "Save on spending abr" /* mined from computed styles */ */
--eds-radius-full: 50%;
/* Effects (18) */
--navigation-mobile-item-height: var(--size-48);
--navigation-skiplink-zindex: 1080;
--navigation-mobile-primary-zindex: 1049;
--navigation-mobile-secondary-zindex: 1047;
--navigation-animation-duration: 350ms;
--navigation-animation-duration-short: 200ms;
--navigation-animation-duration-long: 600ms;
--navigation-desktop-primary-button-height: var(--size-32);
--navigation-desktop-primary-panel-zindex: 1070;
--navigation-desktop-viewport-zindex: 1060;
--navigation-desktop-primary-zindex: 1050;
--navigation-desktop-dimmer-zindex: 1040;
--navigation-desktop-secondary-dropdown-zindex: 1000;
--navigation-desktop-secondary-zindex: 990;
--shadow-sm: rgb(134, 134, 133) 0px 0px 0px 1px inset; /* 2 elements — e.g. button .form-control, button .form-control /* mined from computed styles */ */
--navigation-box-shadow: 0px 4px 16px rgba(0,0,0,0.16);
--disabled-opacity: 0.45;
--shadow-sm: rgb(134,134,133) 0px 0px 0px 1px inset;
/* Motion (60) */
----motion-rotating: @keyframes rotating {
0% { transform: rotate(0deg); }
100% { transform: rotate(1turn); }
}; /* @keyframes rotating */
----motion-droppable-fade-in: @keyframes droppable-fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes droppable-fade-in */
----motion-listSlideOver: @keyframes listSlideOver {
0% { transform: translateX(100vw); }
100% { transform: translateX(0px); }
}; /* @keyframes listSlideOver */
----motion-loaderStroke: @keyframes loaderStroke {
30% { stroke-dashoffset: 300; opacity: 0; }
40% {… <0.2KB elided>; /* @keyframes loaderStroke */
----motion-loaderFill: @keyframes loaderFill {
0% { opacity: 1; }
30% { opacity: 0; }
70% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes loaderFill */
----motion-cover-fade-in: @keyframes cover-fade-in {
0% { opacity: 0; }
100% { opacity: 0.7; }
}; /* @keyframes cover-fade-in */
----motion-process-chase-circle-xxs: @keyframes process-chase-circle-xxs {
0% { transform: rotate(0deg); stroke-da… <0.4KB elided>; /* @keyframes process-chase-circle-xxs */
----motion-process-success-circle-xxs: @keyframes process-success-circle-xxs {
0% { transform: rotate(0deg); stroke-… <0.2KB elided>; /* @keyframes process-success-circle-xxs */
----motion-process-chase-circle-xs: @keyframes process-chase-circle-xs {
0% { transform: rotate(0deg); stroke-das… <0.4KB elided>; /* @keyframes process-chase-circle-xs */
----motion-process-success-circle-xs: @keyframes process-success-circle-xs {
0% { transform: rotate(0deg); stroke-d… <0.2KB elided>; /* @keyframes process-success-circle-xs */
----motion-process-chase-circle-sm: @keyframes process-chase-circle-sm {
0% { transform: rotate(0deg); stroke-das… <0.4KB elided>; /* @keyframes process-chase-circle-sm */
----motion-process-success-circle-sm: @keyframes process-success-circle-sm {
0% { transform: rotate(0deg); stroke-d… <0.2KB elided>; /* @keyframes process-success-circle-sm */
----motion-process-chase-circle-xl: @keyframes process-chase-circle-xl {
0% { transform: rotate(0deg); stroke-das… <0.4KB elided>; /* @keyframes process-chase-circle-xl */
----motion-process-success-circle-xl: @keyframes process-success-circle-xl {
0% { transform: rotate(0deg); stroke-d… <0.2KB elided>; /* @keyframes process-success-circle-xl */
----motion-process-width: @keyframes process-width {
100% { width: 100%; }
}; /* @keyframes process-width */
----motion-process-height: @keyframes process-height {
100% { top: 0px; height: 100%; }
}; /* @keyframes process-height */
----motion-sequence-pip-info: @keyframes sequence-pip-info {
0% { border-color: rgba(255, 255, 255, 0.1); }
100% { border-color: var(--color-interactive-accent); }
}; /* @keyframes sequence-pip-info */
----motion-sequence-pip-primary: @keyframes sequence-pip-primary {
0% { border-color: rgba(255, 255, 255, 0.1); }
100% { border-color: rgb(55, 81, 126); }
}; /* @keyframes sequence-pip-primary */
----motion-sequence-pip-success: @keyframes sequence-pip-success {
0% { border-color: rgba(255, 255, 255, 0.1); }
100% { border-color: var(--color-interactive-positive); }
}; /* @keyframes sequence-pip-success */
----motion-sequence-pip-warning: @keyframes sequence-pip-warning {
0% { border-color: rgba(255, 255, 255, 0.1); }
100% { border-color: var(--color-interactive-warning); }
}; /* @keyframes sequence-pip-warning */
----motion-sequence-pip-danger: @keyframes sequence-pip-danger {
0% { border-color: rgba(255, 255, 255, 0.1); }
100% { border-color: var(--color-interactive-negative); }
}; /* @keyframes sequence-pip-danger */
----motion-sequence-fill: @keyframes sequence-fill {
0% { background-position: 0px 100%; }
100% { background-position: 0px 0px; }
}; /* @keyframes sequence-fill */
----motion-sequence-pulse-info: @keyframes sequence-pulse-info {
0% { box-shadow: rgba(0, 185, 255, 0.3) 0px… <0.2KB elided>; /* @keyframes sequence-pulse-info */
----motion-sequence-pulse-warning: @keyframes sequence-pulse-warning {
0% { box-shadow: rgba(255, 166, 0, 0.3) 0… <0.2KB elided>; /* @keyframes sequence-pulse-warning */
----motion-sequence-pulse-success: @keyframes sequence-pulse-success {
0% { box-shadow: rgba(26, 208, 110, 0.3)… <0.2KB elided>; /* @keyframes sequence-pulse-success */
----motion-sequence-pulse-danger: @keyframes sequence-pulse-danger {
0% { box-shadow: rgba(245, 54, 54, 0.3) 0p… <0.2KB elided>; /* @keyframes sequence-pulse-danger */
----motion-MwFadeIn: @keyframes MwFadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes MwFadeIn */
----motion-MwFadeOut: @keyframes MwFadeOut {
0% { opacity: 1; }
100% { opacity: 0; }
}; /* @keyframes MwFadeOut */
----motion-MwTranslateTop: @keyframes MwTranslateTop {
0% { opacity: 0; transform: translateY(24px); }
100% { opacity: 1; transform: translateY(0px); }
}; /* @keyframes MwTranslateTop */
----motion-MwTranslateBottom: @keyframes MwTranslateBottom {
0% { opacity: 1; transform: translateY(0px); }
100% { opacity: 0; transform: translateY(24px); }
}; /* @keyframes MwTranslateBottom */
----motion-vjs-spinner-show: @keyframes vjs-spinner-show {
100% { visibility: visible; }
}; /* @keyframes vjs-spinner-show */
----motion-vjs-spinner-spin: @keyframes vjs-spinner-spin {
100% { transform: rotate(1turn); }
}; /* @keyframes vjs-spinner-spin */
----motion-vjs-spinner-fade: @keyframes vjs-spinner-fade {
0% { border-top-color: rgb(115, 133, 159); }… <0.3KB elided>; /* @keyframes vjs-spinner-fade */
----motion-spin: @keyframes spin {
0% { width: var(--coin-size); box-shadow: 0 0 0 var(--coin-… <0.5KB elided>; /* @keyframes spin */
----motion-swap-currencies-reduced-motion: @keyframes swap-currencies-reduced-motion {
0% { background-position-x: 0px;… <0.2KB elided>; /* @keyframes swap-currencies-reduced-motion */
----motion-tw-tooltip-disappear: @keyframes tw-tooltip-disappear {
0% { visibility: visible; }
100% { visibility: hidden; }
}; /* @keyframes tw-tooltip-disappear */
----motion-slide: @keyframes slide {
0% { transform: translateX(-12px); }
100% { transform: none; }
}; /* @keyframes slide */
----motion-slideFirst: @keyframes slideFirst {
0% { transform: translateX(-4px); }
100% { transform: none; }
}; /* @keyframes slideFirst */
----motion-fadeIn: @keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 0.6; }
}; /* @keyframes fadeIn */
----motion-NavigationDesktop_enterFromRight: @keyframes NavigationDesktop_enterFromRight {
0% { opacity: 0; transform: translateX(-10px); }
66% { transform: translateX(0px); }
100% { opacity: 1; transform: translateX(0px); }
}; /* @keyframes NavigationDesktop_enterFromRight */
----motion-NavigationDesktop_enterFromLeft: @keyframes NavigationDesktop_enterFromLeft {
0% { opacity: 0; transform: translateX(10px); }
66% { transform: translateX(0px); }
100% { opacity: 1; transform: translateX(0px); }
}; /* @keyframes NavigationDesktop_enterFromLeft */
----motion-NavigationDesktop_exitToRight: @keyframes NavigationDesktop_exitToRight {
0% { opacity: 1; transform: translateX(0px); }
100% { opacity: 0; transform: translateX(-10px); }
}; /* @keyframes NavigationDesktop_exitToRight */
----motion-NavigationDesktop_exitToLeft: @keyframes NavigationDesktop_exitToLeft {
0% { opacity: 1; transform: translateX(0px); }
100% { opacity: 0; transform: translateX(10px); }
}; /* @keyframes NavigationDesktop_exitToLeft */
----motion-slideDown: @keyframes slideDown {
0% { height: 0px; }
100% { height: var(--radix-accordion-content-height); }
}; /* @keyframes slideDown */
----motion-slideUp: @keyframes slideUp {
0% { height: var(--radix-accordion-content-height); }
100% { height: 0px; }
}; /* @keyframes slideUp */
----motion-Animations_move-up: @keyframes Animations_move-up {
0% { transform: translateY(8px); opacity: 0; }
100% { transform: translateY(0px); opacity: 1; }
}; /* @keyframes Animations_move-up */
----motion-Animations_shimmer: @keyframes Animations_shimmer {
100% { background-position-x: -100%; }
}; /* @keyframes Animations_shimmer */
----motion-Animations_fade-in: @keyframes Animations_fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes Animations_fade-in */
----motion-Continue_slideUp: @keyframes Continue_slideUp {
0% { transform: translateY(100%); }
100% { transform: translateY(0px); }
}; /* @keyframes Continue_slideUp */
----motion-Continue_fadeIn: @keyframes Continue_fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes Continue_fadeIn */
----motion-SimpleMotion_fadeInAndDropDown__KAeXq: @keyframes SimpleMotion_fadeInAndDropDown__KAeXq {
0% { opacity: 0; transform… <0.3KB elided>; /* @keyframes SimpleMotion_fadeInAndDropDown__KAeXq */
----motion-SimpleMotion_fadeInAndDropUp__xJAfq: @keyframes SimpleMotion_fadeInAndDropUp__xJAfq {
0% { opacity: 0; transform:… <0.3KB elided>; /* @keyframes SimpleMotion_fadeInAndDropUp__xJAfq */
----motion-RevealInteractive_revealFlag__GCaSC: @keyframes RevealInteractive_revealFlag__GCaSC {
0% { opacity: 0; transform: rotate(-15deg) scale(0.8); }
100% { opacity: 1; transform: rotate(0deg) scale(1); }
}; /* @keyframes RevealInteractive_revealFlag__GCaSC */
----motion-RevealInteractive_arrowSlide__Ij84P: @keyframes RevealInteractive_arrowSlide__Ij84P {
0% { opacity: 0; transform: translateX(-20px) scale(0.8); }
100% { opacity: 1; transform: translateX(0px) scale(1); }
}; /* @keyframes RevealInteractive_arrowSlide__Ij84P */
----motion-RevealInteractive_arrowPulse__SS7PC: @keyframes RevealInteractive_arrowPulse__SS7PC {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}; /* @keyframes RevealInteractive_arrowPulse__SS7PC */
----motion-cc_fade-in_3878789923: @keyframes cc_fade-in_3878789923 {
0% { opacity: 0; }
100% { display: block; opacity: 1; }
}; /* @keyframes cc_fade-in_3878789923 */
--duration-fast: 0.15s; /* 34 elements — e.g. button, button, button /* mined from computed styles */ */
--duration-base: 0.3s; /* 6 elements — e.g. button, button, button /* mined from computed styles */ */
--duration-slow: 0.35s; /* 74 elements — e.g. button, a, a /* mined from computed styles */ */
--ease-default: ease; /* 238 elements — e.g. button, button, button /* mined from computed styles */ */
```
## Appendix B: Token Source Metadata
```
tokenSource: extracted-css-vars
site: wise.com
confidence: high
cssVarsFound: 217
curatedTokens: 42 (mapped to standard roles with --wise-* aliases)
extractionDate: [extract date — update manually]
reconstructed: none — all tokens extracted directly from CSS custom properties
```
**Source notes:**
- Token source is `extracted-css-vars` — all `--color-*`, `--font-*`, `--space-*`, `--radius-*`, `--line-height-*`, `--letter-spacing-*`, and `--motion-*` values are from the live site's CSS, not reverse-engineered from computed styles.
- `--brand-primary-cta`, `--brand-secondary-cta`, `--brand-mark-1/3/4` are **synthesised tokens** derived from computed button background colours and SVG fills — they do not appear verbatim in the CSS custom properties but are the canonical computed values for those roles.
- `--font-size-3xl` (`45.4572px`) and `--font-size-xl` (`24.6285px`) are **computed values** mined from rendered element sizes, mapped to the font-size scale as `--wise-font-size-3xl` and `--wise-font-size-xl` in the curated set.
- The `--eds-space-*` and `--mw-space-*` scales are numerically identical; `--eds-space-*` is canonical for new work.
- **Detected libraries:** Tailwind (utility classes), Bootstrap (legacy component layer), Next.js (framework). The `--btn-*` tokens are Bootstrap-origin; prefer the `--eds-*`/`--mw-*` design system tokens for new component work.
- **Fluid tokens** (`clamp()` values on `--eds-space-*`, `--mw-radius-*`, `--eds-radius-*`) respond to viewport width between approximately 1248px and 1440px based on the clamp parameters.
- The `--wise-radius-sm` curated token (`10px 10px 0px 0px`) is a **shorthand value**, not a scalar — do not use it as `border-radius` uniformly; it is a top-corners-only application for card media elements.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