BESBanking Experience System
Docs Components Journey Showcase
Draft — not yet human-verified. Every gate passing here is automated. No screen-reader, Arabic native-speaker or usability testing has been carried out yet, and all Arabic UI copy is machine-drafted. What has and hasn't been verified
Core components

10 — Core Components: Navigation

Banking Experience System (BES) · Core Components · v2.0.0-draft

Live example

214 transactions this quarter.
✓ Amount 2 Recipient 3 Review 4 Done
Code
<div class="demo-stack" style="max-width:560px">
  <div>
    <div class="bes-tabs" role="tablist" aria-label="Account sections">
      <button class="bes-tab" role="tab" aria-selected="true" aria-controls="dp-1" id="dt-1">Transactions</button>
      <button class="bes-tab" role="tab" aria-selected="false" aria-controls="dp-2" id="dt-2" tabindex="-1">Details</button>
      <button class="bes-tab" role="tab" aria-selected="false" aria-controls="dp-3" id="dt-3" tabindex="-1">Statements</button>
    </div>
    <div id="dp-1" role="tabpanel" aria-labelledby="dt-1" style="padding:12px 2px;font-size:14px;color:var(--bes-text-secondary)">214 transactions this quarter.</div>
    <div id="dp-2" role="tabpanel" aria-labelledby="dt-2" hidden style="padding:12px 2px;font-size:14px;color:var(--bes-text-secondary)">IBAN, SWIFT and account facts.</div>
    <div id="dp-3" role="tabpanel" aria-labelledby="dt-3" hidden style="padding:12px 2px;font-size:14px;color:var(--bes-text-secondary)">Monthly statements, PDF and CSV.</div>
  </div>
  <div class="bes-stepper" aria-label="Progress: step 2 of 4">
    <span class="bes-step bes-step--done"><span class="n">✓</span> Amount</span>
    <span class="bes-step-bar"></span>
    <span class="bes-step bes-step--current"><span class="n">2</span> Recipient</span>
    <span class="bes-step-bar"></span>
    <span class="bes-step"><span class="n">3</span> Review</span>
    <span class="bes-step-bar"></span>
    <span class="bes-step"><span class="n">4</span> Done</span>
  </div>
</div>

Components: App Bar (top) · Bottom Navigation · Side Navigation · Tabs · Segmented Control · Breadcrumb · Pagination · Stepper (Progress) · Language Switcher · Session Bar.


App Bar (Top)

Anatomy: back/close at inline-start · title (screen question, e.g. "Send money") · contextual actions at inline-end (≤2 + overflow) · optional subtitle (account context: "From Current account ••4521").

States: default · scrolled (elevation on) · contextual (in-flow variant locks navigation to Back/Cancel only).

Usage: in money flows the bar shows step context ("Send money · Step 2 of 4") and Cancel behavior is explicit — cancelling a DRAFT asks nothing; cancelling past AUTHENTICATION confirms ("Your transfer hasn't been sent. Leave anyway?").

A11y: title is the page heading (h1); back has accessible name naming the destination ("Back to Payees").

RTL: back chevron mirrors and sits at inline-start (visual right in Arabic); title alignment start.


Bottom Navigation (mobile)

Anatomy: 4–5 destinations: icon + label (labels always visible — icon-only bottom nav is banned) · badge slot (approvals count, unread).

Default retail set: Home · Payments · Cards · Hub (Products/More) · Profile. SME set: Home · Payments · Approvals · Accounts · More.

States: active (filled icon + action.primary tint) · inactive · badge (numeric ≤99, then "99+").

Usage: persistent across top-level destinations; hidden inside money flows (flows are modal journeys with the App Bar contract).

A11y: tab-bar semantics; active announced; badges included in name ("Approvals, 3 pending").

RTL: order mirrors (first destination at visual right).


Side Navigation (desktop / SME / corporate)

Anatomy: product switcher region · sections with headers · items (icon + label + badge) · collapse toggle · footer (settings, language, session).

States: expanded · collapsed (icons + tooltips) · item active/hover/focus · section collapsed.

Financial: corporate surfaces pin Approvals with live count; entity/company switcher at top for multi-entity users, with the active entity always visible ("Al Noor Trading LLC — AED accounts").

A11y: landmark nav with label; collapse state persists; keyboard operable throughout.

RTL: docks at inline-start (visual right in Arabic); collapse chevrons mirror.


Tabs

Anatomy: tab list · tabs (label + optional count) · active indicator · panels.

States: active · inactive · hover · focus · disabled (avoid; explain emptiness inside the panel instead).

