01Glyph field poster

The Type
Atlas & co.

A companion to the Visual Aid Atlas: every way we could think of to help text without drawing a chart. Callouts, quotes, notes, chips, rules, boxes, keys, steps and type itself. Each element carries its number and the name of its kind, so you can point at the ones you want.

Subject matter, as before: the NTB Image Portal prototypes, the Baseline checkout, the receipt feature and the silo rules that keep experiments apart. Scroll and watch the top edge of the window: 02Reading progress bar and 03Sticky running head.

Background: the characters this portal lives on (kr, %, §, IDs, arrows), set in the gallery palette. Hover the field.
What is realQuoted rules, decision IDs, Jira keys, file paths, dates and wording come from the im-web-prototypes repository.Invented user quotes, participant names, reporters, sample terms text and command output are made up for illustration.Mixed real material dressed with invented detail.

A major-third scale from a 15 px base

+657.2 pxCheckout
+545.8 pxPay now
+436.6 pxTotal incl. VAT
+329.3 pxBuying as
+223.4 pxSupplier instructions
+118.8 pxWeb and social media
015 pxPrices in NOK, including VAT.
−112 pxPhoto: creator / credit
Each step is 1.25 times the one below. The sample words are real labels from Baseline's checkout; the scale itself is a suggestion.

One job per signal

Signal Looks like Used only for
Bold Pay now Names of buttons and fields
Italic faktaboks, Pressens hus Foreign words and titles
Highlight incl. VAT for everyone What changed since last time
Small caps NTB · VAT · PDF Abbreviations in running text
Underline a link Links, nothing else
Colour Decided / Assumed Status, never decoration
Mono -lib/vat.ts Code, paths, IDs
Caps, tracked Checkout Eyebrows above a heading
If two signals mean the same thing, readers stop trusting either. The assignments are invented; the words are Baseline's.

A docs page with every level named

Prototype · Baseline
Eyebrow · 11/16 · 700 · caps +8%
Decisions
H1 · 40/44 · 800 · −3%
Where sources disagreed, the one approach this prototype uses everywhere.
Lead · 19/28 · 400 · muted
Prices and words
H2 · 24/30 · 700
D5 · Every customer sees prices including VAT, companies too, everywhere on the site.
H3 · 17/24 · 650
Show customer prices incl. VAT for company and private buyers alike (purchase panel, mini cart, cart, checkout, confirmation, receipt). Admin base prices are entered excl. VAT.
Body · 15/24 · 400
LIP-1440, Slack Q1, 2026-10-08
Source · 12/16 · mono · muted
Text from Baseline's decisions file (D5). The labels give size/leading, weight and tracking.

The badge word at nine weights

100IncludedThin
200IncludedExtra light
300IncludedLight
400IncludedRegular
500IncludedMedium
600IncludedSemibold
700IncludedBold
800IncludedExtra bold
900IncludedBlack
D7: "A license covered by your plan is marked Included." Weights show only where the system font has them.

Numbers that line up, and numbers that read

Proportional

  • 1 111 kr
  • 4 448 kr
  • 11 111 kr
  • 8 880 kr

Tabular

  • 1 111 kr
  • 4 448 kr
  • 11 111 kr
  • 8 880 kr

Lining, serif

  • 8 Oct 2026

Old-style, serif

  • 8 Oct 2026
Prices in a column want tabular figures, so the ones line up under the ones. Old-style figures sit more quietly in running text. Amounts are invented, spacing follows D2.

About 62 characters to a line

max-width: 62ch · comfortable

Experiments often test ideas that contradict each other, so each one is sealed off. Each folder may import only itself and the shared platform. Reusing another experiment's code means copying it. A commit with a cross-import is refused.

24ch · too narrow

A commit with a cross-import is refused before it reaches the repository.

Text from docs/routing.md. The dimension line spans the column, so on a phone it shows the narrower measure honestly. Below it, a column too narrow to read comfortably.

Three levels, each stepped in

1Checkout
1.1Who is buying
1.1.1D13 · From the workspace

Buyer type comes from the active workspace. No company/private choice in checkout.

1.1.2D19 · Buying as

Company name, org. no., address, and "Ordered by".

1.2Paying
1.2.1D14 · No payment step yet

"Pay now" places the order straight away.

Numbers hang in their own column, so headings at the same level share a left edge.

Let the marks hang outside the edge

Set flush

“A feature must work on its own.”
  • Seller and buyer
  • VAT breakdown

Hung

“A feature must work on its own.”
  • Seller and buyer
  • VAT breakdown
The dashed line is the text edge. Hung, the letters align and the quote mark and bullets sit in the margin. Quote from receipt decision R6.

The small characters that make a price look Norwegian

Wrong Right Why
kr 1,711.00 1 711 kr D2: space as thousands separator, øre only when there are any. The spaces are non-breaking, so a price never splits over two lines.
25% 25 % nb-NO puts a space before the per cent sign (D1, D3: "VAT (25 %)").
Pay now - 5 475 kr Pay now · 5 475 kr D8 writes the button with a middle dot.
-25 kr −25 kr A minus sign is as wide as a plus; a hyphen is not.
2-3 days 2–3 days An en dash for ranges.
1920x1080 1920 × 1080 A multiplication sign for resolution and print size (D16).
"Included" “Included” Curly quotes in text; straight ones belong in code.
Press the button: orange marks are non-breaking spaces, blue marks are characters you can't type on a plain keyboard. The minus, dash and quote rows are general advice, not repository decisions.

