Anchor & Oak Back to site
Build Guide

How this site was made.

A walkthrough of the concept, the art direction behind the imagery, the build techniques, and the deployment path behind the Anchor & Oak showcase — written as a real project log, not marketing copy.

01

Concept & direction

The brief was a home-services / handyman / renovation company — a category that's almost always styled in generic corporate blue-and-white with stock-photo drills and clip-art hammers. The direction chosen here goes the other way: warm, tactile, organic-modern craftsmanship. The reference points were boutique renovation studios and Dwell-style architecture editorial, not contractor-directory templates.

That meant three commitments going in:

  • A palette pulled from the materials themselves — clay, oak, moss, linen — instead of a "trust blue" arbitrarily assigned to a trade business.
  • A headline serif with actual character (Fraunces), not a geometric sans that reads like every SaaS landing page from the last five years.
  • A real, well-built before/after interaction, since that's the one home-services trope worth keeping — it's the single most persuasive piece of content this kind of business can show, so it deserved custom engineering rather than a plugin embed.
02

Palette & type

Every color in the system is named after the material it's standing in for, defined once as CSS custom properties in css/style.css and referenced everywhere else — no hard-coded hex values in component rules.

Clay #c1583a
Clay Deep #9c4327
Oak Deep #33241a
Oak #6b4a35
Moss Deep #4c5636
Moss Soft #b7c19c
Linen #f7f1e6
Cream #fbf7ef

Typography pairs Fraunces (a warm, soft-serif display face with real optical-size character — used italic for accent words like "ground" and "life") against Work Sans, a clean humanist grotesque for body copy, labels, and UI chrome. The pairing does the classic job of a characterful display face against a quiet workhorse body face, but the specific choice of Fraunces over something like Playfair or Canela is deliberate: Fraunces leans rounder and warmer at the terminals, closer to hand-cut lettering than a fashion-magazine serif, which matches "craftsmanship" better than something more austere.

Craftsmanship that holds its ground.

Work Sans — Kitchens, baths, decks, repairs, and paint, built with real materials and honest timelines.

03

Asset generation

All photography on the site is AI-generated via the Higgsfield MCP, using the nano_banana_pro model at 2K resolution, then re-encoded to compressed JPEGs (resized with macOS sips) to keep the asset folder light — the eight source PNGs totaled roughly 76 MB; the shipped JPEGs total about 3 MB. Every prompt was art-directed specifically for this palette: golden-hour or soft window light, the same clay/oak/moss materials called out by name, and an explicit "no people, no text" instruction to keep the images usable as clean backgrounds and card imagery.

Each of the eight images — the hero exterior, the before/after kitchen pair, the four service shots, and the process detail — was generated from a carefully art-directed brief specifying the lighting setup, lens character, palette, composition, and mood, then iterated until it sat naturally inside the brand system. The full prompt library behind the set is proprietary to the studio and available to clients on request.

Note on the before/after pair: the two kitchen images were generated separately rather than as a true single-source edit, so the camera angle and cabinet layout are close but not pixel-identical. For a production client build, the more honest approach is a real photographed before/after pair, or an image-to-image edit pass that preserves the exact room geometry — flagged here rather than hidden.

04

Build techniques

Plain HTML/CSS/JS, no build step. Structure lives in index.html, all styling in css/style.css using CSS custom properties for the full palette, type stack, spacing, and easing curves — so the whole visual system can be re-themed by editing the :root block once.

  • Fluid type & spacing with clamp() — the hero headline, section headings, and hero vertical rhythm all scale with clamp(min, vw, max) rather than fixed breakpoint jumps, so type never explodes on ultra-wide monitors or collapses on small laptops.
  • CSS Grid for the services grid and process rail, collapsing from 4 → 2 → 1 columns via @media queries rather than a JS masonry library.
  • Film-grain texture via an inline SVG filter (feTurbulence + feColorMatrix) as a fixed, low-opacity, mix-blend-mode: multiply overlay across the whole page — a texture cue that reinforces the "tactile materials" concept without shipping a single grain image asset.
  • Context-aware header — the nav sits transparent with light text over the dark hero photo, then swaps to a blurred cream background with dark ink text once scrolled, via a ScrollTrigger-driven class toggle rather than a scroll-position hack in plain JS.
  • Semantic, accessible markup — <article> for service and testimonial cards, real form <label>s, a role="slider" with keyboard support on the before/after comparison, and descriptive alt text on every generated photo.
