Design system

Every component, in both registers. The rules live in docs/DESIGN-DOCTRINE.md; this page is the evidence they are followed.

1 · Two registers

A stranger must be able to say "guest-facing" or "staff-facing" in one second, without reading.

Desk — the working surface
Booking EC-2931
Riverbend Cottage · 18–20 Sep · 6 guests
Total18,500
Received5,000
=
Due13,500

6px radius · no shadow · hairlines · 13.5px · rows 36px · hover instant

Lobby — leaves the building
Your stay is confirmed
Riverbend Cottage, 18–20 September. We will have the barbecue ready.

20px radius · cream ground · serif ≥22px · generous · the hill-contour rule

2 · Colour

90 / 8 / 2

Brand — Hill Green

Active nav, the one primary action, the focus ring, the logo. Never status, never charts, never decoration.

--brand-50
--brand-100
--brand-200
--brand-400
--brand-600
--brand-700
--brand-800

Neutral — Stone

Carries 90% of every Desk screen.

--n-50
--n-100
--n-200
--n-300
--n-400
--n-500
--n-600
--n-700
--n-800
--n-900
--n-950

Status — not the brand

D-007: success used to be byte-identical to the brand green, so brand, confirmed and paid were indistinguishable in a table full of money.

--st-teal-600
--st-emerald-600
--st-amber-600
--st-red-600
--st-blue-600

Data visualisation

--viz-1
--viz-2
--viz-3
--viz-4
--viz-5
--viz-6

3 · Typography

3 families · Archivo, Instrument Serif (Lobby only), Hind Siliguri
SpecimenTokenRegisterUse
Ecoza Hill Retreat --t-lobby-xlLobbyLogin hero, invoice title
Ecoza Hill Retreat --t-lobby-lgLobbyDay-sheet header, confirmation
Ecoza Hill Retreat --t-lobby-mdLobbyDocument section head, empty state
Ecoza Hill Retreat --t-head-lgDeskPage H1, drawer title
Ecoza Hill Retreat --t-head-mdDeskCard title, modal title
Ecoza Hill Retreat --t-head-smDeskField-group header
Ecoza Hill Retreat --t-body-lgBothModal body, side note
Ecoza Hill Retreat --t-bodyDeskDefault — table cells, forms
Ecoza Hill Retreat --t-body-smDeskHelper text, meta
Ecoza Hill Retreat --t-labelDeskForm labels
Ecoza Hill Retreat --t-captionDeskFootnotes, attribution
Ecoza Hill Retreat --t-overlineDeskTable headers, nav groups
৳1,25,000 --t-num-heroBothThe Due figure
৳1,25,000 --t-num-lgBothKPI values
৳1,25,000 --t-numDeskMoney in tables
EC-2931 --t-refBothEC-2931

Bengali

Guest names and side notes are usually Bengali. lang="bn" switches family and adds 1px.

মুরগির বদলে গরুর মাংস দিবেন, গ্রোসারি সব লাগবে না।

4 · Status

Never brand green. Colour is never alone.

Each state carries a shape — filled dot, hollow ring, bar, slash — so it survives greyscale, colour-blindness and the printed day sheet.

Draft Pending Confirmed Checked in Checked out Completed Cancelled No show Unpaid Partial Paid Refunded
Draft Pending Confirmed Checked in Checked out Completed Cancelled No show Unpaid Partial Paid Refunded

The same set in greyscale. Still readable — that is the test.

5 · Buttons

One primary per view
Disabled controls always carry the reason.

6 · Fields

Already has a booking 12–14 Sep. Same guest?

7 · Feedback

Empty state

No bookings between 1–7 Aug.

Widen the dates, or clear the status filter.

Names what is missing, why, and the one action that fixes it. Never "No data found".

8 · Motion

Four, and that is the whole list
WhatHowDuration
Overlay enteropacity 0→1 + scale .97→1180ms
Overlay exitopacity 1→0120ms
Drawer slidetranslateX 24px→0260ms
Skeleton shimmerlooping opacity1400ms
Hover, focus, activeno transition0ms

A 150ms hover lag on a 40-row table feels like mud to someone scanning it 200 times a day. Nothing animates while a number is being edited.

9 · Don't

  • No A card inside a card, or more than one shadow per region
  • No A row of three equal KPI cards
  • No Brand green on a status badge
  • No A gradient standing in for a photograph
  • No The serif on a Desk screen, or below 22px
  • No A blank cell where a value is missing — use —
  • No transition: all, anywhere
  • No Raw hex or raw px in page CSS
  • No Emoji in chrome, "Oops!", "No data found"