Studio Bia Santos
A manicurist offering private at-home appointments in Londrina and the surrounding region.
the_problem
A self-employed professional with no digital presence, whose booking happened entirely through loose WhatsApp conversation: no service context, no visible pricing, no organised social proof.
what_it_does
- One page, static, with no backend, no database and no server state.
- A booking card that does not reserve a slot: it composes the message and opens the WhatsApp conversation, where the appointment is confirmed by a human. There is no system to operate, and confirmation stays where it already was.
- Hero, about with a real portrait, services with prices, a gallery of real client photos, testimonials as genuine WhatsApp screenshots, closing call to action and a four-column footer.
- Date picker, floating WhatsApp button, an Open Graph image generated in the brand’s theme, and generated robots and sitemap.
stack
frontend
Next.js (App Router) · React 19 · TypeScript · Tailwind CSS v4 · shadcn/ui on Base UI · Vitest
other
Vercel · GitHub Spec Kit
measured
- Numbered browser validation procedures
- 25V-001 to V-025 across the specification quickstarts
- Display typeface weights
- 1hierarchy comes from size and spacing, by design
how_it_was_built
Spec-driven with four specifications, a project constitution prevailing over everything else, and a living product specification kept beside it.
The rebrand from neighbourhood salon to boutique is documented as its own specification, and the rules that survived it are written prohibitively: a named typeface "is gone, do not reintroduce it"; the old wine, ivory and blush palette "is over, do not reintroduce it". Components read semantic tokens, never a literal hex.
The typographic detail is the project’s signature: the display face has exactly one weight. Hierarchy comes from size, letter-spacing and breathing room, never from a heavier weight. Headings are pinned to weight 400 with weight synthesis disabled, because faux-bold smears a didone.
Typography is self-hosted. Google Fonts at runtime is prohibited in the project, including when a tool tries to inject it.
A single configuration module is the sole source of contact details, services, prices, hours and availability.
known_limitations
- The booking card does not reserve anything. This is a product decision, not a missing feature: there is no system for the client to operate.
- The test suite covers structural invariants (label counts, the six section headings, anchor integrity) and explicitly does not cover appearance. jsdom does not load the stylesheet, so a test proves a token was applied and never proves a pixel was painted.
- Because of that limit, layout and accessibility validation stays a mandatory manual measurement in a real browser, with twenty-five numbered procedures rather than an automated substitute.
- Content rules are not stylistic: there are two services and exactly two, no social proof is invented, and every published number derives from real data at runtime.
tracked coding time
11 hrs 3 mins Source: WakaTime · tracked 2026-03-17 to current