Watch
1
0
Fork
You've already forked backpack.besthappypanda.com
0
Pack Bench — a backpack designer that returns the cut list, nesting layout, webbing schedule, hardware list and build order. Static HTML, installs as an offline app.
  • JavaScript 55.7%
  • CSS 26.9%
  • HTML 14.5%
  • Shell 2.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Adam Harvey e6c5b836d7 Pack Bench: a backpack designer that returns the cut list
Static site, no build step. The designer computes capacity, panel cut sizes with
seam allowance, a shelf-packed nesting layout on the chosen roll width, webbing
and hardware schedules, an estimated empty weight and a build order — all in the
browser, with the design carried in the URL.

Installs as an offline app via a service worker and web manifest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 07:50:21 +01:00
public Pack Bench: a backpack designer that returns the cut list 2026-09-09 07:50:21 +01:00
tools Pack Bench: a backpack designer that returns the cut list 2026-09-09 07:50:21 +01:00
.gitignore Pack Bench: a backpack designer that returns the cut list 2026-09-09 07:50:21 +01:00
.pages Pack Bench: a backpack designer that returns the cut list 2026-09-09 07:50:21 +01:00
README.md Pack Bench: a backpack designer that returns the cut list 2026-09-09 07:50:21 +01:00

Pack Bench

A backpack designer that gives you the paperwork. Set the dimensions, pick the fabric, closure, pockets, harness and colourway, and it returns the whole spec: a panel cut list with seam allowance, a to-scale nesting layout on the roll, a webbing schedule, a hardware list, an estimated empty weight and the order to sew it in. Static HTML — no build step, no framework, no dependencies. Installs as an offline app.

Live at https://backpack.besthappypanda.com

Layout

.pages           bovine-pages-server config (enables the site, sets the domain)
public/          everything that gets served
tools/           helper scripts, not published

Bovine serves the contents of public/ — nothing above it is web-visible.

Deployment

The dev folder is ~/Documents/knitting site/backpack-designer, which sits inside a working tree holding three unrelated sites, so this repo is kept separate and public/ is rebuilt from it:

sh tools/sync-from-dev.sh
git add -A && git commit -m "Update site" && git push

Pushing to main is the deploy — bovine reads the default branch directly, there is no build step.

Things that fail silently

  1. Bump the service worker cache after any asset edit. public/sw.js serves assets cache-first, so an edited stylesheet or script stays invisible to anyone with the app installed until const CACHE = "pack-bench-vN" changes. This site also versions its assets in the markup (app.css?v=N), and the ?v= in sw.js's PRECACHE must match what index.html asks for, or the worker caches a URL nothing ever requests. One number governs both.
  2. The repo name must stay backpack.besthappypanda.com. Bovine verifies domain ownership against a DNS TXT record holding sha256("owner/repository"). Rename the repo and the custom domain silently 404s while the pages URL still returns 200.
  3. Re-registering the domain needs an explicit /index.html — the dots in the repo name make bovine read .com as a file extension, so the bare directory path 404s.

The dev folder reaches its three sibling sites by relative path, and carries a data-port on each link so a dev machine can hit the sibling's local server. tools/sync-from-dev.sh rewrites those to the live URLs and strips data-port, then asserts that no ../ link, no data-port and no localhost URL survives into public/. It fails loudly rather than shipping a dead link.

What is in the site

One page. The drawing is a front and side elevation at one fixed scale, drawn as SVG from your numbers; the nesting layout packs the cut panels onto the roll width for the chosen fabric and tells you the length to buy. Everything is computed in the browser — no account, nothing sent anywhere, and the whole design round-trips through the URL so a link carries it.