The news stack

CheckoutLIP-1440Decided

Companies now see prices with VAT, just like everyone else

One answer from UX on 8 October replaced the design's split between company and private buyers. Every price on the site now says "incl. VAT".

Kicker, headline, then a standfirst that tells the whole story in two lines. Facts from D5 and D3; the headline wording is ours.

Who wrote it, where, and what changed since

Updated8 October: amounts on the receipt now include VAT for every buyer (R7). The earlier version showed companies prices without VAT.
The move (7 October) and R7 are from the receipt's decisions. The team byline and the time are invented.

Three lines deep, with a small-caps lead-in

There's no design for the receipt, so it follows the letter in NTB's brand guide: logo top left, the seller's addresses in a narrow left column, buyer and date at the top, set in Geist with Lava and Dyp mørkerød.

The why of receipt decision R1, verbatim.

The capital stands on the first line

Baseline is the "before" the product admin prototype is compared with, finding by finding. The admin copies the one used in the user test, quirks included, so the two can be compared.

A raised cap keeps the first line's baseline, so it never fights the paragraph's shape. Text from D33.

Four facts before the first sentence

WhatPrices incl. VAT for all buyers
Who decidedFerdinand, UX
When8 October 2026
Where it showsPanel, cart, checkout, receipt

Before, the design split buyers: companies without VAT, private buyers with. Admin base prices are still entered excluding VAT.

From D5 and its source line.

Silos, in four lines

TL;DR
  • One experiment per session.
  • Code imports only its own experiment and src/platform.
  • Reuse by copying, with a note of the source commit.
  • Fallow refuses a commit with a cross-import.
Condensed from AGENTS.md and docs/routing.md.

The newspaper sidebar of facts

Facts The receipt

Format
A4 PDF printed by headless Chrome from the receipt page
Seller
NTB AS, Skippergata 24 (Pressens hus), 0154 Oslo
Colours
Lava, Dyp mørkerød and warm greys, whatever the theme
Status
"Paid"; payment method is not modelled
From receipt decisions R1 and R2.

Four figures worth remembering

25%VAT on image licensesreceipt/-lib/vat.ts
5customers to view the site as, each with a different planbaseline/-docs/status.md
200of 232fixtures are editorial, so search starts thereD25
0payment steps: "Pay now" places the order straight awayD14
All four are real. The big number carries the eye; the label carries the meaning; the source keeps it honest.

A sentence that leads with its figures

Of the 232 images in the fixtures, 200 are editorial. A base price of 1 711 kr plus 25 % VAT gives 2 138,75 kr, and because the designs only show whole kroner, the customer sees 2 139 kr.

Numbers from D25 and D11. Set large inside the sentence, they can be scanned without breaking the reading.

Three marker colours, three meanings

Show "Photo: creator / credit" per image with a help tooltip. Whether it depends on editorial vs commercial use stays an open question in the checkout chart. Still waiting for an answer from Elisabeth.

OpenDepends onInterface
D21, verbatim. The marks sweep in when the card scrolls into view, tilted and rounded like a real marker.

Press a key to isolate one kind of phrase

Write "incl. VAT" next to every customer price. Under price lists: "Prices in NOK, including VAT." Checkout, confirmation and receipt totals, for every buyer: "Subtotal excl. VAT", "VAT (25 %)", "Total incl. VAT".

D3, verbatim. Underlines code the phrases quietly; a key turns one colour up and the others down.

A reviewer's pen on a rule

One checkbox for the license agreement; mention "the supplier instructions listed for the images" only when an image in the order has instructions. Private buyers tick a separate withdrawal waiver.

conditional text: test both orders!
only them, companies never see it
needs a legal read (status: Next)
Rule D15, verbatim; the handwritten notes are invented. Circle, wavy underline and box are drawn with CSS and inline SVG, so they follow the words when lines rewrap.

A rule, rewritten, with the reason beside it

RemovedAddedChange bar
Show customer prices excl. VAT for company buyers and incl. VAT for private buyers incl. VAT for company and private buyers alike (purchase panel, mini cart, cart, checkout, confirmation, receipt).
FE8 Oct 2026 · Replaced the design's split, companies without VAT and private buyers with.
The new rule and the reason are D5's. The deleted wording is reconstructed from its "why".

Marks in the text, instructions in the margin

The checkout prototype says licence1 and Web & Social2; a plan badge says Subscribed3. Prices read kr 1,711.004 on the5 site.

  1. 1license (US)
  2. 2Web and social media
  3. 3Included
  4. 41 711 kr
  5. 5insert: live
Every correction is a Baseline decision: D23, D6, D7, D2. On a phone the margin drops below the text.

Tap a dotted word

