Service · 02  /  Case: Officiti

Design Systems.

Build scalable design systems that ensure consistency across all touchpoints.

Below is a complete, working design system for Officiti, a B2B platform for sharing and booking workspace. It starts from the six colors and Roboto type scale in the original case study, then fixes accessibility gaps and adds tokens, components and patterns based on established UX laws and WCAG 2.2.

Version
1.0
Platforms
iOS · Android
Typeface
Roboto
Base grid
4 pt
Standard
WCAG 2.2 AA
01 · Principles

Six rules every decision is tested against.

Officiti serves working professionals who book desks, rooms and visitors on the go, often one-handed and in a hurry. These principles turn established UX research into constraints that the components below obey.

01

Clear before clever

Every element earns its place. Plain labels, generous space and one focal point per screen.

Minimalist design
02

Fewer choices, faster decisions

Break booking into short steps and reveal detail progressively. Keep menus to five items or fewer.

Hick's Law · Miller's Law
03

Within reach

Primary actions live in the thumb zone with targets of at least 48 px and 8 px between them.

Fitts's Law
04

Familiar patterns

Use platform conventions for navigation, forms and pickers so nobody has to learn Officiti first.

Jakob's Law · Consistency
05

Always show status

Respond within 400 ms, show progress for anything longer, and confirm every result in words.

Doherty Threshold · Visibility of status
06

Accessible by default

Contrast, focus, labels and touch size are built into each token and component, not added later.

WCAG 2.2 AA · Inclusive design
02 · Foundations · Color

Same brand, accessible in use.

The original style guide defined six colors. They are kept as the brand identity. Testing them against WCAG showed that several cannot carry text or white labels, so each gets a darker functional variant for text and controls.

Brand colors

Blue#5D6DFF
Red#E8553E
Amber#FFAE02
Ink#2D2D2D
Gray#BDBDBD
Green#89C053

Use brand colors for illustration, highlights, large graphics and date tiles. Use the functional scales below for text, icons and controls.

Functional scales

Primary / action
50#EEF0FF
100#E0E4FF
200#C4CBFF
300#A3ADFF
400#8290FF
500 · brand#5D6DFF
600 · action#4351E8
700#3A46D1
800 · pressed#2F3AB5
900#232C8C
Danger
50#FDECE8
100#FAD3CB
500 · brand#E8553E
600#C83E2A
700 · text#B5301E
800#8F2415
Success
50#EAF5DD
100#D5EBBB
500 · brand#89C053
600#3F7D1E
700 · text#2F6014
Warning
50#FFF4D6
100#FFE7A8
500 · brand#FFAE02
800 · text#7A5200
Neutral
0#FFFFFF
50#FAFAFA
100#F5F5F5
200#EBEBEB
300#D9D9D9
400 · brand#BDBDBD
500 · border#8A8A8A
600 · muted#6B6B6B
700 · body 2#5C5C5C
800#424242
900 · ink#2D2D2D

What changed from the case study, and why

UseWasNowReason
Buttons, links#5D6DFF#4351E8 (action-600)White text on #5D6DFF is 4.12:1, below the 4.5:1 minimum for 14 px text.
Error text, destructive#E8553E#B5301E text, #C83E2A fill#E8553E on white is 3.62:1. The darker steps reach 6.17:1 and 5.03:1.
Secondary and placeholder text#BDBDBD#5C5C5C / #6B6B6B#BDBDBD on white is 1.88:1 and was hard to read in ticket details.
Input bordersLight gray fill only#8A8A8A 1.5 px borderControls need 3:1 against the background to be found (WCAG 1.4.11).
Text on amber and greenWhiteInk #2D2D2DWhite on #FFAE02 is 1.86:1 and on #89C053 is 2.16:1. Ink reaches 7.42:1 and 6.38:1.
Status meaningColor onlyColor + icon + wordColor alone fails WCAG 1.4.1 and excludes color-blind users.

Contrast matrix (calculated live)

Normal text needs 4.5:1, large text and UI components 3:1, and AAA text 7:1.

PairSampleRatioAA textAA large / UIAAA text
03 · Foundations · Typography

Roboto, tuned for small screens.

Roboto stays as the single typeface. It is designed for mobile, has excellent numerals for times and dates, and ships in every weight the app needs. The original scale is kept and completed, with one change: the 10 px sizes are raised to 11 px because text under 11 px is hard to read on phones.

