mozo — Design System

Can be used as a Google Stitch DESIGN.md. AI agents read this to generate consistent mozo UI. Drop a copy into any mozo repo root for AI tooling that supports DESIGN.md.

Brand Identity

mozo is table-side ordering that makes restaurants faster. Not a POS replacement — a complement. The brand is warm, straightforward, and trustworthy. Like a good waiter: present when needed, invisible otherwise.

Tone: Clean hospitality — not luxury, not tech-bro, not playful-food-app. Who sees it: Restaurant owners (supplier app), diners (user app), curious restaurateurs (marketing site). The promise: “5 minutes to set up. Your guests love it. You make more money.”


Color System

Core Palette (OKLCH-adjacent, warm hospitality)

/* Backgrounds */
--bg-cream:      #fbf8f3;   /* primary page background — warm, not stark white */
--bg-sand:       #f5f0e8;   /* section alternate — subtle differentiation */
--bg-white:      #ffffff;   /* cards, elevated surfaces (rarely used) */

/* Text */
--ink:           #1a1611;   /* primary text — dark brown, never pure black */
--ink-muted:     rgba(26, 22, 17, 0.6);  /* secondary text */
--ink-subtle:    rgba(26, 22, 17, 0.35); /* tertiary, borders */

/* Accent */
--amber:         #d97706;   /* primary accent — CTAs, highlights, mozo.BAR */
--amber-hover:   #b96004;   /* hover state */
--amber-subtle:  rgba(217, 119, 6, 0.1); /* accent backgrounds */

/* Semantic */
--success:       #059669;   /* confirmations, active states */
--danger:        #dc2626;   /* errors, destructive actions */
--warning:       #f59e0b;   /* warnings, pending states */

