One lightweight booking widget for every salon site we build. It opens with who — your regular tech, stylist, or barber — then the service, then a time. Neutral by default; each salon's brand drops in as theme tokens. No payments.
People book around a person, so the funnel starts there. Four taps to booked — no account, no fluff. Availability is computed live for the chosen person, and the database refuses a double-booking even if two people tap the same slot at once.
The widget lives on our platform and embeds as a style-isolated iframe that auto-resizes to its content. It can't break the host site's layout, and the host site can't leak into it. This is how Dolce replaces its current third-party booking box.
Or a "Book Now" button that links straight to the hosted page — for salons with no website yet.
No heavy framework shipped to the salon's page — it works the same on every site we build.
The iframe sandboxes styles both ways. Auto-resize keeps it flush, with no inner scrollbars.
Salons keep their own card processor. We never touch money, which keeps it simple and safe.
The platform's own identity is deliberately quiet — clean greyscale, ink-on-paper. Every color, radius, and font is a named token, so onboarding a salon means swapping a small set of values, not touching the UI.
| Token | Neutral default | Dolce override | Drives |
|---|---|---|---|
| --accent | #17191C | #6B2737 | Buttons, active states |
| --bg | #FFFFFF | #FFFAF5 | Widget background |
| --surface | #FBFBFC | #FAF6F1 | Rows, fields |
| --line | #E3E5E8 | #ECE0D4 | Borders |
| --radius | 10px | 6px | Corner softness |
| --display | System UI | Fraunces serif | Headings, salon name |
Stored as a small theme record on each salon and injected as CSS variables at load — the exact mechanism in the live toggle at the top of this page.
A clean grotesque carries the interface; a monospace handles times, prices, tokens, and the embed snippet — the "engineered & embeddable" signal. A salon's own display face (e.g. Dolce's Fraunces) overrides headings via the --display token.
Two protected areas in the same app. The salon dashboard opens on a calendar — the receptionist's home base — with one-time setup for staff, services, schedules, and hours. The agency admin is where you onboard and manage every salon.
Add each person, their photo, and what they do. Per-salon label: Techs, Stylists, or Barbers.
Name, duration, price (or "from"), and which staff offer it. Seeded from the salon's current menu.
Per-person weekly hours and days off — drives each person's real availability.
Salon-wide hours, holidays, and closures. Staff schedules fall back to these.
| Salon | Slug | Plan | Bookings / 30d | Status |
|---|---|---|---|---|
| Dolce's Nails & Spa | dolce | $100/mo | 312 | Active |
| Sharp & Co. Barbers | sharp-co | $100/mo | 204 | Active |
| Lotus Hair Studio | lotus | Trial | — | Onboarding |
This is a wireframe, not the build. Once you're happy with the who→what→when flow, the owner calendar, and the greyscale default, here's the order I'd take it in.
The screen-by-screen behavior, the data it needs, and the rules (availability, no double-booking) — agreed before any app code.
A navigable /wireframes + /brand in the repo, same pattern you used for Dolce, so the design lives in code.
The themeable widget shell, salon-slug → theme lookup, live availability, and the anti-double-booking guarantee.
Replace the current third-party booking box with our widget as the first real salon.