Each experiment is a . Business rules start from the , the docs sit in a , and keeps it that way. Each session ends with a .

GlossaryTap or hover a dotted word to read its meaning here, without leaving the sentence.
Definitions paraphrased from AGENTS.md and docs/routing.md.

TanStack's file names, defined

route.tsx
The route for its folder's own URL, usually a layoutNames a section: its title is the breadcrumb
index.tsx
The page at the folder's URL exactlyEvery breadcrumb opens a page
$name
A URL parameterMarkdown docs, rule charts, orders
_name
A pathless layout_docs wraps docs pages in the docs shell
-name
Ignored by the router-lib for code, -docs for markdown
a.b.tsx
Flat nesting: b under aOnly for a page plus its PDF
From the table in docs/routing.md.

Small caps, spelled out on tap

VAT is shown on every price. The receipt is an A4 PDF with NTB's addresses and a placeholder org. no. Prices come from the admin, entered in NOK excluding VAT, then formatted as nb-NO.

Tap an abbreviation to expand it in place; tap again to fold it.

Facts from R1, R2, D1 and D5. Small caps keep abbreviations from shouting.

A translation floating above the word

Set in Geist with Lavalava red and Dyp mørkerøddeep dark red, from Pressens husthe press house, SkippergataSkipper Street 24.

Brand colour names and address from R1 and R2; the glosses are our translations. Ruby is made for pronunciation guides, and works just as well for meaning.

Norwegian copy, word by word

Priserprice.pliinNOK,NOKinkludertincludingmva.vat
"Prices in NOK, including VAT."
Handlekurvenshopping.cart-defdinyoureristomempty
"Your cart is empty."
The English lines are real (D3, D10); the Norwegian is our sketch for the customer side, which D4 says will come in Norwegian and English.

One line lifted out of the column

A prototype in a user test shows only what its users would see.

docs/routing.md

App pages never show in the docs nav or breadcrumbs, and their tab titles name only the app. An app may build its own breadcrumb from its own routes.

The facilitator's controls are behind the flask icon, the prototype menu, so a participant never sees a switch they aren't meant to touch.

Floated into the text on wide screens, set full width on phones.

The source, named and linked

A receipt must show what was bought and paid, even if prices or the cart change later.

Receipt decision R3·features/receipt/-lib/decisions.ts
A block quote is for a longer passage someone else wrote; the citation says who and where.

Numbered notes beside the line they belong to

The PDF route has headless Chrome load the receipt page from this server's own localhost address1Not the address the request came in on. See receipt/-lib/pdf.server.ts., so the receipt also works when the prototype is shared through a tunnel2Through ngrok, Chrome got the tunnel's warning page instead of the receipt. That is why R5 exists.. One React component is the on-screen receipt, the browser print and the PDF, with sizes in millimetres and points3R4: "One thing to design and check.".

Receipt decisions R4 and R5. In a wide column the notes sit in the margin; in a narrow one the numbers become buttons that open the note in place.

A rule read by its parts

Says
An image's own instructions from the supplier are shown where they apply, nothing more.
Rule
One alert per image headed "Supplier instructions", only when it has any.
Why
NTB's search API has one free-text field.
Status
Ferdinand's proposal; an assumption until confirmed.
Decision D17, cut into labelled parts so a reader can skip to the one they need.

Details at the bottom, one tap away

The single-purchase flow lives on the order system board1. Checkout isn't made for phones in this round2, and there is no payment step yet3.

  1. FigJam V1PQF8WkLy2WMXUHhVjTHj, node 381:7458. The LIP-1440 link to 278:4667 is gone (D32). ↩
  2. LIP-1440, Slack Q4, 2026-10-08 (D31). ↩
  3. LIP-1436 and LIP-1445 (D14). ↩
Follow a number down; the note lights up. Follow the arrow back up.

Five callouts, five levels of urgency

NoteCheckout isn't made for phones in this round (D31).
TipSwitch between the five sample customers in the prototype menu: the flask icon, or Alt+Shift+P.
ImportantReuse another experiment's code by copying it with scripts/copy-from.ts, never by importing it.
WarningThe purchase panel's "Contact us" still opens a message form; checkout already uses the new contact dialog.
StopA commit with a cross-import is refused by the pre-commit hook.
Colour, icon and label all say the same thing, so the level reads in greyscale and to screen readers. Content from Baseline's status page, D31, AGENTS.md and docs/routing.md.

A note that tells you what to do next

This rule is still an assumption

Supplier instructions (D17) are Ferdinand's proposal. Until confirmed, treat them as provisional.

Facts from D17 and the status page; the buttons jump to other cards here.

Next, on the wall

Ask Ferdinand: should ticked boxes reset when you switch workspace?Next
Undo after removing an imageNext
Decide what logged-out visitors see (LIP-1546)Next
Items from the "Next" list on Baseline's status page, dated 8 October.

A side story the text flows around

The public site has search, an image's page with the purchase panel, the mini cart, the cart, checkout for companies and private buyers, and the confirmation with a receipt you can open as a PDF. The purchase panel appears in every situation from the designs: no plan, a pack, a subscription, both, or an image the plan doesn't cover.