Usage: peer views of one object (Account: Transactions / Details / Statements). Never for sequential steps (that's Stepper) and never nested two-deep.

Financial: counts on tabs reflect filtered results ("Pending (3)"); tab state preserved on back-navigation.

A11y: tablist pattern, arrow-key navigation, panel labeled by tab.

RTL: order and active-indicator animation mirror; horizontal scroll (if overflowing) starts from inline-start.


Segmented Control

Anatomy: 2–4 segments, equal width, single selection.

Usage: view toggles within one dataset (AED / USD display; List / Chart; Monthly / Yearly). Not for navigation, not for actions.

States: selected · unselected · focus · disabled.

A11y/RTL: radiogroup semantics; order mirrors; selection thumb animation mirrors.


Breadcrumb (desktop, deep hierarchies)

Anatomy: links + separator chevron · current page (non-link).

Usage: SME/corporate/back-office depth ("Payments › Bulk payments › July payroll › Payment 41 of 60"). Consumer mobile never shows breadcrumbs.

A11y: nav landmark "Breadcrumb"; current page marked.

RTL: chevrons mirror; order mirrors.


Pagination

Anatomy: prev/next · page numbers or range readout ("41–60 of 214") · optional page-size select.

Usage: desktop tables. Mobile lists use progressive loading with an explicit "Load more" (auto-infinite scroll is banned on transaction lists — it breaks "find the receipt from March" tasks and footer reachability).

Financial: table pagination preserves filters/sort in URL/state; exports respect the filtered set, stated ("Export 214 filtered transactions").

A11y: current page announced; range readout is live text.

RTL: prev/next mirror.


Stepper (Progress)

Anatomy: steps (number/check + label) · connectors · current highlight; horizontal (≤4 visible steps) or compact "Step 2 of 4" text form (mobile default).

States per step: complete (check) · current · upcoming · blocked (with reason) · error (needs revisit).

Usage: every multi-step financial journey ≥3 steps shows position; steps are nouns ("Amount", "Review") not verbs; completed steps are tappable to revisit before AUTHENTICATION, locked after.

A11y: list semantics with state per step ("Step 2 of 4, Amount, current step").

RTL: flows inline — visual right-to-left in Arabic; connector/animation mirror; checkmarks unmirrored.


Language Switcher

Anatomy: globe icon + current language label ("العربية" shown in Arabic when the UI is English, and "English" in English when the UI is Arabic — each language named in itself, always).

Usage: available pre-login and in Profile; switching swaps language and direction live, preserving screen position and any draft state; never resets a flow.

A11y: announces the switch; lang attributes update so screen readers change voice.


Session Bar (security navigation)

Anatomy: timeout countdown region (appears at T-60s: "You'll be signed out in 0:59 — Stay signed in") · sign-out control · last-login note on Home ("Last sign-in: yesterday 21:14, Dubai").

States: hidden · warning · expired (route to the Session Expired page, doc 25, preserving safe drafts).

A11y: countdown is a polite live region; "Stay signed in" is keyboard-first reachable; expiry never silently discards a payment draft (restored after re-auth with explicit confirmation).


All components in this family — live

Every component from this specification, rendered by the coded library. Expand "Code" to copy the markup.

Breadcrumb & pagination

41–60 of 214
Code
<div class="demo-stack">
  <nav aria-label="Breadcrumb"><ol class="bes-breadcrumb">
    <li><a href="#">Payments</a></li><li><a href="#">Bulk payments</a></li><li><a href="#">July payroll</a></li><li aria-current="page">Payment 41 of 60</li>
  </ol></nav>
  <div class="bes-pagination">
    <button class="bes-btn bes-btn--secondary bes-btn--sm">Previous</button>
    <span class="range"><bdi class="bes-amount">41–60</bdi> of <bdi class="bes-amount">214</bdi></span>
    <button class="bes-btn bes-btn--secondary bes-btn--sm">Next</button>
  </div>
</div>

Segmented control

Code
<div class="demo-row">
  <div class="bes-seg" role="group" aria-label="View as">
    <button aria-pressed="true">List</button><button aria-pressed="false">Chart</button>
  </div>
  <div class="bes-seg" role="group" aria-label="Currency display">
    <button aria-pressed="true">AED</button><button aria-pressed="false">USD</button>
  </div>
</div>

Bottom navigation (mobile pattern)

●
Home
○
Payments
○
Cards
○
Approvals3
○
Profile

Labels always visible; badges included in the accessible name; order mirrors in RTL.

Code
<div style="max-width:390px;border:1px solid var(--bes-border-default);border-radius:14px;overflow:hidden">
  <div style="display:flex;background:var(--bes-surface-primary);border-block-start:1px solid var(--bes-border-default)">
    <span style="flex:1;text-align:center;padding:10px 0 12px;color:var(--bes-action-primary);font-size:11px;font-weight:600">●<br>Home</span>
    <span style="flex:1;text-align:center;padding:10px 0 12px;color:var(--bes-text-secondary);font-size:11px;font-weight:500">○<br>Payments</span>
    <span style="flex:1;text-align:center;padding:10px 0 12px;color:var(--bes-text-secondary);font-size:11px;font-weight:500">○<br>Cards</span>
    <span style="flex:1;text-align:center;padding:10px 0 12px;color:var(--bes-text-secondary);font-size:11px;font-weight:500;position:relative">○<br>Approvals<span class="bes-badge bes-badge--error" style="position:absolute;inset-block-start:4px;inset-inline-end:14px;padding:1px 6px;font-size:10px">3</span></span>
    <span style="flex:1;text-align:center;padding:10px 0 12px;color:var(--bes-text-secondary);font-size:11px;font-weight:500">○<br>Profile</span>
  </div>
</div>
<p style="font-size:13px;color:var(--bes-text-secondary);margin:10px 0 0">Labels always visible; badges included in the accessible name; order mirrors in RTL.</p>

Session bar — timeout warning

You'll be signed out in 0:59

Appears at T-60s; expiry never silently discards a payment draft — it's restored after re-auth.

Code
<div class="bes-banner" style="border-radius:10px;border:1px solid var(--bes-border-default);justify-content:space-between">
  <span>You'll be signed out in <bdi class="bes-amount">0:59</bdi></span>
  <button class="bes-btn bes-btn--primary bes-btn--sm">Stay signed in</button>
</div>
<p style="font-size:13px;color:var(--bes-text-secondary);margin:10px 0 0">Appears at T-60s; expiry never silently discards a payment draft — it's restored after re-auth.</p>