Skip to content

Repository files navigation

Crux

Bouldering gym — pick a problem and watch its holds light the line up an SVG wall, filtered by grade.

Live demo Family Stack MIT License

Live demo  ·  Build notes  ·  More templates

Crux — live preview

Use this template — copy the source into a new project:

npx degit bswxyz/crux my-app

A design-showcase website template from Parable: a fictional bouldering gym in an old basalt works. Chalky, communal, stoked-but-grounded — grades and beta talk, welcoming to first-timers.

The signature: a trace-a-route climbing wall. The hero is an inline-SVG wall studded with this week's problems, V0–V7. Pick one and its holds latch on in climbing order — mat to top-out — while a line traces the route through them and every other hold falls back into the plywood. Start and finish holds get the setter's dashed tape ring. Fully keyboard accessible; honest under reduced motion (whole line lights at once, no sequence).

Design system

Token Light (default, "chalk") Dark ("basalt")
Background #f3f1ec chalk #14171c basalt
Ink #14171c #f3f1ec
Accent hold-orange #ff6a3d (#bb3d12 as text on chalk) #ff6a3d
Secondary volcanic #6a3b2a (background wash) same
  • Type: Archivo Black (display) · Inter (body) · Martian Mono (grades, times, tape labels)
  • Easing: "the mantle" cubic-bezier(.17,.89,.32,1.01) for reveals; "the dyno" cubic-bezier(.26,1.45,.42,1) — overshoot, then latch — for holds and buttons
  • Theme toggle persists via localStorage (crux-theme); tokens flip on :root[data-theme]

Stack

  • Vite + vanilla TypeScript — no framework, no runtime deps
  • All art is inline SVG (the wall, the brand mark) — zero image files
  • Hold positions live in the SVG markup; src/wall.ts reads them from the DOM, so the wall renders complete without JavaScript

Run locally

npm install
npm run dev        # dev server
npm run build      # tsc --noEmit && vite build → docs/
npm run preview    # serve the production build

Built output lands in docs/ (with base: '/crux/') so GitHub Pages can serve it straight from the branch — Settings → Pages → deploy from main / docs.

Structure

index.html            all sections + the SVG wall (holds carry data-route/step/x/y)
styles.css            design tokens (both themes) at top, then components
src/main.ts           theme toggle, reveals, counters, grade filter, demo form
src/wall.ts           TraceWall — the signature flourish
src/routes.ts         the beta: names, grades, setters
src/reveal.ts         IntersectionObserver reveals + counters
public/guide/index.html   "How Crux was built" (self-contained, copied to docs/guide/)
public/.nojekyll      GitHub Pages serves the output as-is

Demo vs. real

Everything here is fiction: the gym, the grades, the prices, the bell. The join form is a demo — it validates and confirms in place but sends nothing anywhere. To take real sign-ups, point the submit handler in src/main.ts at your own endpoint (Formspree, a serverless function, your CRM).

License

MIT — see LICENSE. Designed & built by Parable.

About

Crux — bouldering gym. Parable template (Vite+TS): trace-a-route SVG climbing wall with grade filter, light/dark, reduced-motion aware, MIT.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages