Skip to main content
vibld

Template

Fresh Start Cleaning Co.

a site for a residential cleaning service that gives an instant price estimate from the size of the home and how often, explains what each clean includes, and turns the estimate into a booking request.

House cleaning service with an instant estimate · Website · Small business site · 3 pages

A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.

Add app screens

Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.

Account setup
Add edit
Analytics
Appearance
Calendar
Chat
Checklist
Checkout
Confirmation
Dashboard
Delete account
Details
Discovery questions
Empty state
Flowchart
Import export
Inbox
Integrations
Invite team
Loading
Login
Onboarding
Plans
Playground
Product tour
Referral
Search
Settings
Share
Sign up
Success
Table
Team members
Text editor
Upgrade
Usage
Verification
Welcome

Start from this templateRead the build prompt

Typefaces

Lilita One is round and cheerful without being childish; Poppins keeps checklists and prices crisp.

  • Lilita OneHeadings: headlines and the estimate
  • PoppinsBody: checklists, prices and forms

Who it is for

  • Busy households pricing a regular clean
  • People moving in or out who need a deep clean
  • Short-term rental hosts

Layout

  1. Header: logo, Cleans, How it works, FAQ, and Get my price
  2. Split hero: headline left, the estimator card right (bedrooms, bathrooms, how often) with the price
  3. What is included: room-by-room checklist in three columns
  4. How it works: three steps (price, book, relax)
  5. Clean types grid with prices from
  6. Service area list and reviews
  7. FAQ accordion and footer with hours, phone and insurance note

Palette

Fresh, friendly and bright, like a just-opened window: mint white, a deep evergreen and a sunny yellow.

  • mint white#f2fbf8
  • evergreen#123a33
  • fresh green#0b7a5e
  • sunny#ffcf5c

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on the page11.87:14.5:1
Aatext on cards12.51:14.5:1
Aasecondary text on muted surfaces4.90:14.5:1
Aasecondary text on the page5.63:14.5:1
Aalabel on the primary action5.03:14.5:1
Aalabel on secondary surfaces12.51:14.5:1
Aalabel on the accent8.54:14.5:1
Aaerror label5.46:14.5:1
primary action against the page5.03:13:1

As vibld’s tokens

The palette on the 15+ color tokens vibld styles a project with, each text color on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.

  • background
  • card
  • muted *
  • primary
  • secondary
  • accent
  • destructive *

Type scale

Display
Lilita One, headlines and the estimate
Body
Poppins, checklists, prices and forms

Spacing and imagery

Friendly: 80px between sections, rounded cards.

Clean, lived-in rooms in daylight and the team at work with their own supplies; simple sparkle shapes drawn in the palette.

Components

  • Estimator: steppers for bedrooms and bathrooms, a frequency segmented control, and the price from prices.json
  • Checklist card per room with check marks
  • FAQ accordion with one open at a time

Interactions

  • The estimate updates as each control changes and is carried into the booking request
  • The page says the price is an estimate the team confirms before the first clean

Data

  • cleans: a clean type: name, from price, checklist by room, time it takes, add-ons
  • prices: a price rule: bedrooms, bathrooms, base price, discount by frequency
  • form booking-request: name, email, phone, address, bedrooms, bathrooms, frequency, clean type, add-ons (checkboxes), estimated price (hidden, from the estimator), preferred start date, pets, entry instructions

Build prompt

The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.

The baseline
### How to use these prompts
Each niche site prompt describes a whole small site for one kind of owner: its pages, the records it keeps, the forms it collects and the tools it links to. The rules below apply to every one of them.

### Niche site principles
- The site does the one job its owner needs most (a sign-up, an RSVP, a request, a visit) on the first screen, and every page leads back to it.
- Records the owner adds often (sermons, events, listings, galleries, menus, tour dates) are content collections in `src/content/`, each record with a slug, so a new record gets its page with no code change.
- Tools the owner already pays for or uses (giving, tickets, booking, listing search, ordering) are linked, or framed in an `<iframe>` whose address is in `content.ts`, never rebuilt. With no address, a plain button links out instead, and nothing pretends to work.
- Copy is written for the owner's visitors, specific and plain. Dates, times and places are real fields, never baked into prose.
- The design is this site's own. Its layout, type and motion follow the brief, not a shared template.

### Forms
Every form is a plain HTML form, `<form method="post" action="/__vibld/forms/<name>">`, named as the brief names it (lowercase letters, digits and hyphens). Fields are ordinary named inputs; checkboxes repeat their name; no file uploads. Add a hidden `_next` input with the path to land on, and show a thank-you there when the address has `?submitted=<name>`. Add an empty hidden `_gotcha` input. A script may post it instead with `fetch(form.action, { method: 'POST', body: new FormData(form), headers: { accept: 'application/json' } })`, which answers `{ ok: true }` or `{ ok: false, error }`. A form with limited places lists them in `public/vibld.forms.json` (`{"forms":{"<name>":{"slots":{"field":"<field>","options":{"<value>":<places>}}}}}`), the field a select or radio whose values match those keys exactly; `GET /__vibld/forms/<name>/slots` returns `{ field, options: [{ value, capacity, taken, left }] }`, which the page reads to show what is left and disable full options. vibld adds bot protection when the page is served.

