E-commerce by design
Easy to buy from.Easy to run.
A shop has two sides: the one your customers touch and the one your team runs. On our new system both start from rules held in code: a choice before the bag, a bag that is not lost, prices checked again at checkout, taxes to the cent. Below, a small demonstration shop called Nocturne is open. Add, choose, change your mind: nothing is sold and nothing is charged.
Nocturne is a demonstration: its goods are drawn for this page, its prices are invented, and no payment details are asked. The rules run live in your browser, and your demo bag stays there.
01 · The shelf
One tap, and the bag answers.
Nothing to choose: one tap from the card. Options: the card asks first. Watch the bag answer, then take over: the goods are invented, the bag is real shop code kept in your browser.
Nocturneprovisions for clear nights
01 · The shelf
Comet seeds
CAD 9.00
Nothing to choose
Constellation puzzle
CAD 29.00
At most 3 in the bag
Tide glass
CAD 24.00
One size · 500 ml
Moon lantern
CAD 38.00 – 64.00
4 phases · 1 sold out
Moon lantern
Choose a phaseCAD 38.00 – 64.00
Star tea
CAD 14.00 – 28.00
50 g or 120 g
Star tea
Choose a sizeCAD 14.00 – 28.00
Aurora scarf
CAD 72.00
4 colours · 1 sold out
Aurora scarf
Choose a colourCAD 72.00
02 · Your bag
Shown by the tour
Drawn goods, invented prices. The bag is real shop code, kept in your browser and sent nowhere.
How this is read
One tap, or a choice first
The shared purchase rules of our new system decide each card’s action. A product with nothing to choose, or with a single option, goes in from its card in one tap. A product with options asks first, and its card shows the range until a choice is made. A sold-out option stays in sight, disabled. Each product also keeps its own limit per line.
What a line stores
The product, the chosen option, the quantity, and a price kept for display only: at checkout the shop prices the bag again from its own records.
Where it is kept
In this browser’s storage, under a name of its own, so it follows you to a second tab and through a reload. Nothing in it is sent anywhere. The real shop on this site keeps a separate bag, which this page leaves untouched.
The tour
The story that plays first runs on a bag of its own, tagged “Shown by the tour”. It never writes into yours: only your own taps do.
02 · Choices
No choice, no bag.
Until a phase is chosen, the lantern shows its price range and its button says what is missing. A sold-out phase stays in sight, disabled. Switch the rule off and see what an ordinary shop does.
The moon lantern’s page
01 · The piece
02 · The choice
Moon lantern
price range · nothing chosen
03 · The rules
0 of 5 lit by you- Nothing goes in without a choice, not yet met
- Unchosen, the price is a range, not yet met
- Sold out stays in sight, disabled, not yet met
- A single option is not a question, not yet met
- Quantity keeps the product’s limits, not yet met
Quarantine · kept out of your bag
Empty. Only “Without it” puts a line here.
The rules run live from the shop code of our new system. The lantern, its prices and its stock are invented.
How this is read
- Nothing goes in without a choice
- Add asks the shared purchase rules first. While no phase is chosen they answer that a choice is missing, and no line is built. Putting the first option in the bag without asking makes an order that is wrong and internally consistent, so it is found by a customer, not by a test.
- Unchosen, the price is a range
- Until a phase is chosen, no single price is true, so the page shows the lowest and the highest of the lantern’s phases. One price appears only once the rules have a phase to price.
- Sold out stays in sight, disabled
- A sold-out phase stays on the page, named and disabled. A keyboard still reaches it and hears why it cannot be chosen; a phase that vanished would leave the shopper wondering whether it ever existed.
- A single option is not a question
- When a product has one option, the rules choose it before anyone arrives, even on a page that asks for every other choice. The tide glass goes in with one tap.
- Quantity keeps the product’s limits
- The stepper takes its least, its most and its step from the product, and the rules check them again when the line is built. Your bag holds each line to the same most: the lantern stops at two per phase.
- Live, and “Without it”
- Each ring lights from the shared rules’ own answer, computed in your browser, not from a timeline. “Without it” runs the same lantern through a shortcut, the first phase when nothing is chosen; its line is held in quarantine and never reaches your bag. The tour presses the same buttons you do and never writes to your bag.
03 · The bag
A bag that keeps up.
Change a quantity and every figure follows; remove a line and it can come back. Cross the threshold and a gift joins. Then reload, or open a second tab: the bag is kept in your browser.
The bag, on the bench
01 · The bag
CAD 28.00 away from a star-chart postcard, free
- CAD 9.00
Comet seeds
CAD 9.00 each
1 - CAD 24.00
Tide glass
500 ml
CAD 24.00 each
1 - CAD 14.00
Star tea
50 g
CAD 14.00 each
1
02 · Kept in your browser
Read live
—
03 · Another tab
Open a second tab and change the bag there: this one follows.
Open a second tab to see it
Read live from this browser’s storage. Nothing about this bag leaves your device.
How this is read
Where the bag lives
The bag is the basket store the headless WordPress shops of our new system run, kept in this browser’s localStorage under its own key. Every change writes the whole bag again with a new revision, a random id the shop uses to tell one version from the next. The bytes are the length of what is stored, counted as UTF-8.
Through a reload, in a second tab
On load the bag is read back from storage, and again on pageshow, so the back and forward buttons bring it back too. Another tab of this site receives a storage event each time this one writes, and reads the bag again: both stay in step. A storage event only fires for a change made in another tab, so the live label here is proof that one exists.
When storage is refused
Some private windows and strict settings refuse storage. The bag then lives in memory for this visit and says so here, instead of failing.
Intentions, not an order
The bag holds products, options and quantities, with prices as shown. It is not an order: prices are confirmed at checkout, from the shop’s own records (section 04).
The gift and the requests
A shop can set a gift from a threshold; Nocturne’s, the postcard and its prices are invented. Here the gift stands in the bag’s head, worked out from the subtotal: it is not a line, so it is not counted, priced or removed. On the WordPress shops of our new system, the shop’s own server applies the rule again to the order it receives. The request count reads the browser’s Resource Timing for requests started in the second after each of your changes here, not counting the framework’s own page prefetches.
The tour
The tour plays on a copy: of your bag when it has lines, of an example bag when it is empty. Its reload and its second tab are shown, not done; the two buttons above do them for real.
04 · Checkout
Prices are set at the door.
What leaves your browser names products, options and quantities, and no price. The shop prices them from its own records and taxes them for where the order goes. Change a price here: it is ignored.
01 · Your browser
The bag, as data
- basketId
- 6e6f637475726e65a7c3e19052d48f6b
- revision
- 3f1c9a7e5b2d4086c1e8f3a59b7d2e60
- Comet seedshow many ×1price shown CAD 9.009001 · 0
- Tide glass · 500 mlhow many ×1price shown CAD 24.009003 · 90031
- Star tea · 50 ghow many ×1price shown CAD 14.009005 · 90051
- Moon lantern · Crescenthow many ×1price shown CAD 38.009004 · 90041
02 · Our server
What actually leaves
- version
- 1locale en
- basketId
- 6e6f637475726e65a7c3e19052d48f6b
- revision
- 3f1c9a7e5b2d4086c1e8f3a59b7d2e60
- productId 9001variationId 0quantity 1
- productId 9003variationId 90031quantity 1
- productId 9005variationId 90051quantity 1
- productId 9004variationId 90041quantity 1
Seal · HMAC-SHA-256good for 5:00
—
—
after the # in the address, out of server logs
03 · The shop’s records
Priced again, taxed for the address
- Comet seeds×1shown CAD 9.00CAD 9.00
- Tide glass · 500 ml×1shown CAD 24.00CAD 24.00
- Star tea · 50 g×1shown CAD 14.00CAD 14.00basic grocery · no GST or QST
- Moon lantern · Crescent×1shown CAD 38.00CAD 38.00
SubtotalCAD 85.00
taxed on CAD 71.00
- GST 5%3.553.55
- QST 9.975%7.082257.08
TotalCAD 95.63
04 · The payment
Sealed, and not ours
Card details are typed into the payment provider’s own secure fields, never into ours. For a WordPress shop, WooCommerce’s checkout takes over here.
This demonstration stops at the door.
Payment code fetched by this page
—
js.stripe.com · m.stripe.network
01 · The bag
As it is now
- revision
- 3f1c9a7e5b2d4086c1e8f3a59b7d2e60
- checkout opened at
- b84e2a6c90d13f57e2a8c4b6d1f09e35
- Comet seeds×1
- Tide glass · 500 ml×1
- Constellation puzzle×1added since
- + 2 more lines
02 · The receipt
Back from checkout
- state
- completed
- for revision
- b84e2a6c90d13f57e2a8c4b6d1f09e35
- items
- —
isLostCheckout(receipt)false
03 · The bag after
What the rules decide
reconcileBasket(bag, receipt)
Kept5 lines
- Comet seeds×1
- Tide glass · 500 ml×1
- Constellation puzzle×1
- + 2 more lines
04 · Four returns
Run each one
Only a completed order for this exact bag empties it.
Change a price, continue, alter the packet: every check runs in your browser, on a copy of the bag.
The packet is built from the example bag; taxes use the rates checked on 2026-10-02. The shop’s side is simulated. Signed here with a throwaway key made in your browser for this page. A real shop signs on its server, with a secret the browser never sees.
How this is read
- The projection
- The function the WordPress shops of our new system run before checkout, applied live to a copy of the bag. It keeps the version, the bag, its revision, the language and, for each line, the product, the option and the quantity. Every other key is dropped, and the list of dropped keys is computed, not written.
- The seal
- HMAC-SHA-256 from your browser’s own cryptography, over the packet written as base64url, under a key made once when this page opened, never stored, gone when you leave. On our WordPress shops the server signs with a secret it shares only with the shop; the packet is good for five minutes and rides after the # in the address. For our own shop the server checks the bag itself and prices each item from its catalogue before the payment provider is called.
- The prices
- Nocturne’s catalogue stands in for the shop’s records: the server’s side is simulated in your browser, and the prices are invented.
- The taxes
- The site’s own sales-tax module, for a shop in Québec registered for the GST/HST and the QST: each tax is worked out on the taxable lines and rounded to the cent on its own, as on an invoice. Star tea, a basic grocery, is zero-rated. A provincial sales tax applies only where the shop is registered for it, so none is shown.
- The return
- The two rules the shops of our new system run when a visitor comes back from checkout, on a copy of the bag with made-up receipts. A receipt for an older revision never erases newer choices, and an open checkout holding nothing is treated as lost, not as a choice.
- The payment code
- Read live from Resource Timing: requests this page made to js.stripe.com and m.stripe.network. Our own shop loads Stripe’s script only when its checkout opens, and this page has no checkout.
05 · Your side
One tap for them. Four things for you.
The customer sees a confirmation in their language. On your side, at the same moment: the order arrives in WordPress, stock counts down where it is tracked, emails leave, the payment is recorded. Watch both.
01 · Their screen
02 · Your side
An example order, shown by the tour
Thank you
Order DEMO-7F3A
- Comet seeds×1
- Tide glass×1
- Star tea×1
- +1 more
- Star-chart postcardFree
TotalCAD 95.63
A confirmation is on its way
- Ordersin WordPressWaiting for the next orderDEMO-7F3A4 itemsCAD 95.63PaidNewDEMO-9B052 itemsCAD 66.69PaidExampleDEMO-2C811 itemCAD 28.00PaidExampleDEMO-7F3A · 4 items · CAD 95.63Paid
- Stockwhere the shop tracks it+1 more lineMoon lantern · Crescent2 → 1Low stock · your team is toldTide glass · 500 ml7 → 6Star tea · 50 g12 → 11Moon lantern · Crescent · 2 → 1Low stock · your team is told
- Emailssent by your shop
To the customer · in EnglishDrawn: not sent
Your Nocturne order DEMO-7F3A is confirmed
Thank you. 4 items, CAD 95.63, GST & QST included.
- Paymentrecorded on the order
- Paid
- Recorded on the order
- Paid out on your provider’s terms
Total CAD 95.63: subtotal 85.00, plus GST 3.55, QST 7.08. Star tea: basic grocery · no GST or QST.
Paid · recorded · paid out on your provider’s termsStar tea: basic grocery · no GST or QSTCAD 95.63
1 order · 4 items · stock updated · 2 emails · CAD 95.63 recorded
In your shop’s admin, where your team already edits the site. Saving a product refreshes the storefront in the background (see Performance by design).
No order is created and nothing is charged. Steps as shops on our new system record a sale; times drawn; taxes computed from your bag.
How this is read
- Where your team works
- In your shop’s admin, where your team already edits the site. Saving a product refreshes the storefront in the background (see Performance by design).
- Illustrative
- The flow and its timing are drawn. No order is created, no email is sent and nothing is charged. Nocturne’s stock and the two example orders in the list are invented, like its goods and prices.
- The four steps
- They are how a sale is recorded on the WooCommerce shops of our new system: the order created in WooCommerce, stock reduced where the shop tracks it, the customer’s confirmation and the team’s new-order notice sent by the shop, and the payment recorded on the order through the payment provider. A bag that asks for more than the shelf holds is refused at checkout.
- Real
- The figures are computed from the bag in integer cents. The taxes come from the site’s own sales-tax module, worked out on the taxable lines (Star tea, a basic grocery, carries no GST or QST), each tax rounded to the cent on its own, at the rates checked on 2026-10-02. Your bag is emptied by the real rule: opening checkout marks the bag’s revision, and only a completed order for that same revision empties it; a bag changed since is kept. “Restore the bag” puts your lines back.
- On our own shop
- This site’s shop adds two steps of its own: a payment is confirmed by a signed message from the payment provider and checked against its records, a repeated message counted once; then a private download link is emailed in the buyer’s language, good for seven days.
The practice
A shop keeps its word. At every click.
A good shop comes from rules held in common rather than decided again for each project: a choice before the bag, a bag that is not lost, a price checked at the door, taxes computed to the cent, and payment details left to the payment provider. We build shops on WordPress and WooCommerce for teams who run their own catalogue, and on Stripe for smaller catalogues like our own. Our new system starts each one from these rules; the look, the products and the voice are yours.
What this page shows is our new system, the way we build today. Sites we delivered before it may not include it.
Planning a shop?
Tell us what you sell. We will show you the first rules we would hold your shop to.