Aa
Roboto
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
Weights: Regular 400 · Medium 500 · Bold 700. The original "Semibold" maps to Medium 500, the closest Roboto weight.
Display
28 / 36 · Bold
Welcome back, Saagar
Title
20 / 28 · Bold
Create a meeting
Header
16 / 24 · Bold
The spectacle before us was indeed sublime.
Subheader
14 / 20 · Medium
The spectacle before us was indeed sublime.
Body / Button
14 / 20 · Regular, Medium
The spectacle before us was indeed sublime.
Label
12 / 16 · Bold
The spectacle before us was indeed sublime.
Caption
12 / 16 · Regular
The spectacle before us was indeed sublime.
Micro
11 / 14 · Medium (was 10)
The spectacle before us was indeed sublime.
  • Line height. At least 1.4 for body text (WCAG 1.4.12) so paragraphs stay readable.
  • Line length. Keep reading text to roughly 45 to 75 characters per line.
  • Scaling. Define sizes in rem or platform text styles so users' font settings and 200% zoom work.
  • Case. Use sentence case. Reserve uppercase for very short overlines.
  • Numbers. Use tabular numerals for times, prices and counts so columns align.
  • Hierarchy. Limit a screen to three type sizes so the eye finds the main point fast.
  • 04 · Foundations · Space, shape, elevation

    One 4-point grid, everywhere.

    Spacing scale
    space-1 · 4
    space-2 · 8
    space-3 · 12
    space-4 · 16
    space-5 · 20
    space-6 · 24
    space-8 · 32
    space-10 · 40
    space-12 · 48
    space-16 · 64

    Related items sit closer than unrelated ones. Use 8 inside a component, 16 between fields, 24 to 32 between groups.

    Touch target

    Interactive area is at least 48 × 48 px, even when the visible icon is 24 px. Keep at least 8 px between neighboring targets to prevent mis-taps (Fitts's Law, WCAG 2.5.8).

    Radius
    sm · 4
    buttons, inputs
    md · 8
    cards
    lg · 16
    sheets
    full
    avatars, FAB
    Elevation
    elev-1
    cards, inputs
    elev-2
    sticky bars, menus
    elev-3
    dialogs, FAB, toast
    05 · Foundations · Iconography

    One icon family, drawn on a 24 px grid.

    The original set (wifi, visitors, tickets, alerts, notifications, attachments, home, calendar, dropdown, more, support, lock, back) is redrawn as a consistent outline family with a 2 px stroke and round caps, and completed with the icons needed for status, search and scanning.

    wifi
    visitors
    ticket
    alert
    bell
    attach
    home
    calendar
    chevron
    more
    support
    lock
    back
    scan
    add
    check
    close
    pending
    location
    search
    info
    error
    entry
  • Sizes. 16 (inline with text), 24 (default), 40 (empty states).
  • Meaning. An icon that is not universal always gets a text label. Icon-only buttons need an accessible name.
  • Color. Icons inherit text color and follow the same contrast rules as text.
  • Consistency. Never mix filled and outline icons in one row. Active navigation uses a bolder label, not a different icon style.
  • 06 · Foundations · Layout grid

    Phones and tablets, two breakpoints.

    BreakpointWidthColumnsMarginGutter
    Phone360 to 76741616
    Tablet768 and up82424
    07 · Foundations · Motion

    Fast enough to feel instant.

    TokenTimeUse
    motion-fast100 msPress, toggle, selection
    motion-base200 msFields, chips, menus
    motion-slow300 msSheets, dialogs, toasts

    Easing is cubic-bezier(.2, 0, 0, 1): quick start, soft landing.

    Standard easing
  • Feedback under 400 ms. Anything slower shows a loading state (Doherty Threshold).
  • Motion explains. Animate to show where something came from or went, never as decoration.
  • Respect user settings. With reduced motion on, transitions are removed and state changes are instant.
  • No flashing. Nothing flashes more than three times per second.
  • 08 · Components

    Every component, live and interactive.

    These are real, working components built with the tokens above. Try them out and read the specs. Each states the UX rule behind it.

    Buttons

    Anatomy. 48 px high, 24 px side padding, 4 px radius, label 14/20 Medium.
    Hierarchy. One primary button per screen so the main action stands out. Secondary for alternatives, text for low-risk dismissals.
    Labels. Verb plus object: "Book meeting room", never "Submit" or "OK".
    States. Default, pressed, focus (3 px ring), disabled, loading. Loading keeps the label and sets aria-busy.
    Placement. On mobile, the primary action is full width and anchored at the bottom, inside the thumb zone.

    Form fields

    Keep it short. Attendees see this in their invite.
    States
    Default
    Focus
    Filled
    Enter a 10-digit mobile number, for example 9876543210.
    Disabled
    Labels above, always visible. Placeholders disappear and are low contrast, so they never replace a label (recognition over recall).
    Optional, not required. Mark the few optional fields instead of starring most fields. Ask only what is needed (Hick's Law).
    Errors. Inline, below the field, with an icon, red text and a fix: "Enter a 10-digit mobile number". Validate on blur, not on every key press.
    Specs. 48 px high, 1.5 px #8A8A8A border (3.45:1), 4 px radius, 12 px inside padding, focus ring in action color.
    Input help. Use native time and date pickers, autocomplete and correct keyboard types so people type less (Jakob's Law).

    Selection controls

    Select days
    My tickets
    Hit area. Each label row is 48 px high, so the entire row is tappable, not only the 22 px box.
    Selected state. Filled background plus a checkmark or dot, so it is clear without color. Switches also change their label wording where possible.
    Day chips. 40 px circles with 8 px gaps and full-day names for screen readers. Segmented control uses ink (#2D2D2D) for the active tab, as in the original design.

    Cards and status

    20Dec
    Officiti App Demo
    Office building · 1:00 pm to 2:00 pm
    SSMMAK+2 Upcoming
    22Dec
    Wi-Fi not connecting
    Ticket #1042 · Resolved
    Resolved
    23Dec
    Projector needs a cable
    Ticket #1047 · Pending review
    Pending
    22Dec
    Air conditioning too cold
    Ticket #1039 · Reopened by member
    Not resolved
    Date tile and status colors
    StateTileText on tile
    Upcoming / infoaction-600White · 5.86:1
    Resolvedgreen-500Ink · 6.38:1
    Pendingamber-500Ink · 7.42:1
    Not resolveddanger-600White · 5.03:1
    Never color alone. Every status pairs its color with an icon and a word, so it is readable in grayscale and by screen readers.
    Cards. 8 px radius, 16 px padding, elevation 1. The whole card is one tap target when it opens a detail page.
    Hierarchy inside. Title 16 Bold, meta 12 Regular, status 12 Medium. Related facts stay together (Law of Common Region).

    Navigation

    Create a meeting
    Bottom tab bar. Four destinations plus a raised scan button. Five items is the upper limit for one-thumb reach and quick decisions (Hick's and Miller's laws).
    Scan is always reachable. Scanning a QR code at the door is the most time-critical task, so it sits at the center of the thumb zone in ink (#2D2D2D) and stands out from everything else (Fitts's Law).
    Active tab. Darker color and Bold label. Labels are always shown, at 11/14 Medium.
    Top bar. 56 px, back arrow on the left with a 48 px target, centered title. The back arrow always goes to the previous screen (user control and freedom).
    Consistent help. Support stays in the same position on every screen (WCAG 3.2.6).
    Accessible names. Icon-only controls carry labels such as "Scan QR code" and "Go back".

    Feedback and status

    Visitors need approval

    Guests added after 6 pm are approved by the front desk.

    Meeting booked

    Conference call room, 22 Dec, 1:00 pm to 3:00 pm.

    Room fills up fast

    Only 1 meeting room is left for this time.

    This time is taken

    Board room is booked 1 to 3 pm. Choose another time or room.

    Meeting cancelled

    No meetings today

    Book a room for a call or a catch-up with your team.

    Loading skeleton
    Progress, step 2 of 3
    What
    When
    Who
    Alerts. Icon, bold title and one sentence. The message says what happened and what to do next, in plain language.
    Toasts. Confirm reversible actions and offer Undo, staying at least 5 seconds so they can be read and used. Critical errors use inline alerts, not toasts.
    Empty states. Explain why it is empty and give the next action, instead of leaving a blank screen.
    Skeletons. Shown after 400 ms of waiting. They keep the layout stable and feel faster than a spinner (Doherty Threshold).

    Dialogs

    Cancel this meeting?

    Officiti App Demo on 20 Dec will be removed and 5 attendees will be notified.

    Use sparingly. Dialogs interrupt. Use them only for destructive or irreversible actions (error prevention).
    Clear choices. Buttons repeat the action in words ("Cancel meeting" and "Keep meeting"), never "Yes" and "No". The safe option gets initial focus.
    Behavior. Traps focus, closes with Escape, returns focus to the trigger, and dims the page behind.
    09 · Patterns

    Components combined into real journeys.

    Book a room in three short steps

    The original create-meeting screen shows every field at once. Splitting it into three steps lowers the number of decisions on screen (Hick's Law), keeps chunks small (Miller's Law) and shows progress, which encourages people to finish.

    What
    When
    Who
    What
    When
    Who
    Select days
    From
    To
    What
    When
    Who
    SSMMAK

    Ticket status system

    StateTileIcon + wordWhat it meansNext action
    Pending23PendingReceived, waiting for the workspace team.View details, add a note
    Resolved22ResolvedThe team marked it done.Confirm it works or reopen
    Not resolved22Not resolvedMember says the problem remains.Escalate to support

    Visitor access with a QR code

    1. 1. Add visitor. Name, email, date, time and purpose. Fields already known are prefilled (WCAG 3.3.7, no redundant entry).
    2. 2. Share the QR code. Visitor receives a code with name, date and time window. It carries a lock icon and expiry so it is clear it is private.
    3. 3. Scan at the door. The host or front desk scans from the always-visible scan button.
    4. 4. Check-in confirmed. A clear success state names the visitor and host and closes the loop.
    Private access code
    Saagar Shrestha
    9876543210 · 3 Feb 2021, 1:00 pm
    Expires at 3:00 pm

    Empty, loading, error and success

    Empty"No meetings today. Book a room for a call or a catch-up." Explains and offers the next action.
    LoadingSkeleton that matches the final layout, shown after 400 ms. No blank screens.
    Error"Board room is booked 1 to 3 pm. Choose another time or room." What happened and how to fix it.
    Success"Meeting booked. Conference call room, 22 Dec, 1:00 pm." Name the result and offer to add it to the calendar.
    Avoid"Nothing here." A dead end with no direction.
    AvoidA spinner alone on a white screen for several seconds.
    Avoid"Error 409" or "Something went wrong." Blames nobody and helps nobody.
    Avoid"Success" with no detail, or a message that disappears in one second.

    Writing for the interface

    DoUse plain words and active voice: "Book meeting room", "Add visitor". Sentence case. Numerals for numbers and clear dates such as "22 Dec, 1:00 pm".
    Don'tUse jargon or vague labels: "Submit", "Proceed", "Utilize", "Ticket ID 0x2F". Never shout in capitals or use only "Yes" and "No" in dialogs.
    10 · UX laws

    Five laws behind the design.

    A handful of well-known UX laws do most of the work in this system. These are the five it leans on.

    LawIn plain wordsIn Officiti
    Hick's LawFewer choices, faster decisions.Five-item tab bar, three-step booking, one main button per screen.
    Miller's LawPeople hold only a few things in mind.Short form groups, and ticket details split into labeled sections.
    Fitts's LawBig, close targets are easy to tap.48 px targets and full-width buttons within thumb reach.
    Jakob's LawPeople expect familiar patterns.Bottom tabs, a top-left back arrow, and native date and time pickers.
    Doherty ThresholdReplies under 400 ms feel instant.100 to 300 ms motion, and loading skeletons after 400 ms.
    11 · Accessibility

    Built to WCAG 2.2 AA.

    • Text contrast 4.5:1 (3:1 for large text). Enforced by the functional color scales.
    • UI contrast 3:1 for input borders, icons and focus rings (WCAG 1.4.11).
    • Target size. 48 px minimum interactive area, well above the 24 px AA requirement (2.5.8).
    • Keyboard and switch access. Every action reachable in a logical order, no drag-only interactions (2.1.1, 2.5.7).
    • Visible focus. 3 px ring with 2 px offset on every interactive element (2.4.7, 2.4.11).
    • Labels and names. Visible labels on fields and accessible names on icon-only buttons (1.3.1, 4.1.2).
    • Errors identified in text with an icon and a suggested fix, linked with aria-describedby (3.3.1, 3.3.3).
    • Not by color alone. Status uses color, icon and words together (1.4.1).
    • Zoom and reflow. Layout works at 200% text size and 320 px width without horizontal scroll (1.4.4, 1.4.10).
    • Reduced motion. Animations are removed when the user asks for less motion (2.3.3).
    • Consistent help. Support stays in the same place on every screen (3.2.6).
    • Easy sign-in. Password managers and paste work, and QR sign-in has an alternative (3.3.8).
    • Expiring QR codes. Show the expiry time and allow a refresh, so timing is adjustable (2.2.1).
    • Redundant entry. Known details such as company and email are prefilled (3.3.7).
    12 · Governance

    Keeping it consistent as it grows.

    Figma library structure
    1. 0 · Cover and changelog
    2. 1 · Foundations. Color, type, space, radius, elevation, icons, motion.
    3. 2 · Components. Variants for state, size and type, built with auto layout.
    4. 3 · Patterns. Booking, tickets, visitor access, states.
    5. 4 · Templates. Screen starters for iOS and Android.
    Naming
    Variables. color/primary/600, space/4, radius/sm, type/body
    Components. Button / Primary / Default, Field / Text / Error
    Code. --color-* or --primary-* tokens and of-* component classes.
    Contribution process
    1. 1. Propose. Describe the user problem and where it appears.
    2. 2. Check reuse. Can an existing component or variant solve it?
    3. 3. Design and review. Include all states and pass the accessibility checklist above.
    4. 4. Document. Add usage, specs, do and don't, and the UX rule it follows.
    5. 5. Release. Publish with a changelog entry and notify design and engineering.
    Versioning
    Major. Breaking token or API change.
    Minor. New component or variant.
    Patch. Bug fix or documentation update.
    Deprecation. Mark for one minor release before removal.
    Next in the roadmap. Dark theme tokens, a date and time picker, and an empty-state illustration set.