$ cd ~/projects/estheticly-skincare
$ cat README.md[LIVE]2025–2026
EstheticLY Skincare
Multi-page site for a Charlotte, NC esthetician with hardened Acuity booking embed and local-business structured data.
- Next.js
- CSS Modules
- Acuity
- WCAG 2.2
A seven-page marketing site for a solo licensed esthetician. It explains treatments, prep and aftercare, and funnels clients into her existing Acuity booking flow instead of DMs. Delivered, in use, and maintained through client content updates.
Problem
The problem
A one-person skincare studio needed to be found locally, answer the pre- and post-treatment questions clients ask over and over, and get bookings into one system. The existing setup was social media DMs and word of mouth.
Solution
The solution
Next.js App Router, server components by default, styled with CSS Modules over a small token system. Each route is composed from marketing sections driven by typed content modules, so the client's price and FAQ changes are data edits. Booking is an embedded Acuity scheduler gated behind policy acceptance.
Highlights
Interesting details
- Hand-written Content Security Policy plus HSTS, nosniff, Referrer-Policy and Permissions-Policy headers, with narrowly scoped exceptions for the Acuity embed and a documented reason for each one.
- Self-resizing booking iframe that listens for postMessage height events and hard-checks the message origin before touching the DOM, with a shimmer skeleton until load.
- Policy gate: the scheduler only renders after the client has read the cancellation and late policies.
- BeautySalon JSON-LD with address, phone, opening hours and social profiles, sourced from the same content module the contact page renders.
- WCAG 2.2 AA accessibility pass across the site, including a skip link and a contrast fix for mobile dark mode.
- Zero runtime dependencies beyond React and Next.
Tech stack
Built with
- Next.js 15
- React 19
- TypeScript
- CSS Modules + custom properties
- Acuity Scheduling embed
- Square gift cards
- Vercel