Azora Design System
Tokens and components extracted from the live Azora ERP — colors, type, spacing and every confirmed UI pattern, in one reference page.
Azora is the back-office ERP used to run Semicolon's travel, tourism and fleet products (profiles/tourist files, quick services, invoicing, daily program scheduling, CRM dashboards). This system was extracted directly from screenshots of the live application — not invented. Where a value could not be read exactly from a screenshot (a couple of chart hues), the closest reasonable match is used and called out so it can be swapped for the real asset later.
Principles
- Orange carries action. Every primary call-to-action — Add Profile, Pay/Invoice, Invoice, Create Invoice, the stepper's current step, the floating settings control — uses the same brand orange. If it's orange, it's the thing to click next.
- Dark navy is the quiet alternative. Advanced Filter and other secondary/utility actions sit on a near-black navy, never on orange, so the primary action always reads first.
- Status lives in pills, not in page chrome. Pending, Confirmed, Draft and the profile stepper (Pending → Confirmed → Done → Cancel) use a small, consistent vocabulary of filled pill colors, repeated identically across tables, badges and the stepper itself.
- White cards float on a cool, light-gray canvas.
surface-pageis never used for content; every table, form and summary panel sits in asurface-cardblock with a soft shadow and a 1px hairline, keeping dense data screens legible. - Numbers are the hero on the dashboard. Insight tiles and chart totals use the largest, boldest type on the page — bigger than any heading — so KPIs can be read at a glance.
Typography — confirmed
Azora is set in two web fonts split by page direction: the Arabic/RTL build uses Cairo (font-family: Cairo, sans-serif); the English/LTR build uses Roboto (font-family: Roboto, sans-serif). Pick the family by the page's direction, not by device or OS.
Bidirectional layout (RTL/LTR)
Azora ships full RTL, not just translated strings.
- Mirrored chrome. The sidebar, notification bell and account menu flip from the left edge (English) to the right edge (Arabic); the page title and breadcrumb right-align; card internals mirror too.
- Numerals, dates and currency stay LTR inside RTL rows. Table cells like
AZora-2026-10-26-54, a date, or a price, are embedded left-to-right even inside a right-aligned Arabic row. - Color, spacing and radius tokens are direction-agnostic. Only layout mirrors; build components with logical CSS properties rather than hard-coded left/right.
Iconography
Azora draws its icons from two libraries — Tabler Icons (the default, line-style set: sidebar nav, table actions, form field icons) and Font Awesome 6 (the rest of the inventory). Both are outline/line-weight sets at 16–24px, always drawn in a single currentColor-style ink — never multicolor.
2026-10-26 accessibility pass
Two tokens carrying white text were found to fall short of the 4.5:1 contrast minimum and were given fixes: success-strong (darker than success) for any success surface with white text/icons — the success toast now uses it; and button-disabled-bg itself was darkened (from its originally sampled #f3a282 to #c34513) since the captured value measured only ~2.0:1 with white text, now ~5.0:1.
Logo
The real logo is in this system as an asset — the clean, official logo file. Its colors (logo-mark-blue, logo-wordmark-start/-end) are pixel-sampled directly from it.
Color tokens
Surfaces
Borders
Ink / Text
Brand
Status pills
Controls
Success (toast)
Category tiles
Buttons
Logo
Charts
Error
Typography
Arabic/RTL build: Cairo, sans-serif. English/LTR build: Roboto, sans-serif.
| Style | Size | Line height | Weight | Usage |
|---|---|---|---|---|
Display / page-title | 28px | 34px | 600 | Top-of-page titles ("Tourist File", "Add Profile") |
Heading / section | 20px | 26px | 700 | Section headers ("Profile Info") |
Heading / card-title | 16px | 22px | 700 | Card and widget titles ("Money Summary") |
Body / body | 14px | 20px | 400 | Default paragraph and table cell text |
Body / body-strong | 14px | 20px | 600 | Emphasised values, field values, button labels |
Label / field-label | 13px | 18px | 500 | Form field labels ("Arrival Date") |
Label / table-header | 12px | 16px | 600 | Table column headers |
Numeral / stat-value | 30px | 36px | 700 | Dashboard insight numbers |
Spacing & radius
Spacing
space-14pxspace-28pxspace-312pxspace-416pxspace-520pxspace-624pxspace-832pxspace-1040pxRadius
radius-sm6pxradius-md10pxradius-lg16pxradius-full999pxComponents
Button
ActionsFilled action buttons in Azora's two emphasis levels, plus a lower-emphasis outline for menu items.
- Primary (brand orange, white text) is the only filled-orange control on a screen at a time where possible — it marks the single next action.
- Secondary (dark navy, white text) is for a utility action that sits next to a primary one without competing for attention.
- Outline — neutral (transparent,
border-subtle,ink-700text) is for actions inside dropdown menus and toolbar icon buttons. - Outline — primary (white fill,
brand-orange1.5px border,brand-orangetext) is a lower-emphasis sibling to the solid primary button. - Destructive — solid (
errorfill, white text) is for an irreversible action presented as its own clear button rather than a menu item.
All three share one 10px radius, one 14px/600-weight label, and a 0.15s background transition.
Disabled primary — confirmed: a lightened button-disabled-bg with white text — not a gray button on the page background. Keep the white text; only the fill desaturates.
Badge
FeedbackSmall, fully-rounded, filled pills used for every status in the product: the Profiles list, the Last Bookings table, and the profile detail status stepper.
Four fixed pairs — never mix a background from one status with another status's text color:
| Status | Background | Text |
|---|---|---|
| Pending | status-pending-bg | status-pending-ink |
| Confirmed | status-confirmed-bg | status-confirmed-ink |
| Draft | status-draft-bg | status-draft-ink |
| Confirmed / success (list rows) | status-success-bg | status-success-ink |
12px/600-weight label, space-1–space-2 vertical padding, space-3 horizontal padding, radius-full. These are never outlined — fill is what makes them scannable in a dense table.
A second, softer badge style exists for operational/availability states:
| State | Background | Text |
|---|---|---|
| Available | status-available-bg | status-available-ink |
StatCard
Data displayThe KPI tile used in the Dashboard's Insights row. A white card on surface-page, shadow-card, radius-md, space-4 padding: a label row at the top in ink-500/field-label style, then the number in stat-value (largest type in the system) in ink-900, and an optional one-line caption.
Keep captions to a single short sentence. The number is always the visual anchor of the card.
DataTable
Data displayThe dense list pattern that carries most of Azora's screens. A surface-card container with shadow-card and radius-md, a table-header row (ink-500, 12px/600) on a hairline bottom border, and body rows in body/14px with space-3 vertical padding and the same hairline between rows — no zebra striping.
Row content follows a consistent order: an identifier/link column (brand-orange text link), one or more plain data columns, a Badge status column, and a trailing actions column. Selectable tables add a checkbox column at the far left.
StatusDonut
Data displayThe four-segment ring from the Dashboard's "Profiles Processing" / "معالجة الملفات" widget: one donut per status (Pending, Confirmed, Done, Cancel), each shown as its own small ring with the percentage inside and a "Count: N" caption underneath.
Uses its own four-color set (chart-status-pending…chart-status-cancel), not the status-* pair used by table badges.
Toggle
ActionsThe on/off switch used as a row-level active/inactive control in every list table — Hotels, Drivers, Last Profiles. On uses control-on (same orange as every primary button); off uses control-off, a mid-gray track. radius-full track and thumb, white thumb, no label text beside it.
Reserve this for a direct, immediate toggle. For a workflow state that moves through steps, use the Badge or the profile-detail stepper instead — never a Toggle.
Toast
FeedbackThe product's confirmed toast pattern: a solid rectangle, bold white text, fixed to the top-right of the viewport, radius-sm corners. Two outcomes are confirmed — error (error background) and success (success-strong background, the "Updated successfully" toast on the Users page).
- Solid
error/success-strongbackground, never a soft tint. - Uses
success-strong, not the basesuccesstoken: white text on plainsuccess(#1fa971) measures under the 4.5:1 minimum (~3.0:1), so any text-bearing success surface should reach forsuccess-stronginstead. - Stack new toasts above older ones with a small (
space-2) gap; each keeps its own dismiss control. - Known bug, not a pattern: the captured second toast renders a raw i18n key (
general.changeStatusError) instead of translated text.
CategoryTile
NavigationThe row of pastel quick-link tiles at the top of the Users page: an icon + label on a soft, category-colored background, same-hue dark text, no border or shadow.
Four fixed pairs, one per report category:
| Tile | Background | Text/icon |
|---|---|---|
| Cashbox Statement | category-peach-bg | category-peach-ink |
| Invoice Report | category-slate-bg | category-slate-ink |
| Payment Vouchers | category-blue-bg | category-blue-ink |
| Services Report | category-mint-bg | category-mint-ink |
WizardStepper
NavigationThe horizontal numbered stepper used to navigate a multi-step form — Add Profile, Edit User. Distinct from the Badge stepper on a profile's detail page: this one is circles-and-connecting-line, for moving through a form.
- Each step is a numbered circle: current and completed steps are filled
brand-orangewith white text; upcoming steps are an outline circle. - The connecting line is
brand-orangeup through the current step, thenborder-strongfor the rest. - The step's label sits above its circle.
FileUpload
FormsThe attachment dropzone from the Hotel Reservation form's Attachments section: a large dashed-border rectangle, border-strong, radius-md, centered cloud-upload icon in ink-500 and "Drag and drop, or click to upload file" in body size, ink-500.
Pairs with a required-field asterisk on its label like any other FormField, and with a disabled-primary button underneath until a file is actually attached.
ChoiceCard
FormsThe pill-shaped radio selector used for binary either/or choices in the Car Rental wizard, always presented as two large pill cards side by side.
- Unselected:
surface-cardbackground,border-subtle1px border, hollow gray radio dot,ink-700label. - Selected:
brand-orange-softbackground,brand-orange2px border, a filledbrand-orangeradio dot (white center),ink-900bold label. - A small icon sits in its own white, rounded-square chip at the card's outer edge.
- Confirmed RTL-native: radio dot and label sit at the trailing (right) edge in Arabic, the icon chip at the leading (left) edge.
Tabs
NavigationThe underline tab bar used to switch sections of a record's detail page.
- Active tab:
brand-orangetext and icon, bold, a 3pxbrand-orangeunderline spanning the full width of that tab segment. - Inactive tab:
ink-500text and icon, no underline. - A thin
border-subtleline runs under the whole bar. - Tabs are numbered in the label itself ("1. Overview") when they represent a fixed sequence.
- Different from WizardStepper: tabs are peer sections of one finished record a person jumps between freely; WizardStepper is a forward-moving, not-yet-complete multi-step form.
Checkbox
FormsThe row-selection checkbox used in every DataTable: unchecked is a border-strong outline square on surface-card; checked is a solid brand-orange square with a white checkmark, radius-sm corners. The header's select-all control uses the same filled-orange square with a short white dash when the selection is partial.
FormField
FormsThe labeled text input used throughout every "Add…" form: a field-label above a surface-card input with a border-subtle 1px border and radius-sm corners. A required field adds a small error asterisk.
Asterisk position is inconsistent in the product itself: most forms put it after the label text (Name *), but the Hotel Reservation form puts it before (* Check in).
The invalid-field error state: the input's border stays neutral (border-subtle), not error — only one line of error-colored helper text appears directly under the input. Nothing about the label or the input's background changes either way.
AuthLayout
NavigationThe public login screen's split layout — the one surface in the product that isn't the app's internal chrome.
- Left panel (~1/3 width,
surface-pagebackground): the real Azora logo top-left, then "تسجيل الدخول" inpage-title, abody/ink-500subheading, two FormFields (email, password), a plain Checkbox + label ("عرض كلمة المرور" / Show password), and the submit button pinned to the panel's bottom. - Right panel (~2/3 width): a full-bleed photographic/illustration image, no text or UI on top of it.
- The submit button uses
button-disabled-bg, notbrand-orange, even though it's fully enabled and clickable — this is the login screen's own primary-button tone; don't "correct" it to brand-orange when matching this screen specifically. - 2026-10-26 update:
button-disabled-bg's token value was darkened from its originally sampled#f3a282to#c34513as an accessibility fix — white text on the captured pixel value measured only ~2.0:1, now ~5.0:1. - Inline validation here matches FormField's confirmed error pattern: neutral border, red helper text only.