Skip to main content
ENKO

Design principles

Four principles behind every design decision in Senco.

Principles earn their place by resolving arguments. Each one below is stated with the trade-off it accepts, because a principle that costs nothing decides nothing. When two conflict, the order on this page is the tie-breaker: clarity beats speed, speed beats constraint optimization, and all three beat path simplification.

Clarity first

Every screen answers three questions immediately: Where am I? What can I do? What just happened? Moving money across borders requires trust — show everything, hide nothing.

  • Use clear, specific labels — "Send 250 USD" not "Submit"
  • One primary action per screen to reduce decision fatigue
  • Status feedback is immediate and unambiguous
  • Avoid jargon — Senco users may not be native English speakers
  • Show exact fees and exchange rate before confirmation
  • Break down costs visually (transfer fee + FX markup = total)
  • Use recognizable status labels (Pending → Sent → Completed)

What this costs

Clarity costs screen space and it costs conversion. A fee breakdown shown before confirmation loses some users at the last step who would have completed if the total had been a single number. That is the intended outcome: a user who would not have sent had they seen the fee should not be sending.

Trust is built on bad news, not good news

Any product can present a successful transfer well. Trust is decided by how the product behaves when the rate moved, when the transfer is delayed, when verification was rejected. Those screens get the same care as the happy path — specific reasons, an explicit next step, and no euphemism. "Your transfer could not be completed" is not clarity; "The recipient's account number was rejected by the receiving bank" is.

In practice

ClearUnclear
"Send 250.00 USD → 412,500 NGN""Continue"
"Arrives by Thursday, 14 Mar""Arrives in 2–3 business days"
"Fee 3.50 USD + rate margin 1.20 USD""Fees may apply"
"Rejected — the ID photo was too blurry to read""Verification unsuccessful"
"Sent — the bank is processing it""Done"
Do
SNC-2026-0847Completed
You sent$250.00 CAD
Service fee (1.5%)−$3.75
Rate113.38 JPY
Yuki received¥27,731.90 JPY

Every line item visible: status, fee, rate, received amount. Show exact costs upfront — no surprises.

Don't

Fees may apply. See terms and conditions for details on applicable charges and exchange rates.

Vague language hides costs. User has no idea what they'll pay.

Speed over features

Users send money under pressure — reduce steps, not capabilities.

  • Core transfer flow is 3 taps: Amount → Recipient → Confirm
  • Pre-fill with last-used values (currency, recipient)
  • Show exchange rate comparison inline, not behind a "more info" link
  • Skeleton screens during loading — never blank screens

What this costs

Every feature request is measured against the tap count of the core flow. Scheduled transfers, split payments, and multi-recipient batches have all been deferred not because they lack value but because each one adds a decision to a flow that most users complete under time pressure. The system optimizes for the ninetieth transfer, not the first.

Speed means perceived speed

A 400ms response that shows a skeleton feels faster than a 250ms response that shows nothing. The product is measured on when the user can act, not when the request resolves — which is why text renders before images, cached data renders before fresh data, and the primary action is tappable while an entrance animation is still running.

Where speed is deliberately surrendered

The confirmation step. It cannot be skipped, it cannot be triggered by a stray Enter key, and it does not pre-select. One irreversible action in the product, and it is the one place friction is correct.

Do
Your payment methods
Visa ****7788
Expires 11/27
RBC Royal Bank ****4400
Chequing
Sending$250.00 CAD
Fee$3.75 (1.5%)
Total charged$253.75

Saved methods with inline summary — select, review fee, and confirm. No extra steps.

Don't
Send 250 CAD
View exchange rates →
Opens a separate page

Force the user to navigate to a separate rates page.

Design for constraints

Senco users often deal with slow or unstable connections and lower-end phones. Every screen must work fully with zero images loaded.

Core rule

Images are enhancement, never content. Financial data, transaction status, and actionable UI must render and operate with zero images. This is the baseline, not a fallback.

Touch targets

Touch targets are 48px minimum. Users may have damaged screens or use the app while moving — generous tap areas prevent errors on critical financial actions.

Text-first rendering

Critical content (balances, transaction status, amounts) loads as text first. Images like avatars and banners are lazy-loaded only when scrolled into view. The user can already act on their data before a single image appears.

Progressive image strategy

BreakpointMax image sizeFormat
Mobile (≤600px)15 KBWebP
Tablet (≤1024px)40 KBWebP
Desktop (>1024px)80 KBWebP + JPEG fallback

Use srcset with at least 3 sizes. Never serve a single large image to all devices.

Save-Data mode

When the user has Data Saver enabled (Save-Data: on header), Senco strips non-essential images — no promotional banners, initials instead of profile photos, text rates instead of chart visualizations. The page remains branded and clean, not broken.

Cache-first loading

A service worker caches static assets and recent data. On repeat visits, the app renders instantly from cache while fresh data syncs in the background. Image cache is budgeted at 10–15 MB maximum — prioritize financial data over decorative assets.

Offline resilience

When offline, Senco shows cached data with a clear timestamp ("Updated 3 min ago"). Avatars become initial circles, banners become text. All financial information remains accessible. Transfers queue locally and sync when connectivity returns.

Stale data must announce itself

Cached data without a timestamp is worse than no data, because a user cannot tell a balance from three days ago from a balance from three seconds ago. Every cached financial value carries its age. An exchange rate older than its validity window is shown struck through with a refresh action, never shown as current.

What this costs

