N
Neptune Odyssey Design System · Neptune.Fintech
Material 3 · Expressive White-label core v1.0 · Stable

One core. Every bank looks like itself.

A single Material 3 Expressive foundation that any bank can wear as its own — colour, shape, type and motion all flex to the brand, while the structure, accessibility and engineering stay identical. Switch the brand pills above and watch the entire system re-skin.

4
brand themes, infinite seeds
2
modes — light & dark
LTR / RTL
bidi-ready by default
M3
tokens map 1:1 to Flutter

Four banks, one system

Tap a card to theme everything below

Personalisation runs deeper than a primary colour. Each brand redefines its full tonal palette, a corner-radius family, a display typeface and motion feel — yet every component, flow and accessibility guarantee is shared.

Foundations

The tokens behind every screen

Colour roles · derived from one seed, re-mapped per brand & mode

{{ c.name }}

Type scale

{{ t.role }} · {{ t.px }}
{{ t.sample }}

Shape scale · a per-brand corner family

{{ s.name }}

Elevation

{{ e.name }}

Spacing · 4px base

{{ sp.n }}

Motion · easing & duration tokens

{{ m.name }}{{ m.dur }}

Spring easing is the Expressive default for spatial transitions; standard/emphasized cover the rest.

Components

A complete Expressive kit

Every control is live — toggle, drag and select. All of them inherit the active brand's colour, corner family and type, so a component built once is correct for every bank.

Buttons
FAB & icon buttons
Segmented button
Filter chips
Selection controls
Slider{{ sliderPct }}
Text fields
Cards
Elevated
Floats above the surface with a soft shadow.
Filled
Tonal container, no shadow.
Outlined
Quietest emphasis, outline only.
List items
{{ t.iconEl }} {{ t.name }}{{ t.sub }} {{ t.amount }}
Badges & progress
3 ● Active
In context

The same app, wearing {{ brandName }}

Real banking surfaces assembled entirely from the kit above. Switch the brand or mode at the top, or tap the bottom navigation — the structure never moves, only the skin.

9:41 {{ icSignal }}{{ icWifi }}{{ icBattery }}
{{ miniBalance }}
{{ brandMarkEl }} {{ brandWordmark }}{{ L.goodMorning }}, {{ activeUserName }}
{{ a.caption }}
{{ a.balance }}{{ a.dec }} {{ a.cur }}
{{ a.delta }} {{ L.thisMonth }}
{{ L.services }} {{ L.allServices }}
{{ L.moreFrom }} {{ brandName }} {{ L.viewAll }}
{{ p.iconEl }} {{ p.tag }}
{{ p.title }}
{{ p.body }}
{{ p.cta }}
{{ L.upcomingBills }} {{ L.payAll }}
{{ bl.iconEl }} {{ bl.name }}{{ bl.sub }} {{ bl.amount }}
{{ activeAccountName }} {{ L.activitySuffix }} {{ L.seeAll }}
{{ t.iconEl }} {{ t.name }}{{ t.sub }} {{ t.amt }}
{{ L.myCards }}
{{ featuredCard.name }}
{{ featuredCard.net }}
{{ icContactless }}
MU TELLESY EXP{{ featuredCard.expShown }}CVV{{ featuredCard.cvvShown }}
{{ icFreeze }} {{ L.cardFrozenNote }}
{{ L.thisCard }} · {{ deckFrontName }}
{{ t.iconEl }} {{ t.name }}{{ t.sub }} {{ t.amount }}
{{ L.sendTransfer }} {{ icSearch }}
{{ L.allMethods }}
{{ L.recentTransfers }}
{{ t.iconEl }} {{ t.name }}{{ t.sub }} {{ t.amt }}
{{ L.insights }}
{{ L.spentMonth }}
1,620.00 LYD
↓ 8% {{ L.vsLast }}
{{ L.byCategory }}
{{ i.cat }}{{ i.amount }} · {{ i.pct }}
{{ activeUserInit }} {{ activeUserName }}{{ icSparkle }} {{ tierName }}
{{ L.personalize }}
{{ L.appearance }}
{{ icLang }}{{ L.language }}
{{ icSparkle }}{{ L.themeRow }} {{ brandName }}
{{ L.security }}
{{ icShield }} {{ L.biometric }}
{{ icLock }} {{ L.changePin }} {{ icChevR }}
{{ icDevices }} {{ L.trustedDevices }} 2
{{ L.preferences }}
{{ icBellPref }} {{ L.pushNotif }}
{{ icStmt }} {{ L.statements }} {{ icChevR }}
{{ icHelp }} {{ L.help }} {{ icChevR }}
{{ L.accountDetails }}
{{ acctDetailType }} · {{ acctDetailName }}
{{ acctDetailBalance }} {{ acctDetailCur }}
{{ L.availableBalance }}
{{ L.transactionsT }}
{{ t.iconEl }} {{ t.name }}{{ t.sub }} {{ t.amt }}
{{ L.wuTitle }}
{{ s.n }} {{ s.label }}
AH {{ wuReceiver }}{{ L.cashPickup }} · {{ L.country }} {{ icCheckBig }}
{{ L.payoutCountry }}{{ L.country }}
{{ L.deliveryMethod }}{{ L.cashPickup }}
{{ L.amount }}
300 USD
{{ L.fee }}8.00 USD
{{ L.willReceive }}1,470 EGP
{{ L.total }}308.00 USD
{{ L.toLabel }}{{ wuReceiver }}
{{ L.deliveryMethod }}{{ L.cashPickup }} · {{ L.country }}
{{ L.willReceive }}1,470 EGP
{{ L.total }}308.00 USD
{{ icInfo }} {{ wuReviewNote }}
{{ L.sendingTitle }}
{{ L.sendingSub }}
{{ icCheckBig }}
{{ L.successTitle }}
{{ payAmount }} {{ payCur }}
{{ payToLine }}
{{ L.loggedInDevice }}
{{ L.pay }}
{{ activeUserName }}
{{ L.payWithQr }}
{{ icNfcBig }}
{{ L.tapToPayTitle }}
{{ L.payWithNfc }}
{{ L.vouchersTitle }}
{{ v.iconEl }} {{ v.brand }}{{ v.off }}
{{ v.code }} {{ L.exp }} {{ v.exp }}
{{ L.choosePayFrom }}
{{ icCheckMini }} {{ toast }}
Principles

