Design System

Foundations

Typography

The complete set, grouped by typeface and ordered by size. Each style names itself: the left column is set in the style it describes, so every title label renders in its documented style. Specimens are shown in full ink, with one exception: the caps subtitles carry their own colour, because they have no other — they are never set in anything but --mk-text-label. The page is built from what it documents — group heads are H3 title in Inter, spec heads are Subtitle 2, and notes are Body 14px. Every caps label tracks at .1em, one value, and body sits at 350 — the full variable Inter arrived on 29 July, and the subset before it clamped anything under 400 without saying so. Settled with Ihor on 29 July and applied to the pages the same day: 11px, 12px, 15px, 17px and the oversized 40px record title no longer exist in the workspace. The working sizes are 13, 14, 16, 18, 20, 24 and 28. Cormorant is not a heading ladder: it is reserved for the single title at the top of a page; every title below it is Inter.

The scale

Titles

H1 title

Cormorant 600, 36px

The top-level title of an overview or foundational start page.

H2 title

Cormorant 600, 28px

The title at the top of a component or record page.

H3 title

Inter 600, 24px

The step between a page title and a name inside a card.

H4 title

Inter 600, 20px

A named section or object inside the page.

H5 title

Inter 600, 18px

A compact panel, widget, route, or stay title.

Titles (Sans serif)

H1 title

Inter 600, 24px

The heading of a step that owns the screen: starting an itinerary, choosing the date and rate.

H2 title

Inter 600, 20px

A group head that gathers rows beneath it, and an itinerary’s own name in a card. The itineraries list is built on this one.

H3 title

Inter 600, 18px

Widget heads and dialog headings. Dialogs were inheriting the browser’s bold, which Inter has to fake — it carries 400 to 600 and no more.

Subtitles (Uppercase)

Subtitle 1

Inter 500, 16px, .1em, uppercase

One use only: the day marker in the builder schedule. It labels a whole day rather than a field, so it is set larger. Same ink as every other caps label — it stood in full black until 29 July, which made the schedule the one place a caps subtitle changed colour.

Subtitle 2

Inter 500, 14px, .1em, uppercase

The primary caps subtitle is shown in its own --mk-text-label colour, a step darker than the secondary grey. Section titles in a record, table column heads, card kickers and the marker on a nav entry use it.

Subtitles (Sentence case)

Subtitle 1

Inter 600, 16px

The line a row is scanned by — a guest in the queue, a service in a day, the dates of a stay — and the answer half of a fact in a roomy row.

Subtitle 2

Inter 600, 14px

The same weight in a dense row, and the chosen item in a menu.

Controls

One VOICE — Inter 500, no tracking — for anything a hand acts on and the words that name it. The size is not part of the voice: it follows the control’s own size, three steps of it.

Control label, 16px

Inter 500, 16px

The XL button — the one act a start page is about.

Control label, 14px

Inter 500, 14px

The working size: buttons small through large (their sizes differ in height and padding, the label holds), nav entries, the value on a select face, a field’s label, a status badge. The workspace’s second-most-set style; undocumented until 29 July, which is how it came to run at three different trackings — .02em on buttons, .01em on badges, none on nav. It has one now: none.

Control label, 13px

Inter 500, 13px

The small badge only.

Body

Body, 16px

Inter 350, 16px

Roomy rows and single-column reading.

Body, 14px

Inter 350, 14px

The default of the whole workspace and the most-set style in it — rows, fields, sublines, help. This is the default, not 16px.

Tokens and code

--mk-surface

Roboto Mono 400, 14px

--mk-font-code

Token names, class names and code samples in design-system documentation. It is notation, not a product text style.

The neutral inks, ground by ground

Not a new type style — both body sizes in the two working voices, on each ground the workspace actually paints. Body (--mk-text-muted, 0.88) carries everything that IS — names, values, notes, sublines; Quiet (--mk-text-quiet, 0.68) states what is not there — an empty state, a thing not added yet — and stays conspicuously greyer on purpose. The full ink retired as a voice on 08-01: nothing sets it as text any more, it lives on only as the base the registers derive from. Ratios are measured, not estimated, and each carries its WCAG grade for text at these sizes: AA clears 4.5:1, AAA clears 7:1.

Body, 16px — 16.56:1 (AAA)

Body, 14px — 16.56:1 (AAA)

Quiet, 16px — 5.72:1 (AA)

Quiet, 14px — 5.72:1 (AA)

Card

--mk-surface

Cards, tables, panels — where most of the workspace’s text lives, and the ground the greys were tuned against.

Body, 16px — 15.85:1 (AAA)

Body, 14px — 15.85:1 (AAA)

Quiet, 16px — 5.59:1 (AA)

Quiet, 14px — 5.59:1 (AA)

Raised

--mk-surface-raised

A well inside a surface: inputs, empty states. The quiet register’s natural home — an empty state sits on raised, and its words are about an absence. Loses 2.3% against the card: invisible, so it takes no ink of its own.

Body, 16px — 15.40:1 (AAA)