05

The before/after slider & motion

The centerpiece interaction is a hand-built draggable comparison slider (js/main.js), not a plugin. Two full-bleed images stack in a fixed-aspect-ratio frame; the "before" image sits inside a wrapper whose width is driven by pointer position, clipping it against the "after" image underneath. A pointer handle with a brass-toned grip icon tracks the divider line. It supports mouse drag, touch drag, click-to-jump anywhere on the frame, and full keyboard control (arrow keys move the divider in 5% steps) with proper role="slider" and aria-value* attributes. On first scroll into view it runs a one-time automated "sweep" from 12% → 68% → 50% so visitors immediately understand it's interactive before they've touched it.

Beyond the slider, the motion system (GSAP 3 + ScrollTrigger, loaded from CDN) is built from a handful of techniques chosen to match the brand rather than default "fade up on scroll" everywhere:

  • Line-mask headline reveal — each line of the hero headline sits inside an overflow: hidden wrapper and animates up from translateY(120%), a cleaner, more editorial entrance than a plain opacity fade.
  • Parallax hero image — the hero photo scales and drifts slightly on scroll via a scrubbed ScrollTrigger tween, giving the top of the page a sense of depth.
  • Count-up stats — the "14 years / 360 projects / 4.9 rating" row animates from zero using a tweened proxy object rather than static numbers.
  • Magnetic tilt on service cards — a lightweight mousemove listener rotates each card a few degrees toward the cursor in 3D, released with an elastic-out return on mouseleave — a small, tactile detail meant to feel like handling a physical card, not a UI element.
  • Infinite marquee strip — a duplicated flex track scrolling at a constant linear speed lists every service, a nod to painted contractor-van signage rather than a generic logo carousel.
06

Iteration passes

After the first complete build, the site went through three explicit fresh-eyes review passes — each one looking specifically for spacing problems, weak type pairing, color balance, generic-feeling animation, responsive breakage, contrast issues, and any remaining "template" tells. The short version:

  1. Pass 1 caught a real above-the-fold bug: the hero headline was sized for wide monitors only and pushed the CTA buttons and stat row off-screen on common 1280×720–800 laptop viewports; also found the header nav rendering dark text over the dark hero photo before scroll, killing contrast. Both fixed — hero type scale and vertical rhythm now use tighter clamp() ranges, and the header swaps between light and dark text states based on scroll position.
  2. Pass 2 reviewed color balance and rhythm section-by-section (services → showcase → process → testimonials → contact → footer), checked the mobile stack at 375px for overflow and grid collapse, and confirmed the before/after slider's drag math and keyboard support behaved correctly under simulated pointer events.
  3. Pass 3 did a detail sweep — hover/focus states, icon consistency, footer credit-line styling, and a final pass on alt text and semantic structure for accessibility.
07

Deployment

This is a static site with zero build step — no bundler, no package.json, no server-side code. It deploys as-is:

  1. Push the anchor-home/ folder to a Git repository (or drag-and-drop the folder directly).
  2. Connect the repo in Netlify (or drag-and-drop deploy for a one-off), with the publish directory set to the folder root — no build command is needed since there's nothing to compile.
  3. Netlify serves index.html at the root and guide/index.html at /guide/ automatically from the folder structure — no redirects or rewrites required.
  4. Point a custom domain at the Netlify site and Netlify issues the TLS certificate automatically.

Fonts load from Google Fonts and GSAP loads from the jsDelivr CDN at runtime, so there are no local font or script dependencies to manage post-deploy.