The doctrine Odyssey is built on

Six rules decide every call in this system. When a decision is hard, the principle wins — not the individual screen.

{{ p.n }}
{{ p.title }}

{{ p.body }}

Interaction

States & focus, specified

Every interactive surface carries the M3 state-layer model — a translucent overlay of its on- colour. The ratios are fixed system-wide so a button in any brand responds with the same physics.

State layers · filled action
Pay {{ s.label }} {{ s.spec }}
Try it Tab to either to see the focus ring.
Focus indicator
Pay

A 2px primary ring at 2px offset, keyboard-only via :focus-visible. Never shown on pointer input.

{{ n.iconEl }}{{ n.text }}
Motion

Three curves, one feel

Expressive motion is tokenised, not improvised. Standard for the everyday, emphasized for entrances, spring for anything that should feel alive. All three honour prefers-reduced-motion.

{{ m.name }}{{ m.dur }}

{{ m.use }}

{{ m.curve }}
Spacing

A 4-point grid, everywhere

Every gap and padding snaps to a multiple of four. Use gap on flex and grid rather than per-child margins, so spacing survives reorder and RTL untouched.

{{ s.px }} {{ s.use }}
Accessibility

AA is the floor, not the goal

Accessibility is built into the tokens, so it ships with every brand for free. The on- pairings are contrast-validated in every theme and mode before release.

Contrast pairs
{{ c.label }} {{ c.ratio }}
Touch targets · 48dp minimum

A 22px glyph still gets a 48×48 hit area. Icon buttons pad to target; they never shrink to fit.

{{ a.iconEl }}{{ a.text }}
Anatomy

Read one component to read them all

The transaction row is the system in miniature: a leading token-shaped container, a two-line text block, and tabular figures — every measure a token, nothing literal.

{{ anatomyIcon }} Al Mahaba MarketGroceries · Today −86.40 LYD
{{ a.k }} — {{ a.v }}
White-label rule

Same skeleton. Unmistakable skin.

Twelve brand levers separate every bank. The rule: a brand must move at least six — so two banks never feel like the same app reskinned lazily, yet never like a different product either. {{ brandLeverSentence }}

{{ l.iconEl }} {{ l.label }}
Governance

Versioned, governed, ready to ship

Odyssey ships on semantic versioning. Tokens are the public API: a token rename is a breaking change, a new token is a minor, a value fix is a patch. Components carry a status so teams know what they can build on.

ComponentStatusSince
{{ r.name }} {{ r.status }} {{ r.since }}
Onboard a bank in one config

A new bank is one tenant config set — seed hue, corner family, type, motif — never a fork. Author it, validate light/dark + RTL + contrast, ship. The component and screen code never changes.

{{ c.n }}{{ c.text }}