The Salon Co.

A 14-page marketing website for a fictional luxury hair salon — built from scratch with vanilla HTML, CSS, and JavaScript. This is the salon vertical of the CH Studios white-label SaaS platform, designed to work as either a real business deployment or a standalone portfolio piece demonstrating production-level thinking.


Live on GitHub Pages In Progress HTML · CSS · JavaScript No Frameworks
14 HTML Pages
1 Shared Stylesheet
0 Frameworks or Libraries
Visit Live Site

Tech Stack

HTML5 CSS3 JavaScript CSS Custom Properties CSS Grid Flexbox GitHub Pages

Project Snapshot

  • Type: Frontend learning project, polished into a portfolio piece
  • Stack: HTML · CSS · JavaScript — no build tools, no frameworks, no dependencies
  • Status: Core pages live; services, gallery, contact, and booking pages in progress
  • Team: Solo
  • Role: Design and frontend development — layout, design system, interactions

Pages Built

index.html Hero, services preview, reviews carousel, CTA
about.html Founder story, timeline, principles, image gallery
stylists.html Four full profiles, alternating layouts, booking badges
services.html Service overview with accordion
blowout-style.html Service detail page
precision-cut.html Service detail page
color-highlights.html Service detail page
keratin-treatment.html Service detail page
gallery.html Portfolio gallery with JS category filters
book.html Booking page
contact.html Contact page
location-hours.html Location and hours
employment.html Careers page
apprenticeship-program.html Apprenticeship program details

Design System

The entire site's visual language is defined once in CSS custom properties and referenced everywhere — no hardcoded colors or font stacks scattered through the stylesheet.

Typography

Cormorant Garamond for headings — elegant, editorial, appropriate for a luxury brand. Jost for body text — clean and legible at small sizes. Both loaded from Google Fonts with font-display: swap to avoid invisible text on slow connections.

Color Palette

--color-primary #1A2E2A
--color-surface #313E3A
--color-secondary #F5F0E8
--color-accent #C9A96E
--color-white #FAFAF7
--color-muted #6A746D

Layout

CSS Grid for page-level structure and multi-column layouts. Flexbox for component-level alignment — navigation, cards, and inline elements. Both used where each makes the most sense rather than picking one for everything.

JavaScript Features

Everything in ~120 lines of vanilla JS — no libraries, no framework.

Scroll-Based Sticky Header

Adds a .scrolled class after 10px of scroll, swapping the header from dark green to a cream background. The header always stays visible without being visually heavy on page load.

Auto-Rotating Review Carousel

Testimonials rotate every 3 seconds automatically. Clickable progress bar indicators let users jump to any slide. Interval resets on manual navigation so a user click doesn't immediately get overridden by the auto-rotate.

Mobile Hamburger Menu

Toggles .nav-open on the nav element. Closes on any nav link click or an outside click — so users aren't trapped in an open menu. The hamburger icon is CSS-drawn, no image or icon font needed.

FAQ Accordion

Click to expand or collapse. The first item opens by default. Only one item is ever open at a time — opening a new one closes the previous. Toggles aria-expanded alongside the visual state for screen reader support.

Gallery Category Filters

Data-attribute–based show/hide. Filter buttons toggle an .active class for styling. No DOM elements are created or destroyed — cards are shown or hidden with CSS. This keeps filtering instant with no layout recalculation.

Service Detail Pages

Each service has its own dedicated page rather than a shared template with JS routing. No build step, no configuration — just HTML files. The tradeoff: less DRY, but the site works without JavaScript and loads immediately.

Technical Decisions

Single Shared Stylesheet

All 14 pages share one style.css (~3,300 lines). A component styled once looks the same everywhere. The cost is that every page loads styles it doesn't use — a framework would tree-shake these, but for a static site of this size the simplicity is worth it.

Static Header and Footer

Nav and footer are duplicated HTML across pages rather than JS-injected. The site works without JavaScript, there's no render delay waiting for a script, and no flash of unstyled navigation. The cost: a nav change requires editing every file.

CSS Custom Properties First

Every color is defined once on :root and referenced everywhere. Swapping the entire color palette is three line edits. This was a day-one decision, not a refactor — choosing the architecture before writing component styles.

Challenges

Breakpoint Overlap: 1024px Desktop vs. 1000px Hamburger Trigger

The desktop layout switches at 1024px, but the mobile hamburger menu activates at 1000px. In the 24px range between those two breakpoints, both the desktop nav and the mobile hamburger are present at the same time. This is a real bug: a viewport at 1010px gets hamburger behavior inside a desktop layout. The fix is to align both breakpoints to the same value — the desktop layout and the nav behavior need to change at the same moment.

Dead Font Weights: Lobster and Lobster Two

Both Lobster and Lobster Two are loaded in the <head> via Google Fonts but never referenced anywhere in the stylesheet. Every page load fetches these font files for no reason — added latency with zero visual output. The fix is to remove both <link> tags from every page's <head>.

Large Fixed Padding at Desktop Widths

Major sections use padding-left: 12rem on desktop. This works on wide screens but the responsive overrides at 1024px and 1000px leave a gap — narrower viewports get too much horizontal padding before the breakpoint fires. This is the kind of issue that appears between breakpoints rather than at them, and requires testing at every width in between rather than just at the defined breakpoints.

What I Learned

  • CSS custom properties as a design system — defining all values in :root and referencing them throughout the stylesheet is the web equivalent of a centralized style guide. It makes changes trivial and enforces consistency without a preprocessor.
  • When to use Grid vs. Flexbox — Grid for two-dimensional layout (the page itself, the gallery, the stylists grid). Flexbox for one-dimensional alignment (nav items, card content, inline elements). Using both for their actual purpose instead of forcing one to do everything.
  • Accessible accordion patterns — toggling aria-expanded alongside the visual state so the interaction is meaningful to assistive technology, not just to sighted users.
  • Multi-page architecture tradeoffs — the simplicity of plain HTML files versus the maintenance cost of duplicated nav and footer across 14 pages. This project makes the cost of that tradeoff concrete in a way that reading about it doesn't.
  • Typography for luxury brands — pairing a serif display face with a geometric sans-serif body, and understanding why that combination works for the brand voice being designed here.

Still In Progress

  • Mobile responsiveness across all pages — breakpoints exist but need refinement on the stylists and gallery layouts
  • Form functionality on the contact and booking pages — currently static HTML, needs either a form service (Formspree) or a backend endpoint
  • Gallery images — placeholder layout is in place, real photography assets needed
Solo project · HTML · CSS · JavaScript · 14 pages · 0 dependencies · In Progress

Outcome

The Salon Co. is where I moved from following tutorials to making real design decisions. Building 14 pages with a shared design system — and no framework to enforce consistency for me — required thinking about CSS architecture from the start rather than cleaning it up at the end. The gallery filters, accordion, and mobile nav are all written in plain JavaScript against the DOM, which built a clearer mental model of how the browser actually works before reaching for abstractions.