Checkout is as UX designed it for LIP-1440, updated with Ferdinand's answers: prices with VAT for everyone, a review of each image, one box to accept the terms, invoice details for companies, and help that opens in place. The admin is as it was in the user test on 30 September.

Text from Baseline's status page and D33.

Three participants, three reactions

Positive
I like that it says incl. VAT right next to the price. I don't have to ask finance what we actually pay.
P3Picture editorRegional paper, company buyer
Mixed
"Buying as" is clear, but I wanted to change it right there. I didn't expect to go to workspace settings.
P5Photo desk leadTwo workspaces
Negative
The dark picture next to the white panel felt like two different websites glued together.
P7Freelance journalistPrivate buyer
All quotes and participants are invented. They are written to match real decisions: D3 (incl. VAT), D13 ("Buying as" is read only) and D24 (the dark/light mix drew negative feedback).

One quote, given the whole stage

★★★★★
“The terms opened right there in checkout. I never lost my place.”
P2 · Archive manager
Invented, matching D22: license terms open in place.

Short quotes, sorted into piles

Prices 2 of 4 shown

Whole kroner, good.P1

Is VAT in the total or on top?P4

Terms 2 of 3 shown

One box to tick is enough.P6

What's a withdrawal waiver?P7

Help 1 of 2 shown

I'd just phone them.P3

Invented quotes; the themes follow decisions D11, D15 and D30.

Timestamps, speakers, and the line that mattered

FacilitatorYou've added three images. What would you do now?
P5Go to checkout, I think. (clicks Cart, then Checkout)
P5Okay, Pay now and the amount. But it's lit up even though I haven't ticked anything?
FacilitatorWhat do you expect to happen if you press it?
P5Oh, it tells me which box I missed. That's nicer than a grey button.
An invented session, written to show D8: the pay button always works and points out what's missing.

A question asked and answered

8 October 2026
Prototype teamQ1: Should companies see prices without VAT, as in the design?
Ferdinand (UX)No, everyone sees prices including VAT, companies too.
+1 · 3
Prototype teamQ2: Two checkboxes, as in the acceptance criteria?
Ferdinand (UX)One for the license agreement. Private buyers also waive withdrawal.
The answers and the date are real (D5, D15: "LIP-1440, Slack Q1/Q2, 2026-10-08"); the exact wording of the messages is reconstructed.

People as chips inside a sentence

Credit lines wait on EElisabeth; supplier instructions and the terms links on FFerdinand. Prices on the public site come from the admin set up by #product-config.

Who waits on whom is from D21, D17, D22 and the status page.

Reusing another experiment's file

  1. Find the file you needFor example the receipt component in the receipt feature.
  2. Copy it, don't import itbun scripts/copy-from.ts receipt prototypes/baseline receipt.tsx
  3. Find it under -lib/from-receipt/With everything it needs, and the source commit in copied-from.json.
  4. Change it freelyYour experiment owns its copy now.
From docs/routing.md ("Copy, don't import"). The filled circle marks the goal.

Where checkout is, and what doesn't exist yet

  1. Cart
  2. Checkout
  3. Payment
  4. Confirmation
  5. Receipt
Checkout: Buying as (read only), item cards, terms, invoice details. Pay now · total incl. VAT.
Tap a step. The striped, struck-through step is in the flow but not built.

Four ways to say "how far along"

Step 3 of 5 · PaymentSegments
Decisions confirmed by UX78 %
You are here: CheckoutDots
3/5open questions answered on 8 October
The percentages and counts are invented.

Before every commit

0 of 4 done
The four checks of .githooks/pre-commit, from docs/routing.md. Tick them; the count follows.

Done, waiting, not started

  • Checkout as designed for LIP-1440Done
  • Receipt you can open as a PDFDone
  • Contact us in the purchase panelTo align
  • Logged-out visitors (LIP-1546)Undecided
  • Order history and plan pagesNot yet
From Baseline's status page. Each state has its own icon shape, not just a colour.

Two weeks of the prototype

  1. User test of the adminBaseline later mirrors it, quirks included.
  2. Header and widths follow the live siteD9, D12
  3. Receipt becomes a featureD27–D29 move out as R1–R6
  4. UX answers seven questionsVAT for everyone, one checkbox, terms in place D5D15D22
  5. Silos and boundariesExperiments sealed; reuse by copying
Dates from the decisions files, the status page and the commit log.

Baseline's decisions, by group

  • Prices and words 10
    • D1Norwegian formatting
    • D5Prices incl. VAT for all
    • D23"license", US spelling
  • Pages and layout 6
    • D24All light or all dark
    • D25Starts on Editorial
  • Checkout 14
    • D8Pay button always works
    • D14No payment step yet
    • D31Not for phones yet
Group names and decisions from baseline/-lib/decisions.ts; a few per group shown.

Eight bullets, eight tones of voice

Arrow · consequence

  • Remove the last image
  • Empty cart

En dash · plain

  • Creative
  • Editorial

Tick · allowed

  • Copy with copy-from.ts
  • Import src/platform