Usage Rules

  • NEVER use pure black (#000) or pure white (#fff) — always tint slightly
  • No gradients. Solid colors only. No backdrop-blur effects.
  • Amber is scarce. One CTA per viewport. Never amber text on amber background.
  • Gray text always goes on a background with enough contrast — no gray-on-gray-on-gray nesting
  • Dark mode: Not yet. Light theme only. When dark mode is added, invert the cream→dark charcoal, not pure black.

Typography

Font Stack

/* Primary: Inter (clean, versatile, great legibility) */
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

/* Monospace: for code, tables, data (rare in mozo UI but available) */
font-family: 'JetBrains Mono', 'Fira Code', monospace;

Scale

TokenSizeWeightUse
text-xs0.75rem (12px)400/500Labels, captions, meta
text-sm0.875rem (14px)400/500Secondary text, table cells
text-base1rem (16px)400Body text minimum
text-lg1.125rem (18px)400Lead paragraphs, marketing body
text-xl1.25rem (20px)500Subheadings, card titles
text-2xl1.5rem (24px)600Section headers (small)
text-3xl1.875rem (30px)700Section headers
text-4xl2.25rem (36px)700Page titles, hero subheads
text-5xl3rem (48px)800Hero headlines
text-6xl3.75rem (60px)800Hero headlines (large)

Typography Rules

  • Never use more than 3 sizes on one screen (hero can use 4)
  • No all-caps for body text. All-caps only for eyebrow labels (.text-sm.font-semibold.tracking-widest.uppercase)
  • No lorem ipsum in production — real content or nothing
  • Line height: leading-tight for headings (1.25), leading-relaxed for body (1.625)
  • Never use text-center on paragraphs longer than 2 lines — left-aligned is more readable
  • Font weight: 400 for body, 500-600 for emphasis, 700-800 for headings. Never use 300 or 900.

Spatial System

Spacing Scale (Tailwind v4 compatible)

0, px (1px), 0.5 (2px), 1 (4px), 1.5 (6px), 2 (8px), 2.5 (10px),
3 (12px), 3.5 (14px), 4 (16px), 5 (20px), 6 (24px), 7 (28px),
8 (32px), 9 (36px), 10 (40px), 11 (44px), 12 (48px), 14 (56px),
16 (64px), 20 (80px), 24 (96px), 28 (112px), 32 (128px)

Layout

/* Page container */
max-width: 72rem;       /* max-w-6xl = 1152px */
padding-x: 1.25rem;     /* px-5 */
padding-x-md: 2rem;     /* md:px-8 */

/* Section vertical rhythm */
padding-y: 5rem;        /* py-20 */
padding-y-md: 7rem;     /* md:py-28 */

/* Grid gaps */
gap: 1.5rem;            /* gap-6 — card grids */
gap-lg: 2rem;           /* gap-8 — section spacing */

/* Content max-width for readability */
max-width: 42rem;       /* max-w-2xl — for long-form text */

Spatial Rules

  • Generous whitespace. mozo is spacious, not dense. If in doubt, add more space.
  • No borders. Use whitespace and subtle background shifts (bg-sand) to separate sections. Borders only for tables and form fields.
  • No shadows except on primary CTAs — and even then, subtle: shadow-lg shadow-amber/20
  • No cards nested in cards. If content needs grouping, use a subtle background shift, not a border/shadow card.
  • Consistent section rhythm: Every section gets identical vertical padding. No exceptions.

Motion

Philosophy

Motion should feel like a well-trained waiter: efficient, barely noticeable, slightly warm.

Rules

  • Duration: 150ms for micro-interactions, 200-300ms for transitions, 400ms max for entrances
  • Easing: ease-out for entrances, ease-in-out for state changes. Never ease-in alone, never linear.
  • No bounce or elastic easing — feels dated and playful, not right for hospitality
  • No scroll-triggered animations. mozo is functional, not a portfolio site.
  • No skeleton loaders unless the wait is >500ms — render immediately or show a simple spinner
  • Hover states: subtle background shift or underline. Color changes only on interactive elements.

Animation Inventory

ElementAnimationDurationEasing
Button hoverbackground-color + shadow shift150msease-out
Link hovercolor shift + optional underline150msease-out
Modal openfade + scale(0.95→1)200msease-out
Modal closefade + scale(1→0.95)150msease-in
Toast/appearslide-up + fade300msease-out
Toast/dismissfade-out200msease-out
Tab switchcrossfade or instant150msease-in-out
Page transitioninstant (no animation)0ms—

What NOT to animate

  • Page loads (just render the page)
  • Paragraph text (staggered text reveals are for agency sites)
  • Icons spinning endlessly (use for active loading only)
  • Background colors on scroll

Component Inventory

Buttons

<!-- Primary CTA -->
<a class="inline-flex items-center gap-2 bg-amber text-white px-8 py-4 rounded-lg
          font-semibold text-lg hover:bg-amber/90 transition shadow-lg shadow-amber/20">
  Get Started →
</a>

<!-- Secondary -->
<a class="inline-flex items-center gap-2 border border-ink/10 text-ink px-6 py-3
          rounded-lg font-medium hover:bg-ink/5 transition">
  Learn more
</a>

<!-- Ghost / Text-only -->
<a class="text-amber font-medium hover:underline transition">
  Sign in →
</a>

<!-- Destructive -->
<button class="bg-red-600 text-white px-6 py-2.5 rounded-lg font-medium
                hover:bg-red-700 transition">
  Delete
</button>

<!-- Disabled -->
<button class="bg-amber/40 text-white px-6 py-2.5 rounded-lg font-medium cursor-not-allowed" disabled>
  Save
</button>

Cards

<!-- Standard card (no shadow, subtle border) -->
<div class="border border-ink/5 rounded-xl p-6 hover:border-ink/10 transition">
  <h3 class="font-semibold text-ink mb-2">Title</h3>
  <p class="text-ink/60 text-sm">Description</p>
</div>

<!-- Feature card with icon -->
<div class="text-center p-8">
  <div class="text-4xl mb-4">🖨</div>
  <h3 class="font-semibold text-ink mb-2">Feature</h3>
  <p class="text-ink/60 text-sm">Description</p>
</div>

Forms

<!-- Text input -->
<div class="mb-4">
  <label class="block text-sm font-medium text-ink mb-1.5">Email</label>
  <input type="email" class="w-full px-4 py-2.5 border border-ink/10 rounded-lg
                               text-ink bg-white focus:border-amber focus:ring-1
                               focus:ring-amber/20 outline-none transition"
         placeholder="you@restaurant.com">
</div>

<!-- Select -->
<select class="w-full px-4 py-2.5 border border-ink/10 rounded-lg
                text-ink bg-white focus:border-amber focus:ring-1
                focus:ring-amber/20 outline-none transition appearance-none">
  <option>Choose...</option>
</select>

<!-- Checkbox -->
<label class="flex items-center gap-2 cursor-pointer">
  <input type="checkbox" class="w-4 h-4 rounded border-ink/10 text-amber
                                 focus:ring-amber/20">
  <span class="text-sm text-ink/70">Remember me</span>
</label>

<!-- Error state -->
<input class="... border-red-500 focus:border-red-500 focus:ring-red-500/20">
<p class="text-red-600 text-sm mt-1">This field is required</p>

Tables

<!-- Data table -->
<div class="overflow-x-auto">
  <table class="w-full text-left">
    <thead>
      <tr class="border-b border-ink/10">
        <th class="py-3 pr-8 font-semibold text-ink text-sm">Name</th>
        <th class="py-3 pr-8 font-semibold text-ink text-sm">Status</th>
        <th class="py-3 font-semibold text-ink text-sm">Actions</th>
      </tr>
    </thead>
    <tbody class="divide-y divide-ink/5">
      <tr class="hover:bg-ink/[0.02] transition">
        <td class="py-4 pr-8 text-ink">Table 7</td>
        <td class="py-4 pr-8">
          <span class="inline-flex items-center gap-1 text-emerald-700 text-sm">
            <span class="w-1.5 h-1.5 bg-emerald-500 rounded-full"></span>
            Active
          </span>
        </td>
        <td class="py-4">
          <a href="#" class="text-amber text-sm font-medium hover:underline">Edit</a>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Modals

<!-- Backdrop -->
<div class="fixed inset-0 bg-black/40 z-50 flex items-center justify-center p-4">
  <!-- Modal -->
  <div class="bg-white rounded-xl shadow-xl max-w-md w-full p-6">
    <h3 class="text-lg font-semibold text-ink mb-2">Confirm</h3>
    <p class="text-ink/60 text-sm mb-6">Are you sure you want to delete this table?</p>
    <div class="flex justify-end gap-3">
      <button class="px-4 py-2 border border-ink/10 rounded-lg text-ink/70
                     text-sm font-medium hover:bg-ink/5 transition">
        Cancel
      </button>
      <button class="px-4 py-2 bg-red-600 text-white rounded-lg text-sm
                     font-medium hover:bg-red-700 transition">
        Delete
      </button>
    </div>
  </div>
</div>

Status Badges

<!-- Active/Success -->
<span class="inline-flex items-center gap-1 px-2.5 py-1 bg-emerald-50 text-emerald-700
             text-xs font-medium rounded-full">
  <span class="w-1.5 h-1.5 bg-emerald-500 rounded-full"></span> Active
</span>

<!-- Pending/Warning -->
<span class="inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700
             text-xs font-medium rounded-full">
  <span class="w-1.5 h-1.5 bg-amber-500 rounded-full"></span> Pending
</span>

<!-- Error/Danger -->
<span class="inline-flex items-center gap-1 px-2.5 py-1 bg-red-50 text-red-700
             text-xs font-medium rounded-full">
  <span class="w-1.5 h-1.5 bg-red-500 rounded-full"></span> Error
</span>

<!-- Neutral -->
<span class="inline-flex items-center px-2.5 py-1 bg-ink/5 text-ink/60
             text-xs font-medium rounded-full">Draft</span>

Anti-Patterns (DO NOT DO)

These are the most common AI-generated slop patterns. Avoid them all.

Color & Background

  1. ❌ Pure black (#000) or pure white (#fff) — always tint
  2. ❌ Gray text on colored backgrounds — invisible, inaccessible
  3. ❌ Purple-to-blue gradients — the most overused AI design cliché
  4. ❌ Backdrop-blur glassmorphism — wrong for hospitality
  5. ❌ Multiple accent colors — amber is the only accent. One accent = one brand.

Layout

  1. ❌ Cards nested inside cards — if you need grouping, use bg-shift or spacing
  2. ❌ Dark borders everywhere — use whitespace, not boxes
  3. ❌ Center-aligning paragraphs >2 lines — illegible
  4. ❌ Overlapping elements with negative margins — fragile, breaks on mobile
  5. ❌ Horizontal scroll on desktop — never. If it scrolls sideways, it’s broken.

Typography

  1. ❌ Inter for everything — Inter is our primary, but don’t make it the ONLY choice. (Actually for mozo, Inter alone is fine because we’re not a design-forward brand. But don’t use system-ui fallback when Inter is available.)
  2. ❌ All-caps paragraphs — all-caps only for eyebrow labels (< 5 words)
  3. ❌ Em dashes (—) — use regular dashes or commas. Em dashes in AI-generated text are a dead giveaway.
  4. ❌ Title Case Headings — use Sentence case for headings. “How it works” not “How It Works”.
  5. ❌ Bold text in body paragraphs — use for genuine emphasis only, never as decoration.

Content

  1. ❌ “Nestled within…” / “In today’s rapidly evolving…” — AI content tells
  2. ❌ “Great question!” / “I’d be happy to help!” — sycophantic openings
  3. ❌ “Let’s dive in” / “Here’s what you need to know” — signposting filler
  4. ❌ “In conclusion” / “The future looks bright” — generic conclusions
  5. ❌ Emoji in headings or CTAs — emoji in feature cards is fine. In headings, it looks desperate.
  6. ❌ “We’re excited to announce…” — just announce it.

Motion

  1. ❌ Bounce/easeOutBack easing — dated, feels like 2015
  2. ❌ Scroll-triggered reveals — performance tax for no functional gain
  3. ❌ Continuous animations (spinning icons, pulsing elements) — distracting
  4. ❌ Page transition animations — just render the page
  5. ❌ Hover scale transforms — subtle color/bg change only

Empty States

  1. ❌ “No data available” with nothing else — every empty state should tell the user what TO do
  2. ❌ Generic illustrations — a simple icon + text is better than a random undraw illustration

Page Templates

Marketing Page (mozo.bar)

1. HERO — eyebrow label + headline + subheadline + CTA + stats bar
2. HOW IT WORKS — 1-2-3-4 numbered steps
3. WHAT YOU NEED — 3 simple items with emoji icons
4. COMPARISON TABLE — mozo vs alternatives
5. BENEFITS — 3-4 feature cards
6. CTA FOOTER — same CTA as hero

Dashboard Page (supplier app)

1. HEADER — logo + supplier name + nav
2. STATUS BAR — quick stats (active tables, open orders, today's revenue)
3. MAIN CONTENT — table management grid or list
4. SIDE PANEL — context-sensitive details (open on click, not hover)

Form Page

1. HEADER — page title + back link
2. FORM — grouped fields with clear labels, inline validation
3. ACTIONS — save/cancel, save button is amber, cancel is ghost

Accessibility

  • All interactive elements must be keyboard-focusable and show a visible focus ring
  • Focus ring: ring-2 ring-amber/50 ring-offset-2 — amber, not browser default blue
  • Minimum touch target: 44×44px for all interactive elements on mobile
  • Color contrast: Text on backgrounds must meet WCAG AA (4.5:1 for body, 3:1 for large text)
  • Reduced motion: Respect prefers-reduced-motion. Disable all animations when set.
  • Alt text: Every image needs alt. Icons that are decorative get alt="".

Responsive Strategy

Breakpoints (Tailwind v4 defaults)

PrefixMin widthUse for
(none)0Mobile first — everything works here
sm640pxLarge phones
md768pxTablets
lg1024pxSmall laptops
xl1280pxDesktops

Rules

  • Mobile-first always. Write the mobile layout, then add md: overrides.
  • No hidden content on mobile — if it matters, show it. If it doesn’t, remove it.
  • Stack on mobile, side-by-side on desktop — the standard grid pattern
  • Tables on mobile: Either responsive scroll wrapper OR card layout. Never fixed-width tables.
  • Navigation: Bottom tab bar on mobile (or hamburger), top bar on desktop.

Supplier App — Specific

Current State

  • Ember 3.26, Emblem templates, CoffeeScript, Foundation 5
  • Desktop-only design, raw <table> login page
  • FA 4.7 icons via CDN

Immediate Targets

  1. Login page — rewrite with Foundation 5 grid (.row, .small-12.medium-6.columns, .control-group)
  2. Tables — add table.responsive wrapper, test on mobile
  3. Icons — FA 4.7 → 6 migration map
  4. Color tokens — unify with mozo palette via _shared-tokens.scss

Long-term: Component Migration

When migrating from Foundation 5 to Tailwind, go component-by-component:

  1. Pick one route (e.g., login)
  2. Rewrite in Tailwind using this DESIGN.md
  3. Test, deploy, wait a week
  4. Pick next route

Never do a big-bang CSS migration.


Docs Site — Specific

docs.mozo.bar is a Hugo static site with a custom minimal theme. Design constraints:

  • Primarily text content (guides, how-tos)
  • Must be readable on mobile (restaurant owners reading setup guides)
  • Should feel like part of mozo.bar family

The Hugo theme’s CSS should reference the same color tokens and typography scale.


Design Review Checklist

Before shipping any page, verify:

  • No pure black or pure white anywhere
  • No em dashes in text content
  • No AI-tell phrases (“nestled”, “dive in”, “game-changer”)
  • Amber used once per viewport (one CTA, not five)
  • Maximum 3-4 font sizes per page
  • Mobile layout works (not just responsive, actually tested)
  • Touch targets ≥ 44px on mobile
  • No horizontal scroll at any breakpoint
  • No cards nested in cards
  • No gradients or backdrop-blur
  • Forms have visible labels and error states
  • Empty states have clear next actions
  • Focus rings visible on keyboard navigation
  • prefers-reduced-motion respected

Last updated: 2026-06-01 Based on: mozo-page-design-recipe.md + impeccable anti-patterns + taste-skill principles + awesome-design-md format