The system gives up webfonts, decorative imagery, hero animation, and chart-heavy dashboards. The interface is plainer than a competitor designed for a flagship phone on office wifi. That is the deliberate trade: the product has to work on the device the user actually has.

It also constrains the design toolchain. The Figma MCP pipeline does not return images or custom fonts — which costs nothing here, because the system does not use either.

Do
3G — 1.2s
South Korea flag
Min-ji Kim
Mar 28 · Sent
-$250.00 CAD
Completed
United Kingdom flag
James Wilson
Mar 25 · Received
+$80.00 CAD
Pending
Flags + text load instantly. Heavy assets deferred.

Text-first: names, amounts, and status render immediately. Country flags are tiny PNGs that load fast.

Don't
3G — 1.2s
All data waits for images. User sees empty skeletons.

Everything loads together — user stares at empty skeletons while images block the render.

Do
DATA SAVER ON — 120 KB session
South Korea flag
Min-ji Kim
Mar 28 · Sent
-$250.00 CAD
Completed
United Kingdom flag
James Wilson
Mar 25 · Received
+$80.00 CAD
Pending
No banner, no heavy photos. Flags + text only. Clean and fast.

Respect Save-Data header — strip banners, use tiny flags, show text rates. 120 KB per session.

Don't
DATA SAVER ON — 800 KB session
Hero banner loading... 350 KB
Data Saver ignored. Same heavy page burns expensive mobile data.

Ignoring Data Saver wastes expensive bandwidth on assets the user explicitly opted out of.

Do
OFFLINE
Offline · Showing data from 3 min ago
South Korea flag
Min-ji Kim
Mar 28 · Sent
-$250.00 CAD
Completed
United Kingdom flag
James Wilson
Mar 25 · Received
+$80.00 CAD
Pending
Cached data accessible. Transfers queue locally until reconnected.

Show cached history with clear timestamps. User can still view transactions and status offline.

Don't
OFFLINE
No internet connection
Retry

Full-screen 'No internet' dead-end. User can't see balance, can't see history, can do nothing.

Do
REPEAT VISIT — 2G
UI assetsfrom cache — 0ms
Rate dataAPI fetch — 1.8s
Page renderinstant

Service worker caches UI assets. Repeat visits render instantly — only fresh data hits the network.

Don't
REPEAT VISIT — 2G
Banner imagere-download — 350 KB
Rate dataAPI fetch — 1.8s
Page render8s+ wait

No caching — same 350 KB banner re-downloads every visit. 8+ seconds on 2G.

Do
Send
Receive
48px height · full-width touch targets

48px minimum for all interactive elements.

Don't
Send
Receive
28px height — mis-tap risk on financial actions

Small targets cause errors on financial actions.

Do
system-ui font0 KB
SVG icons~0.3 KB each
Mobile image budget≤15 KB WebP
CSS transitions0 KB (GPU)

System fonts, SVG, WebP budget, CSS animations — minimal payload.

Don't
Google Fonts+120 KB
Icon library+85 KB
Unoptimized PNG+350 KB
Lottie animation+200 KB

Web fonts + icon packs + uncompressed images + animation libraries = 755 KB on 3G.

One path, not many

Reduce cognitive load by offering one clear path to each goal.

  • Transfer flow is linear (no branching wizards)
  • Bank vs. Crypto selection is a comparison, not a choice tree
  • Settings are grouped by task ("Notifications", "Security") not by feature
  • Navigation is flat: max 2 levels deep

Comparison, not configuration

Bank versus crypto is the clearest example. As a choice tree it asks the user to understand settlement rails before they can send money. As a comparison it shows both options side by side with the two numbers that decide it — total cost and arrival time — and the user picks a row. Same capability, no expertise required.

What this costs

Power users lose shortcuts. There is no way to skip ahead, no saved templates, no advanced mode. The flow is the same length on the hundredth transfer as on the first. Pre-filling recovers most of that cost, and it recovers it without adding a second path to maintain.

Two levels, no more

Navigation depth is capped at two. A setting that needs a third level is in the wrong group, and the fix is to regroup by task rather than to nest. This cap is also what keeps breadcrumbs unnecessary on mobile.

Do
South Korea flag
Min-ji Kim
Last sent · South Korea
United Kingdom flag
James Wilson
United Kingdom

Smart default — surface the most recent contact, let users change if needed.

Don't
Bank transfer
Mobile money
Cash pickup
Crypto wallet
Card payment

Too many equal choices. User has to evaluate 5 options before acting.

How to apply these principles

When making a design decision, ask in order:

  1. Is it clear and transparent? Can the user understand what's happening without instructions? Are all costs and status visible upfront?
  2. Is it fast? Can we remove a step, pre-fill a field, or show info earlier?
  3. Does it work on constraints? Will it load on a 3G connection with a low-end phone?
  4. Is there one path? Are we adding complexity that could be a simpler flow?

If the answer to any question is no, redesign before shipping.

Resolving conflicts

The order is the tie-breaker. Two worked examples:

ConflictResolution
Showing the full fee breakdown adds a step (clarity vs. speed)Clarity wins — the breakdown stays, and speed is recovered by pre-filling the amount
A live rate chart helps users decide but costs 60KB (clarity vs. constraints)Clarity wins on the information, constraints win on the form — the rate comparison ships as text, not as a chart
Power users want a saved-recipient shortcut (speed vs. one path)One path wins — instead of a second flow, the existing flow pre-fills the last recipient

What these principles are not

They are not a style guide, and they do not decide visual questions. A principle cannot tell you which radius to use — that is what Tokens is for. If a debate about a component can be settled by a token, it is not a principles question.