Objects for everyday rituals
Folio
A small, considered shop — eight things, chosen well. Your basket follows you from page to page, through a reload, even into a second tab.
0 in your basket
Type to filter the shelf — it narrows as you go, no page reload.
Nothing on the shelf matches "".
Try a shorter word, or clear the search to see all eight pieces.
🪔
Aurora Lamp
Light
A warm dimmable glow with a hand-turned oak base.
$149.00
🌀
Briza Fan
Air
Whisper-quiet bladeless airflow, USB-C powered.
$89.00
🔊
Cove Speaker
Sound
Room-filling 360° sound in a palm-sized shell.
$199.00
☕
Dune Mug
Kitchen
Double-walled stoneware that keeps coffee hot for hours.
$24.00
🧊
Fjord Bottle
Kitchen
Vacuum steel, 24h cold, sweat-proof matte finish.
$39.00
🕰️
Glint Desk Clock
Light
E-ink face, ambient backlight, three-month battery.
$69.00
🌿
Haven Diffuser
Air
Ultrasonic mist with a refillable cedar reservoir.
$59.00
🎧
Isle Earbuds
Sound
Active noise cancelling, 30-hour case, tap controls.
$129.00
Your basket 0 items
0
Saved to this browser. Add a few pieces, then head to checkout when you're ready.
Persisted with a single :store cart = []. The very same line on the cart page shares this basket — no backend, no wiring.
✷
Your basket persists across pages, reloads, and tabs. Open this page in two tabs, add something in one, and watch the count rise in the other — that's a :store, synced over the browser's storage event.
Built from Markdown
Every product card, the live search, and the running count are written as plain Markdown with a handful of Darkmown directives. The catalog unrolls from a JSON file; the basket is one shared :store. No components, no JSX, no hand-written event handlers.
View source — it's Markdown
:store cart = []
:computed count = cart.length
:state q = ""
:bind q placeholder="Search the shop…"
::: catalog
@loop /products.json into p where p.name contains q
::: card .product
::: chip
{ p.emoji }
:::
::: body
::: pname
{ p.name }
:::
::: foot
::: price
{ p.price | money }
:::
:button "Add" -> cart += p
:::
:::
:::
@empty
Nothing matches "{ q }".
@endloop
:::
A storefront in two .wd files.
Open the basket →