Foundations

The operating system for booked revenue.

Foundational components for the AI Revenue Engine — the managed booking, AI lead-response, and SEO platform for local service businesses. Every screen composes from the four foundations below.

Green = revenue / booked Amber = missed-lead urgency
01 · Typography

A serif that earns trust, a grotesque that does the work, a mono for the data.

Display moments lean editorial and human so the AI never feels cold. UI is clean and legible. Appointment IDs, metrics, and timestamps render in mono.

Font families

Display
Fraunces
Ag 0123 booked

--font-display · 400/500/600/700 + italic · headings & hero

UI / Body
Archivo
Ag 0123 Book now

--font-ui · 400/500/600/700 · body, labels, buttons

Data / Mono
Plex Mono
APT-4F9X2 · 09:30

--font-mono · 400/500/600 · IDs, metrics, timestamps

Type scale

Never miss a booking.
.type-display · Fraunces 600 · clamp(2.75–4.75rem)/1.05
Your phone rang at 9pm. We answered.
.type-h1 · Fraunces 600 · clamp(2–3rem)/1.25
Calendar prep, done by morning.
.type-h2 · Fraunces 600 · clamp(1.5–2rem)/1.25
Today's appointments
.type-h3 · Archivo 700 · 1.25rem/1.25
The AI greets every caller, checks real-time availability, and books the slot — 24 hours a day.
.type-lead · Archivo 400 · 1.125rem · ink-500
Body copy lives here. Owners are busy and skeptical, so paragraphs stay short, concrete, and outcome-led. Measure caps at ~62ch.
.type-body · Archivo 400 · 1rem/1.6 · max 62ch
Helper and secondary text for forms, captions, and metadata.
.type-sm · Archivo 400 · 0.875rem · ink-500
Section label · eyebrow
.type-cap · Plex Mono · 0.75rem · 0.12em · uppercase
APT-4F9X2 · Sat 9:30 AM · +1 (818) 555-0142
.type-data · Plex Mono 500 · appointment IDs / metrics
02 · Buttons

One obvious action per screen. Green means money.

Primary is the conversion button. Secondary supports it. Urgent is reserved for time-sensitive recovery like reclaiming a missed lead.

Variants

.btn--primary.btn--secondary .btn--ghost.btn--urgent

States & sizes

Hover lifts 2px · focus shows green ring · loading shows spinner · targets ≥44px tall.

Social sign-in · .btn--social

