The Process · a design-thinking case study
A season I grew up inside, turned into a page you can feel.
HARMATTAN is the experimental crown of a 26-site portfolio collection — the one piece with no client, no product and no call to action. Just a question: can a web page hold a poem the way weather holds a day? This page covers the brief, the writing of the ten lines, the directions rejected, and the trade-offs accepted. The guide covers the shader math.
The brief
Concept project. Self-initiated art piece — there is no client and nothing for sale. It exists to demonstrate a capability: shader craft, interaction design and writing, working as one instrument. Everything on it is code-drawn; nothing is stock.
The collection needed one site that was pure technique-as-poetry — a Tier D experiment where the signature is the site. The self-assigned brief, in full:
- An original poem about the harmattan — the dry, dust-laden trade wind that crosses West Africa from the Sahara between November and March — one line per scroll scene.
- A full-viewport fragment shader as the only scenography: dust, haze, light. No images.
- The reader's behaviour is the weather: scroll velocity drives wind, the cursor is a hot gust, and the page must darken through the poem — haze, dust rose, ember, night — ending with dust settling into stars.
- Accessibility as a first-class reading of the piece, not an apology bolted on.
Why the harmattan
If you have lived a December in Ghana you know the season by your body before you know it by name: the white mornings when the sun is a coin you can look at, dust filmed over every sill by noon, lips that crack, the smell of distant grass fires at dusk — and then the strange gift at the end of it, nights swept so clean the stars feel newly installed.
That arc — white, rose, ember, night — is a colour script a page can perform. The season came with its own storyboard, which is why it beat every other candidate subject: rain (already taken by a sibling site in the collection, Terra Rhythm), the sea, market noise.
It also solved the hardest problem of "experimental" sites: why should anyone scroll? Here, scrolling is cast as the wind itself. The reader doesn't navigate the poem; they blow through it. Every interaction has a diegetic answer — the cursor isn't a pointer, it's a hot gust; the scrollbar isn't UI, it's the season passing. When form and metaphor close like that, the piece stops being a demo.
And personally: portfolios are full of other people's cities. This one is home weather.
Writing the ten lines
The poem was written before the shader was tuned — the words are the art direction. Rules set at the start:
- Ten lines, one per scene, each able to stand alone on a full screen for as long as a slow reader wants — no enjambment across scenes.
- One day as the spine: morning haze (I–III), deep dust (IV–VI), ember dusk (VII–VIII), night (IX–X). Each line had to belong to its light, because the shader would be graded to it.
- Concrete over lyrical: things you can touch — sills, lips, wells, mangoes, riverbeds. The wind is personified only through verbs of the body: exhale, sign, lie down, remember, spend.
- The last word is the destination. The whole piece scrolls toward "stars", so the shader's finale and the poem's finale are the same event.
Craft notes
Line I casts the wind as the year's exhale and the map's word — the piece's thesis that naming a thing tames none of it. Line II's "coin dropped in milk" is the season's most photographed fact (you can look straight at the harmattan sun); the shader literally draws this line — a pale disc behind haze that later becomes VII's "old coal somebody blew on twice". Line V uses shea as a verb, because that is what a Ghanaian dry season does to the language of skincare; it earns the poem's only borrowed word. Line VIII lets the smoke and the haze be cousins — bush-fire season and dust season arrive as one family. And IX demotes the terrifying wind to "a tired dog" one scene before the sky pays out its dust as stars — spending, not scattering, because the season is a debt being settled.
What got cut
An earlier line III read "The horizon takes the season's census, counting us in dust." — clever, hollow, gone. Its replacement ("the horizon packs its bags and leaves; the sky forgets which blue it was") does what this poem needed everywhere: an image first, the idea smuggled inside it. A draft ending, "and the night wears all our dust as jewellery", was cut for prettiness — spends is a harder, truer verb than wears.
Directions rejected (with reasons)
- A particle system (thousands of sprites in canvas/Three.js) — dust as particles is literal and thin; real harmattan haze is a volume, not confetti. A field representation (FBM density) looks like air; particles look like a screensaver. Particles also collapse at exactly the moment this piece peaks — full-screen, slow, close.
- Three.js — 150 KB of library to draw one rectangle. The piece needs a fragment shader and nine uniforms; raw WebGL2 is ~120 lines and loads instantly. (Sibling sites in the collection use Three.js where geometry earns it.)
- Video or photographic backgrounds — violates the collection's code-drawn rule, weighs megabytes, and cannot respond to scroll velocity or the cursor. The whole point is weather that listens.
- A "typewriter" poem (lines typing themselves on a timer) — makes the reader a spectator. Rejected on principle: the reader's hand had to be the wind, or the piece is a screensaver with captions.
- Sound — tempting (wind begs for it), but it would demand an opt-in UI that competes with the read-as-text toggle for prominence, and the piece works silent. Restraint won; the collection has a dedicated sound site.
Key decisions & trade-offs
Real text in the weather
The lines could have been drawn into the canvas (perfect compositing control) — but then the poem isn't text: no selection, no screen readers, no find-in-page, no translation. Decision: real DOM text with blend modes over the canvas, and teach the shader where the active line sits so it can thin the dust behind it. Trade-off accepted: blend modes are fussy about stacking contexts and cost a compositing pass; worth it for a poem that is actually made of words.
Kinetic weight costs layout
Animating a variable font's weight re-runs layout every frame — normally forbidden. Scoped it to the one visible line (~15 words), measured it, kept it. The gusting letters are the signature; a signature is allowed to cost something it can afford.
The page darkens — so contrast is a timeline
Ink text on haze fails at ember; haze text on haze fails at dawn. The text's colour and blend flip once, at a progress value chosen to land in the gap between lines VI and VII, and the shader's clearing band guarantees the band behind the words trends toward the text's opposite pole in every phase. Contrast was designed as a function of time, not a static pair of swatches.
Accessibility as a reading, not a ramp
"Read as text" is in the header, styled as the most prominent control on the page — not hidden in a footer. Reduced motion gets five still shader frames (rendered once) so those readers still receive the piece's palette arc. If WebGL2 is missing, the text setting simply is the piece. The poem never has a lesser audience.
What this piece is for
As the collection's experimental crown, HARMATTAN is a capability statement dressed as a poem. Framed as design goals:
- Prove the shader craft — original GLSL, art-directed until it reads as weather, not noise; explained openly in the guide so the skill is verifiable, not vibes.
- Prove interaction taste — every input mapped inside the metaphor; nothing gamified, nothing gratuitous.
- Prove the writing — commissioning copy is easier when the portfolio shows the studio can hold a metaphor for ten lines without dropping it.
- Prove the values — the most experimental page in the collection is also its most accessible, because those were never opposites.
Directed by Hannah Kwakye; engineered with Fable 5. The two roles are the collection's standing argument: AI doesn't replace taste — it amplifies the designer who has it.