Teaching artifact
Guide — how this site was built
Part of a 26-site collection designed and built by Hannah Kwakye, engineered with Fable 5. Everything visible is code-drawn — no photographs, no raster images — which here meant crayon SVG doodles, a paper-doll walker, torn-paper edges, and an illustration system that had to feel hand-made while being entirely mathematical. Static hand-authored HTML, CSS and vanilla JS; two self-hosted variable fonts (Baloo 2 for display, Nunito Sans for reading); zero libraries; deployed on Netlify from a Git push.
Signature: the crayon walk
The timeline is one SVG path in a 0 0 100 100 viewBox with preserveAspectRatio="none", stretched over a tall six-row CSS grid. Because the viewBox is percent-space, every path coordinate is a container percentage — milestone pins at y = 8.3, 25, 41.7milestone dots at y = 8.3, 25, 41.7… landhellip; land exactly on the vertical centres of the six equal grid rows, at any width, with no measurement code. vector-effect="non-scaling-stroke" keeps the crayon line the same thickness however the box stretches.
On scroll, progress t through the section maps to a distance along the path via getPointAtLength(t × L). The paper doll is an absolutely-positioned HTML element moved to that point (coordinates are already percentages — just assign them to left/top), the line “draws” behind her with the classic stroke-dasharray/dashoffset trick, and she grows — scale = 0.55 + 0.45t — from newborn to school-ready as she walks, flipping to face her direction of travel. Milestone tags pop with a spring curve when she passes their share of the path length, which the script finds by sampling 600 points and matching each pin to its nearest arc length. Under reduced motion or without JavaScript, the class that arms the popping never gets added: the full line, all six tags and the doll (placed at the school gate) are simply there.
The paper-cut system
Torn edges between sections are hand-drawn SVG paths (preserveAspectRatio="none", ~70 units tall) filled with the next section’s colour — irregular on purpose, like safety scissors. Paper tags get masking-tape strips from a single ::before rule: a translucent sun-yellow rectangle with dashed left/right borders standing in for torn tape ends. Every card carries a half-degree rotation (rotate: -1.2deg and friends) so the page never looks machine-aligned, and hover straightens cards — paper being smoothed flat.
Type & palette discipline
Baloo 2 (400–800 variable, one 33 KB woff2) gives headings their rounded, crayon-adjacent voice; Nunito Sans keeps paragraphs grown-up and legible. All sizes are clamp() fluid steps. The brief’s five colours were audited with the WCAG relative-luminance formula before use: body ink was darkened from brief-plum #5C374C to #4A2C3D (11.7:1 on cloud), teal passes AA on both cloud (6.1:1) and peach (4.8:1), and sun yellow — a contrast trap on light grounds — is restricted to chips with near-black text (7.2:1), tape, and the crayon line itself.
Iteration log
-
Pass 1 — design critique
- The header’s “Enrol a child” button rendered plum-on-teal — a nav colour rule was out-ranking the button’s. Screenshots catch what stylesheets hide; the nav colour is now scoped with
:not(.btn).
- Hero art had three flaws at one glance: the children’s kite was peach-on-peach and nearly invisible, a second smiley sun duplicated the corner doodle, and the ground was a hard-edged rectangle. Recoloured the kite sun-yellow, cut the extra sun, redrew the ground as two paper-cut mounds.
- Every torn divider summed to less than its 1440-unit viewBox, leaving a band of the previous section’s colour at the right edge on wide screens. Extended each tear path to exactly 1440 units.
-
Pass 2 — elevation
- Milestone dots were SVG circles inside the stretched viewBox and rendered as tall ellipses; rebuilt them as fixed-size HTML pins that light up sun-yellow as the doll passes. The draw-in was also patchy — Chromium measures dash patterns in screen space under
non-scaling-stroke — so the script now builds a screen-space cumulative-length table from the 600 samples and drives stroke-dashoffset from that.
- Gave the walk a destination: a crayon schoolhouse waits at the path’s end, sky doodles fill the empty corners of the field, and the final tag moved off-centre so the fully-grown doll lands at the school door instead of on top of the card.
- Enlarged the holding-hands motif until the arms genuinely reach out from behind both wordmark cards — at its first size it read as a smudge between two rectangles.
-
Pass 3 — ship quality
- Reduced-motion verified in a forced-preference browser context: line fully drawn, all six tags and lit pins visible, doll parked at the school gate, doodle animations off. The no-JS page shows everything too — the arming class never gets added.
- Automated link audit: 15 unique links, all resolving to in-page anchors, the /guide and /process stubs, the hub, or live sibling concepts. Details cards open; the
?success confirmation renders and takes focus.
- Keyboard walk with the dashed plum ring visible at every stop (sun-coloured on dark grounds); zero console errors at 390/834/1440 px and across scrolled viewport shots of the whole walk.
Deploy
Netlify, straight from the repository: publish = ".", immutable cache headers on /assets/*, Netlify Forms handling enrolment with a honeypot and a ?success confirmation. /guide and /process exist as redirect stubs to these anchored sections, so the collection’s route contract holds on every site.