Skip to content

feat(404): branded leaf-fall custom 404 page + dark 500 fallback (#1190)#1359

Merged
jonfroehlich merged 1 commit into
masterfrom
1190-custom-404-page
Jun 20, 2026
Merged

feat(404): branded leaf-fall custom 404 page + dark 500 fallback (#1190)#1359
jonfroehlich merged 1 commit into
masterfrom
1190-custom-404-page

Conversation

@jonfroehlich

@jonfroehlich jonfroehlich commented Jun 20, 2026

Copy link
Copy Markdown
Member

Closes #1190.

What this adds

A branded, animated 404 page (plus a matching dark 500 fallback), wired through Django's root-URLconf error handlers.

404 — "leaf fall"

The page loads fully assembled (a full-window grid of triangles with the Makeability Lab logo embedded), then the background grid flutters down like falling leaves and settles into a pile, leaving the logo standing. Click anywhere or press R to replay.

  • Uses MakeabilityLabLogoLeafFall from the pinned CDN dist makeabilitylab/js@0.6.0 (startAssembleddropLeaves()).
  • The logo's L overlay is semi-translucent via the lib's setLTriangleFillColor (added in 0.6.0).
  • Responsive: the logo (and its derived grid) shrinks and is lifted by a continuous, width-based amount, so placement stays good from desktop down to narrow phones with no breakpoint jump.
  • Accessibility: all recovery content is real DOM — a big 404 / PAGE NOT FOUND heading, supportive text, and <nav> links — not canvas text. The canvas is decorative (role="img" + aria-label). Honors prefers-reduced-motion (renders the static settled state, drops "Animated" from the label). Each text line gets a tight black highlight for legibility over the grid.

500

Static, dark fallback with the colored logo — no JS/CDN dependency (a 500 means something already broke).

Implementation notes

  • handler404 / handler500 declared in the root URLconf (makeabilitylab/urls.py); views in website/views/custom_404.py.
  • Dev-only /404-preview/ and /500-preview/ routes, registered only when DEBUG=True, so the pages can be viewed locally with static files intact — sidestepping the DEBUG=False/static-serving pitfall that derailed earlier attempts (no global DEBUG flip, no WhiteNoise, no --insecure).

Testing

  • New website/tests/test_custom_404.py (5 tests): 404 status, custom template used, recovery nav links present, requested-path HTML-escaping (reflected-XSS guard), and preview route absent when not DEBUG.
  • Full suite green: python manage.py test website --settings=makeabilitylab.settings_test.

Screenshots

404BrokenGlassMakeabilityLab.mov

Notes / follow-ups

  • Apache scope (see issue comment): Django-routed 404s render this page automatically once DEBUG=False; only 404s for missing /static/ & /media/ files (served directly by Apache) would need an ErrorDocument 404 from UW CSE IT. Not a blocker.
  • Pa11y pass recommended before merge (the page isn't in .pa11yci.json since the preview route is dev-only).

🤖 Generated with Claude Code

Add custom error pages wired via root-URLconf handler404/handler500.

- 404: the page loads fully assembled (a full-window grid of triangles with
  the Makeability Lab logo embedded), then the background grid flutters down
  like falling leaves and settles into a pile, leaving the logo standing
  (makelab-404.js, MakeabilityLabLogoLeafFall from the pinned js@0.6.0 dist).
  Click / press R to replay. The logo's L overlay is set semi-translucent via
  the lib's setLTriangleFillColor. Honors prefers-reduced-motion (static
  settled state). Recovery content -- big "404 / PAGE NOT FOUND" heading above
  the logo, supportive text + nav links below -- lives in the DOM, with a tight
  black highlight per line for legibility over the grid.
- Responsive logo placement: the logo (and its grid) shrinks and is lifted by a
  continuous, width-based amount so it stays well-placed from desktop down to
  narrow phones (no breakpoint jump).
- 500: static dark fallback with the colored logo (no JS/CDN dependency).
- Dev-only /404-preview/ and /500-preview/ routes (registered only when
  DEBUG=True) so the pages can be viewed locally with static files intact,
  avoiding the DEBUG=False/static-serving pitfall of earlier attempts.
- Regression tests: 404 status, custom template, nav links present,
  requested-path HTML-escaping (reflected-XSS guard), preview route absent
  when not DEBUG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jonfroehlich jonfroehlich merged commit ea0fb32 into master Jun 20, 2026
3 checks passed
@jonfroehlich jonfroehlich deleted the 1190-custom-404-page branch June 22, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom 404 page for ML

1 participant