# The Math Cabinet

A hand-built, dependency-free museum of six interactive mathematical curiosities.
Everything is drawn in the browser with the Canvas API: no images, no libraries,
no build step, no tracking.

**Live:** https://funmath.hanthebot.com/

**Directory share:** https://mgmt.hanthebot.com/s/funmath/  
(append `?list=1` to browse the source files)

## The exhibits

| # | Exhibit | Idea |
|---|---------|------|
| 01 | Fourier's drawing machine | Rotating epicycles trace a heart, star, infinity sign, and rose. |
| 02 | The primes decide to dance | Ulam spiral with a sieve, hover inspection, and mod-4 colouring. |
| 03 | The edge of chaos | Bifurcation diagram of the logistic map, with instant period classification. |
| 04 | A coastline that never ends | Progressive, zoomable Mandelbrot renderer with presets and drag-to-pan. |
| 05 | The most famous unproven shortcut | Animated Collatz hailstone graphs on a log scale. |
| 06 | A fern from coin flips | Barnsley fern and Sierpiński triangle generated by the chaos game. |

The hero is a slowly rotating Lorenz attractor. All animation stops when a section
is off-screen, and `prefers-reduced-motion` is respected.

## Files

| File | Purpose |
|------|---------|
| `index.html` | Content, exhibit structure, controls |
| `styles.css` | Design system, layout, responsive rules |
| `app.js` | All six exhibits + hero, from scratch |
| `README.md` | This note |

## Hosting

The directory is served as a static `hosting` app:

```json
// ~/.config/hosting/apps/funmath.json
{
  "domain": "funmath.hanthebot.com",
  "static": true,
  "root": "/home/hanthebot/chat/funmath",
  "ip_allow": false,
  "tls": true,
  "port": 8201
}
```

It is also registered as a directory share:

```json
// ~/.config/hosting/shares/funmath.json
{
  "root": "/home/hanthebot/chat/funmath",
  "mode": "list",
  "ip_allow": false,
  "title": "The Math Cabinet"
}
```

### TLS

The wildcard `*.hanthebot.com` certificate on this VPS expired in May 2026, so
`funmath.hanthebot.com` has its own Let's Encrypt certificate issued through a
user-owned certbot configuration:

```
~/.config/hosting/letsencrypt/config/live/funmath.hanthebot.com/
```

`/etc/letsencrypt/live/funmath.hanthebot.com/{fullchain,privkey,chain,cert}.pem`
are symlinks to those files, which lets the hosting supervisor's normal
`/etc/letsencrypt/live/<domain>/` convention keep working.

Renewal runs from a systemd user timer:

```bash
systemctl --user list-timers certbot-funmath.timer
systemctl --user start certbot-funmath.service     # renew now
certbot renew --dry-run \
  --config-dir ~/.config/hosting/letsencrypt/config \
  --work-dir ~/.config/hosting/letsencrypt/work \
  --logs-dir ~/.config/hosting/letsencrypt/logs
```

The deploy hook reloads nginx after a successful renewal.

## Notes

- Canvas size adapts to device pixel ratio, with a pixel budget for the heavier
  renders (Mandelbrot, logistic map).
- The Mandelbrot renderer works in row chunks so the page stays responsive.
- Hover the Ulam spiral or the Collatz chart for exact values.
- No server-side code is involved; the app is three static files.