A neutral/bordered full-width button for SSO, distinct from the primary CTA (white is the Google convention). Provider-agnostic — each provider only supplies its own inline brand SVG (Lucide has no brand glyphs, so it's never used here). Used on Login and Accept Invite. Mockup of the SSO entry point — no real OAuth.

or

The .or-divider (rule + centered "or") separates SSO from the email form. .auth-legal carries the "By continuing you agree to Terms & Privacy" microcopy.

02b · Buttons & Actions

Grouped, split, clustered — and what they collapse to on a phone.

Extends Buttons: button groups, split buttons, action rows (which collapse to icon-only 44px circles on mobile), pills/badges/tags, and standalone icon buttons. Every icon button carries an accessible name.

Button groups · segmented (single-select) · multi-action · split

Segmented toggle (single-select — same control as the calendar Month/Week/Day)
Multi-button action group (joined)
Split button (primary action + dropdown caret)
States: selected · hover · disabled

Action row · desktop (labeled) vs mobile (icon-only 44px)

Same markup. Resize to ≤760px (or view at 390px) and the labels drop — each action becomes a 44px circular icon button, title/aria-label kept. This matches the Tables row-action rule.

Maria Gomez — HVAC tune-up

Pills · badges · tags

Status pills (semantic — consistent with Tables badges)
Booked Pending No-show Active Draft
Filter / choice pills (toggle) — default · selected · disabled
Removable filter tags (Lucide x to dismiss)
This week Booked Locked
Count / notification pills
Missed leads 9 Today 4 Drafts 12

Icon buttons · sizes · variants · states

Sizes (md and up ≥44px)
Variants: default · ghost · subtle · danger
States: default · disabled · loading
03 · Sections

Composable layout blocks — the bones of every page.

Pages are assembled from a small set of section containers: a hero, a feature grid, and a conversion banner.

Hero block · .hero

For local service businesses

Stop losing jobs to voicemail.

Your AI answers every call and text, checks your real calendar, and books the appointment — even at 11pm on a Saturday.

24/7
Always answering
<30s
Lead response
0
Double-bookings

Feature grid · .feature-grid / .feature

24/7 Booking

Real-time availability, exact-date checks, and instant confirmation with an appointment ID.

AI Lead Response

Catches calls, texts, web forms, and DMs — qualifies the lead and gathers job details.

SEO & Visibility

Climb from page 2 into the local pack where your great reviews can finally convert.

Conversion banner · .banner

04 · Form Controls

Inputs that feel safe to type into.

Owners enter credentials, phone numbers, and job details on a phone, often outdoors. Fields are large, high-contrast, and clear about errors. Every icon is a real Lucide glyph.

Text inputs · states

Default resting state with a leading icon.
Green ring + border on focus. Click to see it live.
Holds a valid value.
Not editable; muted surface.
Enter a valid email address.
Looks good.

Password · show / hide toggle

Click the eye to reveal. Toggles Lucide eyeeye-off.

Dropdowns / selects · states

Native select, custom chevron. Chevron flips on focus.
Holds a chosen value.
Not changeable; muted surface.

Open state (custom menu)

Native selects render the OS menu when open, so here is the styled custom-menu pattern for richer dropdowns, with a Lucide check on the selected row:

Plumbing

Rows are padded pills inset from the menu border — the hover/selected highlight never touches the edge. Same treatment applies to the typeahead and split-button menus.

Dropdown with icons (actions menu)

A .menu--icons variant: each row has a leading Lucide icon that aligns with the label. Shows all states — default, hover, focused, selected, disabled, and a destructive (danger) row in red. Reuses the same .menu structure and the new inset hover padding.

Icons via Lucide: pencil, copy, bell, archive, lock, trash-2. The Delete row uses .is-danger (red text + red hover).

Label · helper · error pattern

Each field is: label (with optional inline action) → controlhelper in resting state, replaced by error text + red border + aria-invalid on failure.

Used for customer confirmations and your owner alerts.
05 · Calendar

Booking lives on a calendar. So does the product.

A month grid, a compact date-picker tied to a date input, and an agenda/day view. Dots and counts show where appointments sit; past days are disabled; today and selection are obvious.

Month view · populated (dots + count) & selection

June 2026
Su
Mo
Tu
We
Th
Fr
Sa
June 2026 range
Su
Mo
Tu
We
Th
Fr
Sa

Compact date-picker (drops from a date input)

June 2026
Su
Mo
Tu
We
Th
Fr
Sa

Agenda / day view · populated & empty

Friday, June 19
9:00
Maria G.
HVAC tune-up · APT-4F9X2
10:30
Dev P.
Drain cleaning · APT-7B2K9
12:00
Open slot
2:00
The Reyes family
Pool service · APT-1Q8M4
Sunday, June 21
No appointments yet.
Open all day.
06 · Metric Cards

Outcomes, not features. Green is good; red is lost.

KPI cards for the owner dashboard, tied to the product's real outcomes. Trend up in green when it's good; a rising Missed Leads trends red because that's lost revenue.

Default · trend up / down (real outcomes)

Revenue Generated
$18,400
12% vs last month
Leads Captured
142
8% vs last month
Missed Leads
9
3 more vs last month
Appointments Booked
87
4% vs last month

With sparkline · loading skeleton · empty / no data

Missed Leads Recovered
$3,250
21% vs last month
No-Show Rate
No data yet
Avg. Response Time
Collecting…
07 · Tables

Lists of the things that make money: appointments, leads, customers.

Sortable headers, status badges in the semantic colors, and row actions. Responsive choice: at ~390px each row collapses into a labelled card (not horizontal scroll) — easier to scan and tap for booking data. Action buttons become 44px icon-only targets on mobile.

Populated · sortable · status badges · row actions

Customer Service Date & time Status Actions
Maria Gomez
+1 (818) 555-0142
HVAC tune-up Jun 19 · 9:00 AM Booked
Dev Patel
+1 (818) 555-0199
Drain cleaning Jun 20 · 10:30 AM Pending
The Reyes family
+1 (818) 555-0177
Pool service Jun 21 · 2:00 PM No-show
1–3 of 142

Loading (skeleton rows)

CustomerServiceDate & timeStatusActions

Empty state

No appointments yet

When the AI books a job, it'll show up here. Share your booking link to get the first one.

08 · Feedback & Overlays

Toasts & modals — one set of semantics across the app.

Transient toasts and blocking modals, with shared semantic colors/icons: success = green / check-circle, warning = amber / alert-triangle, danger = red / alert-circle or trash-2, info = neutral-blue / info. These back the inline confirmations and destructive actions used elsewhere (Profile save, danger-zone delete, cancel subscription, remove teammate).

Toasts · variants (click to trigger a real one)

Static examples (one of each), with leading icon, message, optional action link, and dismiss:

Booking confirmed
Maria G. — Sat 9:30 AM.
Couldn't save changes
Check your connection and try again.
Appointment in 30 minutes
Dev P. — drain cleaning.
AI booked an appointment
A new 2:00 PM slot just filled.

Placement: fixed top-right on desktop, top-center on phones (.toast-region). They never block interaction. Auto-dismiss after ~4s unless persist. Trigger via window.sgToast({intent,title,msg,action}). Stacked group = the four above rendered together.

Modal · base dialog (reusable shell)

Modal · warning (risky but not destructive)

Modal · success (confirming)

Confirmation · neutral (Confirm / Cancel)

Confirmation · destructive (default + type-to-confirm + loading)

Destructive confirms use .btn--danger as the primary; the most dangerous (Delete account) gates the button behind a type-to-confirm field. These are what the Profile danger zone, Subscription cancel, and Team remove-member actions point to.

09 · Showcase & Reviews

Proof that sells: completed work + reviews.

The social-proof foundation — before/after work, star ratings, and reviews. These power the public Business Showcase (the SEO/brand landing page), the owner-side Work Gallery and Reviews settings, and the review-request email. Images here are inline SVG placeholders so the components render offline.

Before / after slider — paired + single-image

After: clean pool Before: green pool Before After
Green-to-clean pool restoration · Pool clean-up

Drag the handle (or use ← → keys). 44px knob, full-height hit area. Touch-friendly.

Finished fade haircut Result
Skin-fade & line-up · Haircut

.ba-slider--single — single "after-only" photo (a haircut/nail set is one great photo, not a transform). Handle + before layer hidden.

Work grid (4→2→1) + lightbox

Lightbox (opened tile — shown inline)

Tiles show the finished image, a service tag, and a before/after vs single-photo marker. Click opens the lightbox (reuses the modal scrim) with the slider + caption + prev/next.

Star rating (fractional) + rating summary

4.8 127 reviews · across Google & Yelp
Google4.9 · 98 reviews
Yelp4.6 · 29 reviews

Stars use a clipped green/amber overlay (--pct) so half-stars are exact; role="img" + aria-label speaks the value (icons are decorative).

Review card + source badges

M
Maria G.
2 weeks ago
Google

Booked online at 11pm and they were out the next morning. Pool went from green to crystal clear. Will use again.

via Google · displayed per Google policy
D
Devon R.
1 month ago
Yelp

Great communication and fair pricing. Showed up on time and explained everything.

via Yelp · excerpt, attribution required

Each card carries its source badge + required attribution. Reality: Google Places & Yelp Fusion are display-only (a few recent reviews, caps ~3–5, attribution required) — we cannot post or auto-leave reviews.

Connect-source card — connect / connected / error

Google Business Profile
Pull your rating & recent reviews
Google Business Profile
Connected · 4.9★ · 98 reviews
Yelp
Couldn't connect — listing not found

Mirrors the onboarding calendar-connect pattern. Mock OAuth — connect → connected (shows summary) / error (retry). Google-first.