Cross · not allowed

  • Import another experiment
  • Import src/reference

Squared numbers · order

  1. Cart
  2. Checkout

Letters · options

  1. No plan
  2. A pack

Roman · formal parts

  1. Seller
  2. Buyer

Diamond · highlights

  • Five customers
  • Admin as tested
Items from docs/routing.md, D18, D25, R1 and the status page.

Hanging decimal numbers for terms

The terms text is invented. The license name (D6), the credit line format (D21) and supplier instructions (D17) are real.

When can a buyer pay?

IFthe license terms are accepted
AND EITHER
ORthe buyer is a company
ORthe withdrawal waiver is ticked
THENPay now places the order; otherwise each unticked box shows an error
The canPay guard in Baseline's checkout machine (rules/checkout.ts), with D8 for the error.

Prices and badges, right and wrong

1 711 kr
DoSpace for thousands, kr after (D2)
kr 1,711.00
Don'tThe live site's format; no øre unless there are any
Included
DoOne word for plan coverage (D7)
Subscribed
Don'tFigma's second word for the same thing
The "don't" side is greyed so a skimming eye copies the right one.

Company buyer and private buyer in checkout

Company

Buying as
Company, org. no., address, and "Ordered by"
Checkboxes
One: the license agreement
Invoice details
Your reference, PO number (optional)
Prices
Incl. VAT

Private

Buying as
Name, address, email
Checkboxes
Two: agreement and withdrawal waiver
Invoice details
None
Prices
Incl. VAT
D19, D15, D20 and D5. Rows that don't differ are marked "same" and greyed.

One total, before and after D5

After · every buyer
3 images5 475 kr incl. VAT
Subtotal excl. VAT4 380 kr
VAT (25 %)1 095 kr
Total incl. VAT5 475 kr
Labels from D3; the total 5 475 kr is the one in D8's button. The "before" layout is reconstructed.

What changed in a decision's wording

Widths max 1200 px everywhere follow the live site: full-width header and search, readable content columns. Content gets a max width for reading; backgrounds may run full width.

+11 words−4 wordsD12 · 6 Oct 2026
D12's why: it "replaced everything max 1200 px". The old phrase is quoted from that line.

Copying code between experiments

+For

  • Each experiment owns its versionstrong
  • Ideas can contradict freelystrong
  • Source commit is noted

−Against

  • Fixes don't spread by themselvesstrong
  • Duplicated code

VerdictCopy. Duplication is reported by bun run check, but doesn't stop anything.

The reasons come from docs/routing.md; the weighing is ours.

The same license, priced the new way

Web and social media1 711 kr excl. VATBase price as entered in the admin2 139 krincl. VAT
Rounding2 138,75 krWhole kroner only2 139 kr
D11's example. The old figure stays readable, so the reader can check the step.

Three things people still believe

Myth

Companies see prices without VAT.

Fact

Since 8 October everyone sees prices incl. VAT (D5).

Myth

The buyer picks company or private in checkout.

Fact

It comes from the active workspace (D13).

Myth

You can change the license in checkout.

Fact

Only in the cart; checkout can only remove (D18).

Myths struck through and greyed, facts with their source.

Before and the thing it's compared with

Baseline

The "before"
  • Admin as in the 30 Sep user test
  • Quirks kept, bugs not
  • Labels as tested
vs

Product admin

The prototype
  • Compared finding by finding
  • Its own decisions
  • Its own silo
From D33. The product admin side lists only what Baseline's docs say about it; we didn't read that silo.

One badge family, five weights

Solid · strongest

PaidRefusedPrototype

Soft · in lists

IncludedEditorialCreative

Outline, pill, dot

DecidedAssumedOpen

Tiny caps · beside a title

NewDraftTo align

Split · key and value

VAT25 %buyercompanystatusPaid
Words from D7, D25, R1 and the decision statuses. Weight follows importance, not taste.

Choose a family, then narrow it

Showing 62 of 200 editorial images

Creative and Editorial with no "All", starting on Editorial, and 200 of 232: D25. The topic chips and their counts are invented.

Live, waiting, stopped, never started

Dev server on port 3100Running
PDF through a tunnelWorks (R5)
Ferdinand's confirmation of D17Waiting
Payment stepNot built
The pulse is saved for the one thing that is live right now. Port 3100 is from AGENTS.md; the "running" state is illustrative.

How many, at a glance

Decisions 39Open 2

Press "Add an image": the badge counts up and pops once.

D9 adds a Cart button to the live site's header. The counts are illustrative.

The facilitator's shortcut

Open the prototype menu with Alt+Shift+P, or ⌥⇧P on a Mac. It works over modals too. Close it with Esc.

The shortcut and "works over modals" are from the commit that added the flask menu. Try the keys: the big caps press down. Esc is a common convention, not a quoted fact.

Where a fact comes from, coloured by system

Prices incl. VAT D5 came from JiraLIP-1440, and the receipt follows suit R7. The flow is drawn on Figma381:7458; the admin is copied from im-web906f196.

Every ID is real. The prefix says which system, the colour repeats it.

How sure we are, said inline