Body, 14px — 15.40:1 (AAA)

Quiet, 16px — 5.50:1 (AA)

Quiet, 14px — 5.50:1 (AA)

Page

--mk-page

The ground itself — text sits straight on it between the cards: a page head’s subline, a foot note. Loses 3.7% against the card — still invisible, still no ink of its own.

Body, 16px — 14.83:1 (AAA)

Body, 14px — 14.83:1 (AAA)

Quiet, 16px — 5.06:1 (AA)

Quiet, 14px — 5.06:1 (AA)

Sunken

--mk-surface-sunken

Bands and table heads — and the one neutral ground that does NOT show the plain body grey. It loses 11.4% against the card, which is what a status tint costs, so the band hands its body text the tint step (--mk-text-on-tint, shown above) — the same hand-down the status tints get in the next row; the unstepped grey would arrive at 13.19:1. Quiet keeps its own value — an absence does not darken to compete.

Body, 16px — 15.76:1 (AAA)

Body, 14px — 15.76:1 (AAA)

Quiet, 16px — 5.22:1 (AA)

Quiet, 14px — 5.22:1 (AA)

Success

--mk-success-tint

The same two voices on a coloured ground. Body here IS the stepped token — the panel re-points --mk-text-muted: var(--mk-text-on-tint) (a tint costs the ink what the sunken band costs; unstepped, body would arrive at 13.93:1) with .mk-tinted as the ready-made carrier, so body copy, a currency, a note and whatever is added next inherit the step without knowing they sit on a tint. Quiet holds its own value, as on the sunken band. Coloured ink needs none of this: --mk-warning-text and its siblings document their own on-tint ratio.

Body, 16px — 15.44:1 (AAA)

Body, 14px — 15.44:1 (AAA)

Quiet, 16px — 5.17:1 (AA)

Quiet, 14px — 5.17:1 (AA)

Warning

--mk-warning-tint

Same rule; the tint changes, the registers hold. Unstepped body would arrive at 13.68:1.

Body, 16px — 14.60:1 (AAA)

Body, 14px — 14.60:1 (AAA)

Quiet, 16px — 5.03:1 (AA)

Quiet, 14px — 5.03:1 (AA)

Error

--mk-error-tint

Same rule. Unstepped body would arrive at 13.00:1.

Figures and money

Figures

Saturday, 14 November

Date figure

.mk-schedule-date

Inter 500, 24px, tabular. The schedule date is a numeric scanning anchor with its own figure style. It does not modify or replace the 24px/600 Inter title.

Price

OMR4,444

Inter 650, 20px · currency 18px

The money figure: a total, and a line price on a card. The largest an amount goes. The currency is not a style of its own — it is the second half of this one, and it steps 2px under it — but never below 13px, where it stops being readable. Set the size on .mk-price and the currency follows by max(13px, calc(1em - 2px)).

OMR4,444

Inter 650, 18px · currency 16px

The step between a card’s own total and the figure a payment step is about — a price that leads its card without being the page’s largest number.

OMR4,444

Inter 650, 16px · currency 14px

The figure a payment step is about — a deposit, a balance.

OMR4,444

Inter 650, 14px · currency 13px

A line inside a summary: rooms, services, taxes. It ran at 600 here and 650 on a card until 29 July — one figure, one weight.

The wordmark descriptor

A decorative brand piece, not a step of any scale — it lives apart from the subtitles on purpose.

Reservation Workspace

Intervogue 400, 13px, .1em, uppercase

It sets ONE element: the centred line under the sidebar wordmark, in the brand’s own capitals. Nothing on any page may take it. The 13px is not a free choice either — it is the largest size that fits the 195px brand block, 14px overflows it by 3px, and it fits at all only because Intervogue runs narrower than Inter. That width is what held this line at 12px until 31 July.

Guest surface

A different system, on purpose. The landing page is editorial and fluid: Cormorant carries the single page-opening title and editorial body, while Intervogue carries the titles below it and every label. Sizes move with the viewport. Measured at 1440px. The boundary is deliberate — the mid-office may not borrow Intervogue.

H1 title

Cormorant 600, 56px

The guest title, once.

H2 title

Intervogue 400, 54px

A chapter opening on a place. Sans-serif because it sits below the page title.

H3 title

Intervogue 400, 34 to 36px

A section heading. Fluid across the range.

H4 title

Intervogue 400, 26px

A moment inside a day.

OMR 16,092

Cormorant 500, 25px

The summary band. Lining figures, now set once for every page rather than per style.

H5 title

Intervogue 400, 21 to 23px

Offered experiences and comfort cards.

Lead

Cormorant 500, 21 to 25px

The opening voice of a section.

Body

Cormorant 500, 18px

The guest reads serif throughout. The workspace never does.

Eyebrow

Intervogue 400, 17px, .24em

Chapter and lead eyebrows.

Day label

Intervogue 400, 15px, .22em

The spine of the itinerary.

Label

Intervogue 400, 14px, .22em

Section eyebrows, moment times, summary keys and the pay action. The keys were 12px and now join the rest here.