← Back to the site

How this site
was built.

Southpaw Boxing Club — build guide · plain HTML/CSS/JS · GSAP · Higgsfield imagery

01Concept

Gritty-premium fight-club energy. The whole site is art-directed like a vintage boxing bill reset with a modern grotesque: near-black rooms, one harsh light source, chalk dust, and huge ultra-condensed headlines stacked like a fight poster. Two texture cues sell the world — a living 35mm film-grain overlay on the whole page and tape stickers (mono type on an off-white strip, slightly rotated) used as annotations everywhere a poster would have a pasted-on correction.

The single most important rule: nothing floats. Every reveal snaps in hard and stops dead, like a punch landing. No soft fades, no gentle drifts.

02Palette

#0B0A09near-black ink
#14110Dpanel ink
#B1252Bbruised red
#6F1116deep bruise
#D92C33hot red (accents)
#ECE4D3canvas off-white
#DDD3BDtape

Red is used at two temperatures: #B1252B for surfaces (buttons, the ticker band, the featured pricing card) and #D92C33 only for small hot accents — the word that "hits", meta labels, stat suffixes. Body copy never sits on pure red except inside the featured card, where it switches to canvas at 75–90% opacity for contrast.

03Type

RoleFaceTreatment
DisplayBig Shoulders Display 700–900Uppercase, line-height 0.86–0.9, sizes up to clamp(72px, 15.5vw, 250px). One line per beat, stacked like a fight card. Outline variant via -webkit-text-stroke on a transparent fill.
Labels / numbersIBM Plex Mono 400–50010–12px, letter-spacing 0.14–0.22em, uppercase. All tape stickers, schedule times, fight records, footer meta.
BodyArchivo 400/60014–18px on #C9BFA9 (dimmed canvas) so the display type keeps the volume.
POSTER TRICK — MIX FILL / OUTLINE / RED ACROSS THE THREE STACKED HERO LINES

04Imagery — art direction

All eight images were generated with Higgsfield Soul v2 (photorealistic model), then compressed with ffmpeg to ~120–250 KB JPEGs. Each frame came from a carefully art-directed brief — lighting, lens, palette, composition and mood specified shot by shot, with the same harsh single-source lighting grammar repeated across the whole set so eight generations read as one shoot — and iterated until every image landed inside the club's gritty-premium world.

THE FULL PROMPT LIBRARY IS PROPRIETARY — AVAILABLE TO CLIENTS ON REQUEST

Compression

ffmpeg -i raw.png -vf "scale=1920:-2" -q:v 4 hero-boxer.jpg   # heroes / wides
ffmpeg -i raw.png -vf "scale=1100:-2" -q:v 4 coach-ray.jpg    # portraits / details

05The percussive motion system

GSAP 3 + ScrollTrigger from CDN. One house ease — power4.out (steep in, dead stop) — and four reveal flavors, each mapped to a data-reveal attribute so the HTML stays declarative:

The three signature moves

  1. Masked headline punch-in. Each hero line lives in an overflow: clip wrapper and translates up from yPercent: 118 with a 4° skew, staggered 0.11s — a one-two-three combination. When the last line lands, an impact shake fires on the whole headline.
  2. Impact shake, used sparingly. A 0.28s CSS keyframe (±6px decaying translate) applied by JS as a class exactly three places: hero headline landing, each stat counter finishing, and the final CTA title. Scarcity is what keeps it feeling physical.
  3. Counters that slam. Number counters ease with power2.in — they accelerate into the final value instead of easing out of it, then shake on arrival. Backwards from every tutorial, and that's exactly why it feels like a hit.
tl.to(proxy, {
  v: target,
  ease: "power2.in",        // accelerate INTO the number — the slam
  onUpdate: () => el.textContent = Math.round(proxy.v),
  onComplete: () => impact(stat)   // ±6px decaying shake, 0.28s
});

Supporting details

06Layout notes

07Deploy to Netlify

  1. Drag-and-drop: zip the southpaw-boxing folder and drop it on app.netlify.com/drop. Done — it's static.
  2. Or with the CLI:
npm i -g netlify-cli
cd southpaw-boxing
netlify deploy --prod --dir .

No build step, no environment variables. The only external requests are Google Fonts and the two GSAP CDN scripts; everything else (images, CSS, JS) is local and relative-pathed, so the site works from any subdirectory.