Everyone sees prices with VAT Decided. Supplier instructions show only when present Assumed. Whether the credit line depends on editorial or commercial use Open.

DecidedConfirmed by the ownerAssumedOur proposal, until confirmedOpenWaiting for an answer
D5, D17 and D21.

Real or made up, marked on every card

QuotedFrom the repository, verbatim or close
InventedMade up to show the technique
MixedReal facts, invented dressing

"Prices in NOK, including VAT."quoted said P3, a picture editor.invented

The labels next to every number on this page. The last line shows them at word level.

Pictograms set at the size of the words

Open the prototype menu to switch customer. In checkout, the License agreement opens in a new tab and Contact us shows phone and email .

12 px 16 px 22 px 30 px
D22 and D30. Icons are sized in em and shifted to the x-height, so they scale with any text.

A line that says what comes next

Prices and words
Checkout
Admin as tested
Receipt
Open questions3
or
Not built yet
Group names from the decisions files. A centred "or" splits alternatives; a dashed one marks a gap.

Breaks without a heading

Dinkus, asterism, fleuron, a drawn lozenge pair, and the gallery's own colour dots. Use one for a change of scene inside a text.

Eleven rules, labelled

hairline 0.5
1 px
4 px heavy
double
thick-thin
dashed
dotted
gradient
fade-out
wave
hand-drawn
Thick-thin and double come from newspapers; the gradient is the hero's.

A price list the eye can follow across

Prices in NOK, including VAT.
  • Web and social media2 139 kr
  • Included in your plan0 kr
  • Editorial, print and web3 125 kr
  • Commercial, one campaign11 875 kr
  • Pack of 10 editorial downloads18 750 kr
The heading line is D3's. The first price is D11's; the others and the license names after it are invented.

Ten frames, ten levels of separation

OutlineItem card in checkout (D16)
TintedAn alert: "Supplier instructions"
Side barA rule quoted in docs
InsetA field: your reference
Hard shadowThe one thing to press
Double frameFormal: the receipt total
DashedNot designed yet
InverseFacilitator only
With a header strip, for grouped settings
Rules onlyA boxless box: top and bottom rules
Labels inside are uses from the prototypes (D16, D17, D20, R1). Lighter frames for content that belongs to the page, heavier for what stands apart.

Words inside forms

25 %VAT
D5DECIDED
New!
Copied
not
imported
Included Prototype Next: Payment
Circle, hexagon, starburst, seal, tag, ribbon and arrow, all with CSS clip-path or radius, so the text stays real text.

The receipt's status, stamped

Receipt · Order 2026-1008-03
3 images5 475 kr
VAT (25 %)1 095 kr
Total incl. VAT5 475 kr
PAID8 OCT 2026
R1: status "Paid", payment method not modelled. Order number invented. An SVG noise filter roughens the edges like ink.

A sash across a corner

Prototype
Checkout

Not made for phones in this round. Pay now places the order straight away.

D31 and D14. A corner ribbon marks the whole object, not one part of it.

The paragraph bends round the figure

25 %VAT

Totals from prices that include VAT are the same for companies and private persons: VAT is the part inside, the subtotal excl. VAT is what's left. A net price with VAT added is rounded to whole kroner. Every buyer, company or private, sees amounts including VAT and the same VAT breakdown, and the receipt shows it as "Subtotal excl. VAT", "VAT (25 %)" and "Total incl. VAT".

Comments in receipt/-lib/vat.ts and R7. CSS shape-outside makes the lines follow the circle, not its box.

Columns with rules, a headline across them

Experiments are sealed off from each other
From docs/routing.md · Silos: what an experiment may use

Experiments often test ideas that contradict each other, so each one is sealed off. Each folder may import only itself and the shared platform.

Reusing another experiment's code means copying it. A script copies a file and everything it needs into a folder named after its source, and notes the source commit.

The working model is the source. It lives in the reference folder. Baseline has its own copy; improving the shared model means changing the reference, then copying it again.

Fallow checks it. Every folder under prototypes and features is its own zone automatically, after each edit and in the commit hook.

Three columns on desktop, one on a phone, set by column width rather than a count.

A bracket that groups lines and names them

3 × Web and social media6 417 kr
Subtotal excl. VAT5 134 kr
VAT (25 %)1 283 kr
Total incl. VAT6 417 kr
the three lines every buyer sees (D3)
Three images at D11's price (2 139 kr each); totals computed with the receipt's priceSummary(). The bracket spans only the VAT lines and stretches with them.

A path coloured by what each part means

src/routes/prototypes/baseline/-lib/decisions.ts
kindexperimentignored by the routerfile
Wraps only between segments, never inside one. The copy button puts the plain path on the clipboard.

The shape of an experiment

baseline/
├─ route.tsxnames the experiment
├─ _docs/docs shell, adds nothing to the URL
│ ├─ index.tsxthe docs start page
│ └─ decisions.tsxfrom -lib/decisions.ts
├─ app/the running prototype, own chrome
│ └─ _public/…/prototypes/baseline/app/search
├─ -lib/code: components, rules, decisions
└─ -docs/markdown for people
From docs/routing.md. The two highlighted folders are the ones the URL scheme hangs on.

