#design
12 posts
Putting a Three.js island inside a static site
The isle page downloads only its own script. The scene is computed at runtime, Three.js stays in that page's chunk, and the first HTML response carries an empty stage.
Volume without a modelling tool: triangulating an island by hand
The rock on this island is not exported from a modelling tool. It is five irregular rings stitched together at runtime, and vertex colours plus flat shading are enough to make it read as stone.
Lighting one scene: three lamps and a shadow map computed once
A hemisphere light for ambience, a key light for direction and shadow, a rim light to pull the island off the background — and seven point lights that only add glow.
Water from two shaders: a pool, a stream and a waterfall
There is no water simulation on the island and no reflections. Two ShaderMaterials cover all of it, one lying flat and one falling, sharing a single time and night uniform.
Using @layer to make CSS precedence a declared order, not a specificity fight
Runaway styles come from everyone solving problems by adding specificity. Cascade layers make the order explicit: between layers only order matters, and specificity applies within a layer.
Anchors hidden behind a sticky header: one scroll-padding-top for the whole site
A sticky header covers every anchor target. scroll-margin per heading always misses one; scroll-padding-top on the scroll container does not, fed by the real header height.
Use the native dialog element: you get more than you think
A hand-rolled modal needs a focus trap, ESC handling, scroll locking and focus restore. Native dialog with showModal has all of it plus ::backdrop, and one style rule as the price.
Dark mode forms stay white: color-scheme is the switch
Painting a dark background does not darken native controls. Select popups, date pickers and autofill follow color-scheme; accent-color only reaches checkboxes and sliders.
Design tokens: one file that runs the whole site
Why every colour, spacing step and corner radius lives in _tokens.scss — and why changing this site's entire visual direction only touched two files.
Manual i18n: what hand-rolling three languages costs
I hand-rolled this site's i18n instead of using Astro's built-in config. Here is why, and exactly where the cost shows up — two 404 incidents and a blog that was half translated.
Turning screen-printing limits into design tokens
This site's visual direction is Riso screen printing. What I actually built was the printing constraints as tokens, so retheming touched two files and no component changed.
A theme-switch ripple with the View Transitions API
A circle growing from the click point reveals the new theme. The radius must reach the farthest corner, and the custom properties must be cleaned up or they leak into the next switch.
