> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# Example design

# Example design system: Universal Exports

This is an optional, ready-made design system you can adopt wholesale or restyle to your own brand. It exists so a developer with no design of their own can still ship an on-brand, premium product on the Open Money Stack, and so an AI build tool has a complete visual contract to generate against. It pairs with the [Open Money Stack skill](https://docs.polygon.technology/skill.md): the screens below are already mapped to real OMS endpoints.

If you have your own brand, bring it instead (logo, colors, type, components) and use this only as a reference for how screens map to the API. Everything here is an example, not a requirement. Provider names mentioned are illustrative.

"Universal Exports" is a premium, borderless neobank: spend, send, exchange, and grow money anywhere. Positioning line: "Money without borders." The brand is discreet, global, and precise: confident without hype, technical without coldness. Think a private bank's restraint with a modern consumer app's speed.

## Surfaces and themes

A dark-led product (the mobile app runs on onyx), warm paper for the light web dashboard, and a single signature accent (Voltage lime `#CDEC5F`) for energy and primary action. Both themes are first-class; pick one per surface and do not mix them within a single screen.

* `data-theme="dark"`: onyx canvas. Default for the mobile app.
* `data-theme="light"`: warm paper. For the web dashboard, marketing, and docs.

The primary action color flips by theme automatically through tokens: Voltage on dark (onyx text), onyx ink on light (white text), with Voltage as accent only.

### Device framing

The mobile app is the primary surface, so render its screens inside an iPhone device frame by default. Use a 390x844 logical viewport (or a current iPhone equivalent), the device's rounded corners, a status bar or dynamic island at the top, and a home indicator at the bottom. Respect the safe-area insets: keep the balance and header clear of the top inset, and float the bottom tab bar above the home indicator. Center the framed app on a plain onyx 950 backdrop so the product reads as a real phone rather than a full-bleed web page.

The light web dashboard is the exception: build it as a standard, responsive browser layout with no device frame. Treat the iPhone frame as the default for app screens and a plain web canvas as the default for the dashboard.

## Design tokens (the contract)

Use tokens, never raw hex, in product code. These are the foundation values.

### Color primitives

Onyx (cool near-black neutral ramp):
`950 #0A0B0D` · `900 #101216` · `850 #15181C` · `800 #1B1F24` · `700 #262B31` · `600 #353B43` · `500 #4C535C` · `400 #6B727B` · `300 #969CA4` · `200 #C2C7CD` · `100 #E2E5E9` · `50 #F1F2F4`

Paper (warm off-white ramp): `50 #FBFAF6` · `100 #F6F4EC` · `200 #ECE9DD` · `300 #DDD9C9`

Voltage (signature acid-lime): `50 #F6FBE4` · `100 #EAF7BE` · `200 #DCF291` · `300 #CDEC5F` (signature) · `400 #BBDE3A` · `500 #A2C424` · `600 #7E9A18` · `700 #5C7012`

Atlantic (deep teal, trust / secondary): `50 #E6F2F0` · `100 #C0DEDA` · `300 #5FA39A` · `500 #1C6F66` · `600 #145A52` · `900 #0B3531`

Semantic hues: green `400 #34C77B` / `600 #15924F`, amber `400 #F2B824` / `600 #C28A0A`, red `400 #F0604E` / `600 #CF3320`, sky `400 #46A8F0` / `600 #1B7BC4`.

Spending categories (use consistently across donut, row icon, chart): transfers `#CDEC5F`, dining `#F2884E`, travel `#46A8F0`, shopping `#B98CF0`, bills `#1C6F66`, income `#34C77B`, other `#969CA4`.

### Theme tokens

Dark (default app surface): `--bg #0A0B0D`, `--surface #101216`, `--surface-2 #15181C`, `--surface-3 #1B1F24`, `--fg #F4F5F2`, `--fg-secondary #969CA4`, `--fg-faint #6B727B`, `--border rgba(255,255,255,0.09)`, `--border-strong rgba(255,255,255,0.16)`, `--brand #CDEC5F`, `--brand-fg #0A0B0D`, `--cta-bg #CDEC5F`, `--cta-fg #0A0B0D`, `--pos #34C77B`, `--neg #FF8A7A`.

Light (web dashboard): `--bg #F6F4EC`, `--surface #FFFFFF`, `--surface-2 #FBFAF6`, `--fg #14150F`, `--fg-secondary #5C5E54`, `--border #ECE9DD`, `--brand #A2C424`, `--cta-bg #0A0B0D`, `--cta-fg #FFFFFF`, `--pos #15924F`, `--neg #CF3320`, `--link #1C6F66`.

### Type

Two families only. Hanken Grotesk (`--font-ui`) for all words; JetBrains Mono (`--font-mono`, tabular) for all money, codes, and micro-labels. Both load from Google Fonts.

Scale (mobile-first, px): display 44 (hero balance or one marketing headline, max one per screen), h1 32, h2 26, h3 21, body-lg 18, body 16 (default), body-sm 14, label 13, caption 12 (floor, never smaller). Weights 400/500/600/700/800. Line height: 1.08 display, 1.18 heading, 1.5 body. Tracking: display -0.02em, heading -0.01em, label +0.08em.

### Space, radii, elevation, motion

4px grid: 4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 56 / 72. Radii: xs 6, sm 10, md 16, lg 22, xl 28, full 999. Elevation is soft and low-contrast; the only colored glows are the focus ring `0 0 0 3px rgba(205,236,95,0.55)` and the Voltage CTA lift on dark. Motion durations 120 / 200 / 320ms, ease-out for enter, no spring, no bounce, no parallax.

## Hard rules

### Color

* Voltage is a seasoning, not a sauce. Use it for the primary CTA on dark, key highlights, active states, focus rings, one metal card. Never fill a whole screen or large surface with it; if more than about 10% of a screen is lime, cut back.
* Dark is the default product surface. The web dashboard and docs may run light. Both are first-class; do not mix within one screen.
* Money has color semantics. Money in and gains use `--pos`; money out and loss use `--neg`. Never use Voltage to mean "positive"; Voltage is brand, not signal.
* Spending categories use the category palette, reused consistently so a category reads the same color everywhere.
* No pure black `#000` and no pure-white text on color. Onyx 950 is the darkest surface. Text on Voltage is always onyx, never white.
* WCAG AA minimum: 4.5:1 body, 3:1 large text.

### Typography

* Two families only. No third face, no italics, no gradient text, no all-caps headlines.
* All money renders in mono with tabular figures: balances, amounts, rates, account numbers, percentages, timers. This is the single most recognizable trait of the system. Never set an amount in Hanken.
* One heading treatment per screen. Display (44) is reserved for the hero balance or one marketing headline, max one per screen.
* Micro-labels are mono, uppercase, tracked, and faint ("AVAILABLE BALANCE", "TODAY", "SANDBOX"). At most one or two per screen. They are the only uppercase text allowed.
* Floor is 12px. Body default 16px. Sentence case everywhere except micro-labels. No Title Case buttons.

### Layout and space

* 4px grid. Screen gutters 20 to 24px on mobile, 32 to 64px on web.
* Spacing groups content, not borders. Do not wrap every block in a card. Use whitespace and a single hairline divider where separation is needed.
* Cards wrap to content. No large empty colored rectangles, no nested cards beyond one level, no left-side accent borders.
* Mobile-first. Bottom tab bar, 5 items max, 44px+ hit targets. Balance and context at the top of the screen; thumb-reachable actions below.

## Components

* Buttons. Radius 16. One primary per visible section (uses the CTA token). Secondary is transparent with a strong border. Ghost is text only. Press scales to 0.98 over 120ms. Min height 44px on mobile.
* Inputs. Surface-2 fill, hairline border, radius 10. Focus moves the border to brand and adds the focus ring. Label above, sentence case. Every field is keyboard-navigable in a logical tab order. A one-time-code (OTP) entry accepts paste and browser autofill, splitting a pasted code across its boxes, not only per-digit typing.
* Pills and segmented filters. Full radius. Active pill is a brand fill with onyx text.
* Status badges. Mono, uppercase, tinted with the matching semantic at about 18% alpha: SETTLED, PENDING, SENT, REVIEW.
* Transaction row. A 42px round category-tinted icon, title plus sub (place / time / card), and a mono amount on the right (green `--pos` if incoming, default `--fg` with a leading minus if outgoing). Hairline divider between rows, none on the last.
* Balance hero. Mono balance at display size with faint cents. One soft radial Voltage glow allowed top-right. Primary plus secondary action below. Label it "Available balance"; never "On-chain balance" or a chain-tagged label such as "· Polygon". USDC is the rail, not a user-facing label.
* Receive / QR. The receive screen shows the user's own wallet address as a real, scannable QR code generated from the actual address (a QR library or a data-URI canvas), with the address in mono beneath and a copy-address action. Render an actual code, never a placeholder image or icon.
* Payment card visual. Aspect ratio 1.586, radius 28. Onyx gradient (standard) or Voltage gradient (Metal / premium). Mono card number, uppercase mono name, gold chip. Never show the full number; mask to last four (`•••• 4218`). OMS does not issue cards, so treat this as a brand object for marketing and illustration, not a spendable issued card.
* Currency exchange. Two surface-2 legs (from / to) with mono values and a round brand swap button between them. Always show the rate and a lock timer in mono beneath.
* Charts. Sparklines and spending donuts use category colors; area and line gains use `--pos`. Axis and grid in faint onyx. Tabular mono for all data labels.

## Motion, voice, and copy

* Motion is fade and slide only, within 120 / 200 / 320ms. Sheets slide up 320ms; toasts fade. Numbers may count up on a balance reveal (ease-out, 600ms or less).
* Voice is second person and action-led. Buttons are verb plus noun: "Send money", "Add money", "Create deposit address", "Exchange". Never "Get started!" or "Learn more".
* Plain, declarative, cause then effect: "Rate locks in 30 seconds." "Senders must be verified before funds settle."
* No emoji, no exclamation marks, no periods on short labels or titles. Sentence case.
* Money is precise: explicit currency symbol or code, two decimals for fiat, mono. Truncate long IDs with `••••` and the last four, never paraphrase.
* Label money to users as USD (dollars). USDC is the settlement asset on the rail, not a user-facing label; do not show "USDC" in consumer copy.
* Global by default: the product assumes money crosses borders.

## Self-review checklist

Run this against every screen before it ships.

1. Tokens only, zero raw hex in markup.
2. Every monetary figure in JetBrains Mono, tabular.
3. Exactly one primary button per visible section.
4. Voltage at most about 10% of the surface, never a full background.
5. Money in and out use `--pos` and `--neg`, not Voltage, for meaning.
6. One heading treatment; at most two mono micro-labels; no italics, gradient, or all-caps headlines.
7. Correct primary-CTA color for the theme (Voltage on dark, ink on light).
8. Cards wrap to content; no empty colored rectangles, no nested cards, no left-accent borders.
9. Spending categories use the category palette consistently.
10. Sentence case; verb-noun buttons; no emoji; no exclamation marks; no periods on titles.
11. Mobile hit targets 44px or larger; tab bar 5 items or fewer.
12. Body 16px or larger, nothing under 12px; AA contrast.
13. Motion is fade or slide only, within the duration tokens; no bounce.
14. App screens render inside an iPhone device frame with safe-area insets and a bottom tab bar; the web dashboard renders as a standard browser layout.

If a request forces a banned pattern, push back and propose an in-system alternative.

## Information architecture

The full Universal Exports vision is a 5-tab mobile app, but only some tabs are backed by
a live OMS capability today. Build the live-backed tabs as core wired screens and render
the rest as coming-soon states. This mirrors the live-versus-early-access discipline in
the [skill](https://docs.polygon.technology/skill.md): do not wire a screen the API
cannot serve.

Core tabs (backed by live OMS endpoints, build these):

1. Home: total balance, quick actions (Add money, Send), recent activity.
2. Activity: full transaction history, filters, search, category insights.
3. Hub / Profile: recipients, settings, verification (KYC) status.

Vision tabs (not backed by a live OMS capability today, render as coming-soon, do not wire):

* Cards: OMS does not issue cards, so there is no spendable-card capability to wire. The
  payment-card object in this system is a brand element, not an issued card.
* Exchange: in-app FX between currencies is not a live OMS capability, and a US/USD product
  has nothing to convert. Add it only once a real rail backs it.

Cross-cutting flows: onboarding / KYC, send and request (P2P), spending analytics,
notifications / toasts.

## Screen to OMS endpoint mapping

The reference backend is the Polygon Open Money Stack. Each consumer screen names the mechanism and endpoints it calls, so the design and the implementation plan line up. Follow the same live-versus-early-access split as the main skill: standard transactions and cash-in are live today; virtual accounts and deposit addresses are early access (only their `simulate` endpoints exist in sandbox).

| Consumer screen  | OMS mechanism                        | Endpoints                                                                                                                                                                                                                        | Status        |
| ---------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| Review transfer  | Transaction (quote then transaction) | Accept the recipient as an email, username, or `0x` address; resolve to a `blockchainAddress` or an internal `walletId`, then `POST /quotes` then `POST /transactions`. Show the fee breakdown, exchange rate, and quote expiry. | Live          |
| Transfer status  | Transaction lifecycle                | `GET /transactions/{id}`; `processing` then `completed` or `failed`. Prefer the `transaction.*` webhooks over polling.                                                                                                           | Live          |
| Add cash         | Cash-in                              | `POST /cash-ins` returns a deposit code (valid 1 hour); `POST /cash-ins/{id}/refresh` to renew.                                                                                                                                  | Live          |
| Add money (bank) | Virtual account                      | Dedicated bank account; inbound fiat auto-converts to USDC. Sandbox: `POST /virtual-accounts/{id}/simulate`.                                                                                                                     | Early access  |
| Receive crypto   | Deposit address                      | Persistent onchain address from `depositInstructions`; auto-creates a transaction on deposit. Sandbox: `POST /deposit-addresses/{id}/simulate`.                                                                                  | Early access  |
| Cards            | None                                 | OMS does not issue cards, so there is no endpoint to wire. The payment-card visual is a brand object, not an issued card.                                                                                                        | Not available |
| Exchange         | None                                 | No OMS endpoint for in-app FX; a US/USD product has nothing to convert.                                                                                                                                                          | Not available |

Auth and conventions match the main skill: exchange key and secret at `POST /auth/token` for a 60-minute bearer token, send `Authorization: Bearer <token>` on every call, and put an `Idempotency-Key` on every POST. Assets and networks are lowercase pairs (`usdc`/`polygon`, `usd`/`ach`, `usd`/`cash`). Custodial wallets come from `POST /customers/{id}/wallets`; non-custodial uses the embedded wallet, which carries your branding.

## Onboarding and KYC

The onboarding form collects the identity the OMS needs (name, email, phone, date of birth, residential address, and an SSN for US users) and runs KYC through `POST /customers`. Keep the verify-your-identity step quiet and trustworthy:

* The form follows the input rules above: a logical tab order through every field, and a verification-code entry that accepts paste and autofill.
* Do not gate the step with jurisdiction copy such as "US residents only". State what the step does ("Verify your identity to hold and move funds"), not who may use it.
* Do not add a sandbox explainer note at the bottom of the step. A single "SANDBOX" micro-label or pill is the only sandbox indicator a screen needs.

## Notes and substitutions

* Fonts load from Google Fonts (Hanken Grotesk, JetBrains Mono). Swap to self-hosted in production.
* Icons: adopt a single line-icon set (Lucide works well: 1.5px stroke, `currentColor`) at 16 / 20 / 24px.
* No product photography or 3D. The brand leans on type, color, and the payment-card object.
* This is an example. Swap the palette, type, and copy for your own brand; keep the structure and the screen-to-endpoint mapping.