The VAT arithmetic, explained line by line

features/receipt/-lib/vat.tsTypeScript
export const VAT_RATE = 0.251 export function withVat(net: number): number {  return Math.round(net * (1 + VAT_RATE))2} export function priceSummary(prices: number[]) {  const total = prices.reduce((a, b) => a + b, 0)3  const vat = Math.round(total - total / (1 + VAT_RATE))4  return { subtotal: total - vat, vat, total }5}
  1. 1Norwegian VAT on image licenses: 25 %.
  2. 2A net price with VAT added, rounded to whole kroner (D11). 1 711 becomes 2 139.
  3. 3Start from prices that already include VAT, the same for companies and private persons (R7).
  4. 4VAT is the part inside the total, not added on top.
  5. 5The subtotal excl. VAT is what's left, so the three lines always add up.
The function bodies are verbatim; the return type of priceSummary is left out to keep lines short. Hover or tap a yellow marker or a note to light up its partner.

A command, its output, and the refusal

im-web-prototypes
~/im-web-prototypesbun scripts/copy-from.ts receipt prototypes/baseline vat.ts
✓ copied vat.ts → -lib/from-receipt/
✓ noted source commit in copied-from.json
~/im-web-prototypesgit commit -m "Use the receipt's VAT"
✗ fallow: baseline imports features/receipt
  copy it instead: bun scripts/copy-from.ts
~/im-web-prototypes
The commands and the rule are real (AGENTS.md); the output lines are invented to show what the hook does.

Four kinds of computer text in one sentence

Every route sets staticData with a title; layouts that aren't a step use title: null. The type guard lives in src/platform/route-guard.ts, and bun run check runs it all.

codeidentifiersvaluea literal valuepatha file or foldercmdsomething to type
From docs/routing.md and AGENTS.md. Each kind gets its own tint, so a reader knows whether to type it, open it or look for it.

What each part of an address means

/prototypesKindprototype or feature
/baselineExperimentone folder, one silo
/appReservedthe running thing
/receiptPagecopies the real site
/2026-1008-03Param$orderId

Without /app the same prefix is the docs: /prototypes/baseline is the docs start page, inside the pathless _docs layout.

From docs/routing.md and the route file app/receipt.$orderId.tsx. The order number is invented.

The import that's refused, and the fix