### Engineering baseline
- TypeScript strict mode, small typed components, and one source of truth for design tokens (CSS variables consumed by Tailwind).
- All copy lives in typed content files, so the owner can edit words without touching layout.
- Every form validates on the client, says what went wrong in plain words beside the field, and never claims success it has not had.
- No secrets in the bundle and no third-party scripts beyond Google Fonts; an owner's tool comes in only as a link or a framed page.
### Goal
Build **Fresh Start Cleaning Co.**: a site for a residential cleaning service that gives an instant price estimate from the size of the home and how often, explains what each clean includes, and turns the estimate into a booking request.

### Stack
React + TypeScript + Vite, Tailwind CSS and React Router, one route per page. Content collections in `src/content/`, forms posting to vibld (see Forms in the baseline). No backend of its own.

### Pages & layout
- `/` Home: hero with the estimator, what is included, how it works, service area, reviews, FAQ
- `/services` Cleans: standard, deep, move-in and move-out, rentals, each with its checklist
- `/book` Book: the estimate carried into a booking request

Home, top to bottom:
1. Header: logo, Cleans, How it works, FAQ, and Get my price.
2. Split hero: headline left, the estimator card right (bedrooms, bathrooms, how often) with the price.
3. What is included: room-by-room checklist in three columns.
4. How it works: three steps (price, book, relax).
5. Clean types grid with prices from.
6. Service area list and reviews.
7. FAQ accordion and footer with hours, phone and insurance note.

Copy to start from, in `content.ts`: headline "Come home to clean", subcopy "Weekly, every two weeks or once. Get a price in ten seconds, and the same two cleaners every time.", primary action "Get my price".

### Design system
Mood: Fresh, friendly and bright, like a just-opened window: mint white, a deep evergreen and a sunny yellow.

Palette: mint white `#f2fbf8`, evergreen `#123a33`, fresh green `#0b7a5e`, sunny `#ffcf5c`. Tokens: background `#f2fbf8`, foreground `#123a33`, primary `#0b7a5e` with `#f2fbf8` labels, cards `#ffffff`, accent `#ffcf5c`.

Type: Lilita One for headlines and the estimate; Poppins for checklists, prices and forms. Load both from https://fonts.googleapis.com/css2?family=Lilita+One&family=Poppins:wght@400;600&display=swap.

Corners: 999px on controls, 22px on cards, 32px on large panels. Spacing: Friendly: 80px between sections, rounded cards.

Imagery: Clean, lived-in rooms in daylight and the team at work with their own supplies; simple sparkle shapes drawn in the palette. Use the owner's photos where the project has them. Without them, use the project's stock photos, or shapes and color from the palette; never a stock photo of people at desks.

### Components & interactions
- Estimator: steppers for bedrooms and bathrooms, a frequency segmented control, and the price from prices.json
- Checklist card per room with check marks
- FAQ accordion with one open at a time

Motion:
- The estimate updates as each control changes and is carried into the booking request
- The page says the price is an estimate the team confirms before the first clean

The signature motion is: a small sparkle glints across the estimate each time the price changes. Keep it to that one; everything else is a 150 to 300ms state change. With prefers-reduced-motion, it and every reveal are still.

### Data & state
Collections:
- `src/content/cleans.json`: a clean type: name, from price, checklist by room, time it takes, add-ons; each has its page at `/services/<slug>`
- `src/content/prices.json`: a price rule: bedrooms, bathrooms, base price, discount by frequency

Forms:
- `booking-request`: A customer asks to book the clean they priced. Fields: name, email, phone, address, bedrooms, bathrooms, frequency, clean type, add-ons (checkboxes), estimated price (hidden, from the estimator), preferred start date, pets, entry instructions.

Linked tools:
- None.

### Accessibility
WCAG 2.2 AA. Every control has a visible focus ring and a 44px target, every form field a visible label, and errors are announced. Dates and times are written out ("Sunday, March 8, 10:30 AM"), not only shown in a grid. Images have alt text that says what is in them. Verified contrast: body text on the page #123a33 on #f2fbf8 11.87:1; text on cards #123a33 on #ffffff 12.50:1; secondary text on muted surfaces #4a6a64 on #e0ece8 4.90:1; secondary text on the page #4a6a64 on #f2fbf8 5.63:1; label on the primary action #f2fbf8 on #0b7a5e 5.03:1; label on secondary surfaces #123a33 on #ffffff 12.50:1; label on the accent #123a33 on #ffcf5c 8.53:1; error label #ffffff on #c62f2f 5.45:1; primary action against the page #0b7a5e on #f2fbf8 5.03:1.

### Security
No third-party scripts other than Google Fonts. Framed tools are `<iframe>`s from the owner's own address with a `title`, `loading="lazy"` and `referrerpolicy="strict-origin-when-cross-origin"`. Forms cap input length and carry the empty `_gotcha` field.

### Performance & SEO
Images as AVIF or WebP with width and height, the first one eager and the rest lazy. Preconnect to Google Fonts. Each page has its own title and description from content, and records' pages take theirs from the record. Structured data where it fits: LocalBusiness with opening hours.

### Guardrails
- Avoid: Gloved hands holding spray bottles as stock, "spotless guaranteed" promises, hidden pricing, and taking payment on the site.
- One primary action per screen, one accent color, at most six top-level links.
- No carousel in the hero, no mega menu, no emoji or clip-art icons, no hard offset shadows, no purple-to-blue gradient.
- The names in it are invented. Use no real organization's or person's name, logo or trademark.

Open the builderAll templatesThis palette on its own