baseline/-lib/tenant.ts−1 +1
import { SELLER } from '@/routes/features/receipt/-lib/receipt'
import { SELLER } from './from-receipt/receipt'
export const tenant = {
name: 'NTB',
Fallow: a prototype may import only itself and src/platform.
tenant.ts does import SELLER from its own copy of the receipt (written here relative; the file uses the full alias). The "before" line is invented. Long paths break after slashes only.

Three breadcrumb styles, one source

Chevron

Pills

Slash, collapsed

Tab title, built backwards

Pack lifecycle · Rules · Baseline
docs/routing.md: titles in staticData build the breadcrumbs, the nav and the tab title. "Every breadcrumb opens a page."

Same checkout, three viewpoints

  • "Buying as": company, org. no., address
  • "Ordered by": the user's name and email
  • Optional invoice details: your reference, PO number
D19, D15, D20 and R1/R3. Arrow keys move between tabs.

Questions a participant might ask

Why can't I change the license in checkout?
Checkout is for checking and paying. Change the license in the cart; in checkout you can only remove an image.D18
Why is there no payment step?
It's the next story. "Pay now" places the order straight away.D14 · LIP-1436, LIP-1445
Where do I choose company or private?
You don't. It follows the active workspace; "Buying as" links to workspace settings.D13
Built on native details/summary, so it works without JavaScript and with a keyboard.

A decision as a card: ID, headline, rule, source

D24Pages and layout
A page is all light or all dark, never a dark column next to a light panel.

The mix of dark and light on the details page drew negative feedback.

DecidedBaseline
D16Checkout
Each image in checkout is a card with everything you need to check before paying.

Thumbnail at true aspect ratio, title (two lines max), ID, price, license, credit.

DecidedLIP-1440, 2026-10-08
R6How it's made
The receipt has its own sample orders and works without any prototype.

A feature must work on its own, and prototypes may change their sample data freely.

DecidedReceipt
Headlines and reasons verbatim from the decisions files; the rule for D16 is shortened.

The headline on the front, the reason on the back

Flash cards for learning the decisions. Text from D23, D11, R5 and D25.

The credit line's little question mark

Photo: Ola Nordmann / NTB Name the photographer and agency like this wherever you publish the image.

Hover, focus or tap the question mark.

D21: show "Photo: creator / credit" per image with a help tooltip. The tooltip text and the name are invented (the name is a seed user).

A message that slides in, then leaves

Image removed from your order.
"Undo after removing an image" is on Baseline's Next list; this is how it might look. The bar shows the time left.

Nothing here yet, and where to go

Your cart is empty

Images you add will show up here.

Browse images
Heading and button from D10; the middle line is ours.

Press Pay now without ticking

Accept the license agreement to pay.
Tick to waive withdrawal, or ask us first.
Order placed. (No payment step yet, D14.)
D8: always enabled; an error under each unticked box and focus on the first. D15 for the two boxes (private buyer). Error wording is invented.

Two lines in the card, one in the summary

Item card · two lines
Supporters celebrate on the square outside the town hall after the final whistle in the cup final, with flares and flags in the club colours
ID NTB-8XK2 · 2 139 kr incl. VAT
Order summary · one line
Supporters celebrate on the square outside the town hall after the final whistle in the cup final, with flares and flags in the club colours
Hover for the full title; tap to open
D16: "title (two lines max, full title on hover). In the order summary titles take one line." The image title and ID are invented.

Guess the decision, then check

Which decision says checkout drops search and cart from the header?
D9 · The header is the live site's, plus a cart button; checkout drops search and cart.
Which one keeps the receipt working without any prototype?
R6 · Its own sample orders; never import from a prototype.
The answer sits blurred under the question, so the reader can test themselves first.

The end of a docs page

Page names from Baseline's docs (-docs/status.md, _docs/decisions.tsx). Order is ours.

Where you are inside one page

The headings of docs/routing.md. Read sections are ticked, the current one is marked in the rail.

A dismissible line across the top

PrototypePrices and customers are sample data. Switch customer with the flask icon.
Sample data and the flask icon are from the status page. The banner wording is ours.

The same decision, said three ways

One checkbox accepts the license terms; private buyers also waive withdrawal.
Decision D15's headline, reason and rule, all verbatim. Baseline's decisions are written with a headline for people and a rule for builders.

Change the words, and the numbers follow

A buyer licensing 3 images at a base price of pays 6 417 kr in total, of which 1 283 kr is VAT, and ticks one box before paying.

Computed with the receipt's own rules: withVat() rounds each price to whole kroner, priceSummary() finds the VAT inside the total (vat.ts). The checkbox count follows D15. 1 711 kr is D11's example; the other base prices are invented.

An explorable explanation: the sentence is the interface.

Colour running through the letters

incl. VAT
Prices in NOK, including VAT.
D3's wording. The hero's gradient, slowly moving; a quieter navy-to-blue fade below.

Pattern inside, line around, block behind

SILOS
Copy it
Don't import
The rule in AGENTS.md, three ways: a pattern clipped to the letters, an outline stroke, and reversed type on a block.

A slogan running round a seal

EXPERIMENTS ARE SEALED · COPY, DON'T IMPORT · src/ platform

The words run along an SVG circle with textPath, stretched to close the loop exactly. In the middle, the one folder every experiment may import.

From AGENTS.md and docs/routing.md.

A spine down the side

Baseline · Status
Not there yet

Visitors who aren't logged in. What they should see isn't decided.

Order history and plan pages. Approval steps for editorial use and for some suppliers. A designed front page.

From Baseline's status page. The vertical label names the section like a book's spine and costs no height.

Real interface strings, typed out

Strings from D8, D10, D3 and D17.
For a hero line or a demo. It respects reduced-motion settings and then shows the first string still.

Decisions crawling past, like a news wire

Decided
D5Every customer sees prices including VATD11Customer prices are rounded to whole kronerD24A page is all light or all darkD25Search starts on EditorialR3A receipt keeps a copy of the orderD31Checkout isn't made for phones in this round
A nod to NTB's wire. Hover to pause. Headlines shortened from the decisions files.

Every line set to the full width

Every price
says
incl. VAT
for every
buyer
D3 and D5, as a poster. Each line is scaled to fill the column exactly, at any width.

Where a printed page says where you are

NTB · ReceiptOrder 2026-1008-03
License terms

Web and social media. The image may be published once on the buyer's own website and social media accounts.

Supplier instructions. Only when an image has them.

Credit. Every use shows "Photo: creator / credit".

Editorial, print and web

Use. One publication in print and on the web within 30 days.

Not included. Advertising and commercial use.

NTB AS · Skippergata 24, 0154 Oslo2 / 2
R1: license terms per license and page numbers in the footer. Order number and terms text invented.

The receipt, set like NTB's letter

Receipt8 October 2026 · Order 2026-1008-03 · Paid

SellerNTB AS
Skippergata 24 (Pressens hus)
0154 Oslo

PostBoks 6817 St. Olavs plass
N-0130 Oslo

Org. no.000 000 000

Buyer
Bergens Tidende · Attn. Line Berg
Web and social media · 3 images6 417 kr
Subtotal excl. VAT5 134 kr
VAT (25 %)1 283 kr
Total incl. VAT6 417 kr
Layout and addresses from R1 and R2 (logo top left, the seller's addresses in a narrow left column, buyer and date at the top; org. no. a placeholder). The buyer is one of Baseline's seed customers. Lava and Dyp mørkerød are approximated; Geist isn't loaded, so the system font stands in.

A stamp of a word, in three dimensions

PAID
R1's status, built from eight stacked text shadows and one soft one.

Letters that thicken where you point

Included
200move the pointer or a finger across900
D7's badge word. The system font's variable weight axis is set per letter from the distance to the pointer.