Haute Lumière · A build brief · Published in full
The Reader
This is the missing document. The design exists as a working mockup — Haute Lumiere Reader.dc.html — and the mockup shows what every surface looks like. It does not explain how the note-taking works, how a mark is anchored so it survives a re-render, what the messenger actually connects to, or how a video session with Ammanuel is established on a channel that logs nothing.
Those four things are the whole build. Everything else in the app is layout, and the mockup already answers layout.
Read it alongside The Server, which specifies the machine this application talks to, and The Protocol, which specifies what may and may not be recorded. Where this document and those two disagree, they win — the reader is a client of that architecture, not an exception to it.
- Design source
- The live mockup — Haute Lumiere Reader.dc.html
- Surfaces
- Nine, one bar, seven schools
- Storage
- The device. Nothing else, by default.
- Comms
- Our own machine · end-to-end · no logs
- Offline
- Every purchased title, fully. Non-negotiable.
- Accounts
- Optional. Reading requires none.
Part I
The Shape
Nine surfaces sharing one chrome. The mockup shows all nine; this part names what each is for, because several of them look similar and are not.
Nine surfaces
One
Library
What you own, with its state. Not a store — a shelf. Every item shows where you stopped, in text and in audio, and whether the two agree.
Two
The Reader
The reading surface. Three modes, four edges, seven pens. Where most of the engineering lives.
Three
Listening
Narration with the page following. The sync contract in Part V is the whole feature.
Four
Serene
The player alone — cover, tide, one button. For when the screen is not being looked at.
Five
Journal
Every mark and note from every source, in one book. Part IV.
Six
Store
New titles and issues. Enquiry-priced per prices.json.
Seven
Archive
Every Haute Lumière issue, free, permanently, to everyone.
Eight
The Channel
Messages, rooms, and video. Part VI.
Nine
Coaching
Sessions, the arc, and the door to a private room with Ammanuel.
The seven schools
Every title belongs to exactly one school, and the school is a colour accent rather than a category label. Haute Lumière (gold, free to all) · Ecstatic Economics (green) · Luminous Tantra (coral) · Luminous Clinical (blue) · The Developmental Canon (violet) · Luminous Leadership (wine) · Luminous Mysticism (indigo).
The accent is exposed as --accent, --accent-2, --accent-soft and --accent-fg on a data-school attribute, so switching school re-tints the chrome without touching the register. Register and school are orthogonal — the register is the hour you are reading in, the school is what you are reading. Conflating them is the most likely architectural mistake here.
The school bar
Across the very top, full width, above everything including the rail. It names which school you are in and, behind a short rule at the right, what that school is in one italic line.
Implementation notes that cost time to find: it must be exactly height: var(--bar) with flex-wrap: nowrap, because an auto-height header wraps to two rows at narrow widths and silently breaks the offset every other panel is computed from. The descriptor truncates with an ellipsis rather than wrapping. And the tab strip is flex: 1 1 auto; min-width: 0; overflow-x: auto with the scrollbar hidden — at 480px the strip is wider than the box, and without the scroll the last school is simply unreachable.
The active tab must also be scrolled into view when the school changes programmatically. Measure the tab's position relative to the scroll container from bounding rects, not with offsetLeft — offsetLeft is measured against offsetParent, which is not the strip, and it resolves the first tab to a non-zero value.
The rule
One bar, one row, at every width. Everything else is computed from its height.
Local first, always
The governing constraint, and it is not a preference.
A purchased title is a file on the device. It opens with no network, no account, and no permission check. If this application were deleted tomorrow the files would still open in something else. The store's promise is a file, not a licence, and the reader is where that promise is either kept or quietly broken.
Which means: no phone-home on open, no entitlement check before render, no analytics, no crash reporter that transmits content, and no cloud sync of marks unless the reader explicitly asks for it and understands what she is enabling.
Part II
Reading
The reading surface has one job that overrides every other consideration: it must be possible to disappear into. Everything in this part is about the chrome getting out of the way by degrees without ever stranding the reader.
Three modes
Full — rail, text and margin. Everything within reach. The working mode.
Page — the rail goes; your marks stay beside the line that earned them.
Bare — text alone on paper. No rail, no margin, no bar. One faint line at 45% opacity in the corner to return.
The mode is a persisted preference, not a session state. A reader who chose Bare last night wants Bare this morning.
The failure to avoid
The first implementation unmounted the whole edge container in Page mode — which deleted the spine, which was the only way back. Every edge must keep a visible tab in every mode. Hiding a panel is not the same as removing its handle.
The four edges
Left, right and bottom each carry a 30px tab that survives all three modes; the top is the bar. Tabs are hover-reveal on pointer devices and permanently visible on touch.
The left tab opens the rail. The right tab opens the margin, and it doubles as the spine (Part III). The bottom tab expands the narration bar from its collapsed hairline.
Letter size
Four buttons beside the pen, each rendered as a serif A at its own actual size — the control shows the thing rather than naming it. Small 88% · Set (the book as published) · Large 118% · Larger 140%.
It scales the type, the measure and the leading together as one ratio. Scaling font size alone produces a long line of large text, which is worse than the small text it replaced.
The arched progress
The progress indicator is an arc rather than a bar, with a sphere riding it.
Two implementation notes. The sphere must be a zero-length round-capped line with vector-effect: non-scaling-stroke — a <circle> in a stretched viewBox renders as an oval and reads as an insect on the track. And the arc needs a brighter core stroke over a wider dim one so it reads as tubular rather than flat.
Part III
The Marks
This is the part the mockup cannot explain, and the part that will take the longest. A highlight looks trivial and is not: it has to survive a font-size change, a mode change, a register change, a re-render, an app restart, and a revised edition of the text.
Seven pens, seven meanings
Seven highlight colours, and each one means something. This is the feature, not the colour count.
| Pen | Means | Pastel | Vivid |
|---|---|---|---|
| Rose | This moved me | #F3DDE4 | #B0335C |
| Amber | I want to remember this | #F7E7C8 | #B8801E |
| Sage | True, and I already knew it | #DCEADD | #3A7A4E |
| Sky | I do not understand this yet | #D9E7F2 | #2C6690 |
| Violet | This changes something | #E6DBE9 | #6B4A86 |
| Clay | I disagree | #F0DCD2 | #A6532E |
| Ink | Return to this | #DEDCD6 | #2E3436 |
The meanings are shown as tooltips on the pen swatches and as legends in the Journal. A reader who never learns them still gets seven colours; a reader who does gets a coding system.
The vibrancy axis
Each pen has two states. A mark is laid down pastel — a wash under the text. Clicking an existing mark promotes it to vivid: the saturated version of the same hue, which reads as underline-weight emphasis rather than a wash.
That gives every reader a two-level importance axis inside each meaning, without a second control. Clicking a vivid mark cycles it back to pastel; a long press removes it.
On the three dark registers, pastels are far too light to sit under cream text. They are converted to translucent tints of the same hue at 26% alpha rather than swapped for different colours — the hue stays constant so the reader's coding survives a register change. Vivid marks on dark registers are lightened rather than darkened, for the same reason.
Anchoring a mark
The single most important engineering decision in the application. Get this wrong and every mark in the app drifts the first time the reader changes the letter size.
Do not store pixel positions. Do not store DOM node paths. Both are invalidated by re-render, and node paths are invalidated by a revised edition.
Store a text-quote anchor: the exact quoted string, plus 32 characters of prefix and 32 of suffix, plus a character offset into the chapter as a tiebreak. To restore, search the chapter's plain text for the quote; if it appears once, done. If it appears several times, use the prefix and suffix to disambiguate. If those fail, use the offset to pick the nearest.
If a mark cannot be located at all — because the text was revised — it is not deleted. It becomes an orphan, still visible in the Journal with its own note and a quiet line saying the passage has changed. Losing a reader's note because an author fixed a typo is unacceptable.
The record for one mark
{ id, titleId, chapterId, pen, vivid, quote, prefix, suffix, offset, note, created, updated } — and nothing else. No user id, no device id, no session, no analytics envelope.
The margin
The right-hand column, and where notes are written. Each mark in view appears as a small entry: its pen as a dot, the quoted fragment in italic, and the note beneath it in the body serif.
The note field is a serif at reading size — 17px minimum, in Cormorant, not a 13px sans textarea. The cursor falls into a serif in this system; a note is writing, not metadata.
Notes save on blur and on a two-second idle. There is no save button. There is no unsaved state that can be lost by closing the app.
The spine
When the margin is closed, the right edge shows a spine: a vertical run of small dots, one per mark on the current page, each in its own pen colour. It reports what is marked without opening anything, and clicking a dot opens the margin scrolled to that note.
This is also the right tab, so the edge is never without a handle.
Bookmarks
Distinct from marks and deliberately simpler. A bookmark has no colour, no note, and no meaning — it is a place. One gesture sets it, the rail lists them, and the reading position is separately and automatically remembered without any gesture at all.
Do not merge bookmarks into the mark system. A reader who wants to find her place should not have to choose a pen.
Part IV
The Journal
One book that collects every mark and note the reader has ever made, from every source — a purchased title, a free issue, a guided meditation, a coaching session, an idle thought typed into nothing in particular.
It is the surface that makes the application worth returning to for years rather than months, and it is entirely local.
One book, every source
Entries come from five places and each carries its provenance: a mark in a book (with its pen and its quote), a note in a book (attached to a mark or free-standing on a page), an inquiry answer (the ruled sheets in Tantra I and the Gratitude Journal write here), a session note from the coaching arc, and an unattached entry written straight into the Journal.
They are one stream in date order by default. The provenance is a filter, never a separate silo — the point is that a woman can search her own thinking across a decade without remembering which book it was in.
The data shape
One store, one record type, IndexedDB.
{ id, kind, sourceType, sourceId, sourceLabel, chapterLabel, pen, vivid, quote, note, prompt, created, updated }
kind is mark, note, answer, session or loose. prompt holds the question for an inquiry answer, so the answer still makes sense in ten years when the book is closed.
Indexed on created, sourceId, pen and kind. Full-text search is over quote, note and prompt.
Search and filter
One serif search field at the top — 24px, because the cursor falls into a serif — and three filter rows beneath it: by pen (the seven dots), by source, by kind.
Filters compose. Everything I marked Sky in the economics books is two taps, and it is the single most useful query in the application: show me every passage I did not understand.
Export and print
Two exports, both offered without an account.
The ledger — everything, as a printable document set in the house system with the pen colours intact. This prints. It is the artifact a reader takes to a session, and it is why the Journal is not a database view.
The file — plain JSON, the raw records. Her data, in a form she can keep, move, or open in something else.
Both are generated on the device. Neither passes through a server.
What never leaves
All of it, by default. No sync, no backup, no account, no telemetry on which passages are marked most.
If sync is ever built, it must be end-to-end encrypted with a key that exists only on the reader's devices, opt-in with a plain explanation of the trade, and it must state clearly that a lost device with sync off means lost notes. That is the same honest cost the Server standard states about message history, and it is stated the same way.
A note about a book on desire is exactly the record this architecture exists to never hold.
Part V
Listening
The sync contract
One sentence, and it is the entire feature: your place carries between the page and the voice, in both directions, without being asked.
Which requires a per-title map from character offset to audio timestamp. Generate it once, on the device, with a local forced-aligner at import time — never at runtime, and never on a server. Store it beside the title.
Then: opening the narration starts at the sentence you last read. Opening the text scrolls to the sentence last spoken. Marks made while listening anchor to the text, not to a timestamp, so they behave identically to marks made while reading.
The follow behaviour is a toggle, stated plainly — Page follows the voice / Page stays put — because a reader taking notes wants the page to hold still.
Serene
The player with no page: cover, breathing bloom, an eighteen-bar tide on independent 2.4–5s cycles, progress, one large button, three quiet actions.
Every dimension is clamp() against vh and vw with no breakpoints, so it composes from a watch face to a wall. This matters because Serene is the surface most likely to be used on the smallest and largest screens in the range.
The collapsing bar
The narration bar sits at the bottom and collapses to a hairline when clicked, taking the progress with it. One play speed only — the mockup originally carried several and the clutter was not worth the option.
Collapsed, it keeps a 52px tab, matching the side edges. Same rule as Part II: never remove the handle.
Part VI
The Channel
Messages, rooms, and video — including a private session with Ammanuel. This is the part of the application that touches a network, and the only part, so it is specified against the Server standard rather than described.
What it runs on
Not a platform. Not a hosted service. One machine we own, in a room we control, reached through an outbound tunnel that never opens a port. The full architecture is The Server; the client obligations are these:
Keys are generated on the device, inside its secure hardware, and never leave it. The application cannot read a message it did not receive, and neither can we.
No phone number, no email. Identity is a keypair and a handle. The account arrives on a printed card (Part VIII).
Notifications are blank triggers. The push carries nothing — no sender, no room, no preview. The device wakes, fetches the sealed blob down the tunnel, decrypts locally, and renders the notification itself. An ordinary implementation hands the message text to a manufacturer's push service, which is an astonishing leak given the effort spent encrypting the message.
The client writes no log. Not a debug log, not a crash report containing content, not a local history of who was contacted when.
Messages
Set as writing rather than as chat. Serif at reading size, generous leading, no bubbles, no delivery receipts, no typing indicators, no read state — all four are surveillance of the other person's attention, and this cohort is done being surveilled.
A message can carry a passage: a quoted fragment from a book with its source. That is the feature that makes the channel belong inside a reader rather than beside one — this paragraph, and what I think about it, to one person.
Groups are encrypted identically to one-to-one. There is no tier where a group is readable by the server; a network built for eleven women in a room cannot have one.
The Room
Video and voice, on the same machine, with the same properties. Nothing is recorded, at either end, ever. No local capture, no cloud capture, no transcript, no automated notes.
The interface is deliberately plain: the other person, large; yourself, small and dismissible; and three controls — mute, camera, leave. No reactions, no backgrounds, no grid view, no raised hands.
Two things are present that ordinary conferencing omits. A quiet indicator confirming end-to-end encryption and naming the machine the call is on, because this cohort wants the architecture shown rather than asserted. And a notes panel that writes straight into the Journal as kind: session, local-only, so a reader can take her own notes without a recording existing.
A session with Ammanuel
The specific flow, because it is the one that matters commercially and the one the mockup only gestures at.
One
The door
From Coaching, a single line: the next session, its time in her timezone, and Enter the room. No dial-in, no meeting id, no link to lose, no waiting-room branding.
Two
The room opens at the hour
Not before. There is no lobby to sit in and nobody watching her wait. If she is early the line says when it opens.
Three
Both ends verify
A short key fingerprint shown to both, once, on the first session only. Thereafter it is remembered and a change is flagged loudly — that is the only alarm in the application.
Four
Ninety minutes, unmarked
No visible timer counting down. A single soft indication at eighty minutes, once, and nothing else. A clock on the wall changes what gets said.
Five
It ends and nothing remains
No recording to review, no transcript to file. Her own notes are in her Journal. What the practitioner remembers is the only other record, and that is by design.
The nine-month arc is shown as the arc it is — three phases, progressively emptier by intention, ending in a final conversation and a ninety-day follow-up. Progress is stated in months, never as a percentage. This is not a course to complete.
Groups and circles
A circle is eleven people, fortnightly. The application shows the circle as a room with a standing time and a member list that is first names only, and only inside the room — no directory, no profiles, no way to enumerate the membership from outside it.
Reader groups and interest groups are self-created and self-moderated, with the same encryption. The creator holds the room; there is no platform moderation because there is no platform.
The refusals
No read receipts, no typing indicators, no last-seen. No recording, at either end, by anyone. No transcript or AI summary — that would mean transmitting session content to a model, which contradicts everything above. No screenshot suppression theatre: it cannot be enforced and pretending otherwise is a false promise. No presence broadcast — nobody needs to know when she is in the application. No unread badge with a count. A single gold dot, per the design system: the dot, not the badge.
Part VII
Five Surfaces
The same application on a phone, a watch, a headset, a desk and a television. Not five products — one library, one journal, one channel, reached by five different hands.
The governing principle: the hit areas and the chrome scale with the hand; the marks stay typographically exact. A pull-quote is the same measure and the same ratio on every surface. What changes is how close the reader is, what she is holding, and how much of her attention is available.
One codebase, five hands
SwiftUI with a shared core, five thin surface layers. The core owns the library, the mark store, the Journal, the alignment maps and the channel client — none of which know what they are being rendered on.
Everything visual reads from the same token set already built: seven registers on the environment, seven school accents, every colour a token. The seven pens keep their exact hex values across all five surfaces, because a reader's colour coding must mean the same thing on her watch as on her desk.
The one rule that decides the rest
Every surface reads the local hour and sets the register from it. A reader who moves from her desk to her headset at dusk finds both in Dusk. The register is a property of the hour, not of the device.
| Surface | Reads | Marks | Journal | Messages | Video |
|---|---|---|---|---|---|
| iOS / iPadOS | Full | Full | Full | Full | Full |
| watchOS | Listen only | Flag | Read + dictate | Read + dictate | — |
| visionOS | Full | Full | Full | Full | Full |
| macOS | Full | Full | Full · authoring | Full | Full |
| tvOS | Listen only | Flag | — | — | Room only |
iOS and iPadOS
The primary surface and the one to build first. Everything in Parts I–VI applies without modification.
Hit areas never below 44pt. That includes the seven pen swatches, which at 19px in the web mockup are decorative dots — on a phone they become 44pt targets with the visible swatch centred inside, or they are unusable with a thumb.
Marks are made by selection. Long-press to select, and the pen palette rises as a custom accessory above the selection — seven swatches in a row, the last-used one pre-lit. Not the system menu. The system Copy/Look Up sheet is the wrong register entirely and it buries the feature.
Three modes become two gestures. Full and Bare only; Page has no meaning without a rail. A single tap on the text toggles between them, which is the standard reader idiom and the one thing here that should not be reinvented.
The margin becomes a sheet. Swipe from the right edge, or tap a spine dot, and the notes for the current page rise as a medium detent sheet. The spine itself stays as a thin run of coloured dots on the right edge — it is the only chrome that survives Bare mode.
iPad specifically: the rail and margin can both be present as they are on the desktop, and Page mode returns. Pencil support is worth the work — a Pencil hover previews the pen, a stroke lays the mark, and scribble writes the note. That is the closest this application gets to the ruled sheet it descends from.
Blank push triggers. Per Part VI. The notification extension fetches and decrypts locally; the payload from the push service carries nothing.
Apple Watch
The watch does four things and refuses the rest. It is not a reader.
It listens. Narration playback with the standard now-playing surface, the cover, and the one large button. The tide from Serene appears here as eight bars rather than eighteen, because at 40mm the rest is noise.
It flags. One complication-adjacent gesture — a firm press while listening — drops a return to this flag at the current sentence. It is not a pen and it has no colour; it becomes an Ink mark waiting in the Journal for her to decide about later. This is the single most useful thing the watch can do: she was walking, something landed, and now it is not lost.
It reads the Journal aloud. Yesterday's marks, on the wrist, spoken. A small feature that changes the relationship to the Journal from an archive to a practice.
It receives and dictates. Messages arrive as a gold dot and a first name, never a preview. She can dictate a reply — processed on-device, per the privacy floor; if on-device dictation is unavailable, the feature is absent rather than routed through a server.
Never on the watch: video, the pen palette, the reading surface, prices, and the store. Also no rings, no streaks, no daily goal — the design system has no urgency surface and the watch is where that temptation is strongest.
visionOS
The most interesting surface and the one where the temptation to over-build is greatest. Resist nearly all of it.
The page is a page. A single flat window at a comfortable reading distance, sized to the same measure as every other surface — roughly 65 characters. Not a curved wall of text, not three floating columns, not a book with animated page turns. The measure is the measure because of how eyes work, and a headset does not change that.
The margin is a second window. This is the one thing visionOS genuinely improves: notes can sit beside the text at the same depth without stealing width from it. On every other surface the margin costs measure; here it does not.
The register becomes the room. Each of the seven registers sets an ambient tint on the environment — very slight, well under what would read as a filter. Nocturne dims the surroundings; Solstice warms them. This is the register doing what it was always describing.
Marks by look and pinch. Gaze to the passage, pinch to select, and the pen palette appears at hand level rather than in the reader's line of sight. Never require a raised arm for more than a moment.
The Room is presence. A video session in visionOS is the one place the persona representation is appropriate — a session with Ammanuel at conversational scale, seated, at eye level, in her own room. Still nothing recorded, at either end, per Part VI.
Never in visionOS: a virtual library room with shelves to walk through, animated page turns, a floating dashboard of statistics, or anything that requires her to stand. Reading is a seated, still activity and the headset does not get to change that either.
macOS
The authoring surface. Everything the phone can do, plus the two things a keyboard makes possible.
The full three modes, with the rail and margin as real panels. This is the layout the web mockup already shows, and it translates directly.
The Journal becomes a workspace. This is the reason macOS matters: multi-select, bulk re-pen, drag entries into an order, and export a curated ledger rather than the whole book. A woman preparing for a session with nine months of marks needs this and cannot do it with a thumb.
Keyboard throughout. Digits 1–7 lay the seven pens on the current selection — the fastest marking interface on any surface. Space plays and pauses narration. ⌘F searches the Journal. ⌘\ toggles the rail, ⌘⇧\ the margin. Escape steps back through the modes to Bare and no further.
Print properly. The ledger export and any book's inquiry sheets print from here at full quality, on real paper, which is the format they were designed for.
Menu bar, not a floating window. A quiet menu-bar item showing only whether narration is playing and whether a message waits. One dot, no count.
Apple TV
The narrowest surface and the one with the clearest single purpose: a room with more than one person in it.
Listening at ten feet. The cover large, the title, the chapter, the tide, and the progress arc. Type at a minimum of 32pt because nobody is closer than two metres. A firm press on the remote drops the same return to this flag the watch offers.
The Room on a television. A circle meeting or a session with Ammanuel, on the largest screen in the house, with the camera on the set-top or continuity camera. This is the genuine case for tvOS and it is worth building: eleven faces at conversational size in a room she is actually sitting in.
Guided meditations. Audio with a still plate and the breath pacer from the Luminous Library rendered large. No animation beyond the pacer itself.
Never on tvOS: the reading surface, the pen palette, the Journal, the store, and any text entry beyond a search field. A television is not a place to write, and a shared screen is not a place for a private journal.
Handoff
The property that makes five surfaces one application, and it has to work without a server.
Position, both ways, everywhere. The sync contract from Part V extends across devices: page on the desk, voice in the car, flag on the watch, and the phone opens where the car stopped. Carried over the local encrypted channel between her own devices — never through our machine, which has no business holding her reading position.
Marks and notes travel with it, end-to-end encrypted, keyed only to her devices. Same honest cost as everywhere else in this architecture: if she declines device sync and loses a device, the notes on it are gone. Stated at setup, in plain words, once.
Continuity for the Room. A session can move from headset to television to phone mid-call. The call does not drop; the surface changes.
One library, one journal, one channel. Five hands, five distances, one hour of the day.
Part VIII
Getting In
The request form
Already built and live on the Application page; the reader links to it rather than reimplementing it. Its mechanism is worth understanding because the same reasoning governs anything else in the application that collects words.
Six fields: name, where to reply, which door, timing, what you would like to know, and anything you would rather not be asked about — which is honoured absolutely and never revisited.
It composes an email in the reader's own application and she sends it herself. There is a Copy it instead fallback for webmail.
Not a form service, deliberately. A third-party POST endpoint would put a company between a woman and her first sentence, on a property that publishes the Protocol. The honest cost is that mailto is less slick and a minority need the copy button — stated in the interface rather than hidden.
Two details worth carrying: the short option labels have a mapping to full phrases in the composed email, so the column stays narrow while the message that reaches the inbox reads properly. And placeholder text uses color-mix(in srgb, var(--muted) 62%, var(--ink)) — the raw --muted token fails contrast at input size in four registers.
The printed card
An accepted member's account is created by hand on our own machine and printed onto card — a handle, a first credential, and the address of the server — then couriered in a tamper-evident envelope.
The reason a printer is the most secure step in the sequence: the credential never travels through any digital channel at all. Not our email, not hers, not a messaging app, not a password manager. There is no interceptable path because there is no path.
On first launch she enters it once, the device generates its own keypair in secure hardware, she sets her own credential, and the printed one is dead.
Entitlement
Three tiers, and the first one is the important one.
Everyone — every Haute Lumière issue, free, permanently, with no account. The Archive works on a fresh install with nothing signed in.
Purchased — a title bought outright is a file. It opens forever, offline, with no check. Losing access to it must be impossible.
Subscribed — the house subscription unlocks every school. Per prices.json, the figure is not displayed: the surface reads Arranged in conversation.
The line that cannot be crossed
An entitlement check may never gate rendering. If the check cannot run — offline, server down, tunnel closed — the reader keeps reading. A purchase that stops working when a server is unreachable was a licence, and the store promised a file.
Part IX
Building It
Five phases
One
One book, read
Import, render, three modes, four edges, letter size, position remembered. Ships when a title can be read start to finish offline.
Two
The marks
Seven pens, the vibrancy axis, text-quote anchoring, the margin, the spine. Ships when a mark survives a letter-size change and a restart.
Three
The Journal
One store, five provenances, search, the three filters, both exports. Ships when a year of marks is searchable in one field.
Four
The voice
Alignment at import, the sync contract both ways, Serene, the collapsing bar. Ships when a reader can switch mid-sentence and lose nothing.
Five
The channel
Messages, rooms, video, the session flow. Ships when a ninety-minute call happens on our own machine with nothing recorded.
Six
The other four surfaces
macOS next, because it shares the layout and adds the Journal workspace. Then watchOS for the flag, then tvOS for the Room, then visionOS last — it is the most work and the least load-bearing.
Phase two before phase three is deliberate — the Journal has nothing to collect until marks exist. Phase five last because it is the only phase with an external dependency, and every phase before it is independently useful.
The stack
No prescription beyond four constraints, because the constraints are the architecture and the framework is not.
It must run offline in full. That rules out anything requiring a server round-trip to render.
Storage is IndexedDB. One store for the Journal, one for titles, one for the alignment maps. No cloud database.
The messaging layer is a client of our own server, speaking a mature federated protocol with federation switched off. Do not write a protocol.
The visual system is the one already built. Seven registers on data-register, seven school accents on data-school, both orthogonal, every colour a token, color-scheme declared per register, no literal hex anywhere.
Twenty-one tests
- Does a purchased title open with the network disabled and nothing signed in?
- Do all seven registers render every surface legibly, including the three dark?
- Is
color-schemecorrect per register, so native popups follow the page? - Are register and school genuinely independent?
- Does the school bar stay one row from 320px to 2560px?
- Is the active school tab always scrolled into view?
- Does every edge keep a visible handle in all three modes?
- Does a mark survive a letter-size change, a mode change and a restart?
- Does a mark against revised text become an orphan rather than vanish?
- Are pastel marks legible under cream text on the dark registers?
- Does clicking a mark promote it to vivid, and again return it?
- Does a note save without a save button and survive a hard close?
- Does the Journal collect from all five provenances in one stream?
- Does the ledger export print with pen colours intact?
- Does the reading position carry both ways between page and voice?
- Does a notification carry no content to any third party?
- Is there any recording, transcript or summary of a session? There must not be.
- Could a failed entitlement check ever stop a reader reading? It must not.
- Is every hit area at least 44pt on touch, including the seven pens?
- Do the seven pens hold identical hex values across all five surfaces?
- Does the reading position carry between two devices with no server involved?
Never change these
Offline reading of anything purchased. The one promise that cannot be walked back.
The seven pens with their meanings. Not a highlight colour picker — a coding system.
Text-quote anchoring. Any pixel or node-path scheme will drift, and drifted marks destroy trust in the Journal permanently.
The Journal staying local. Notes on these books are the exact record this architecture exists not to hold.
Nothing recorded in a room. At either end, by anyone, including the reader.
No read receipts, no presence, no unread counts. The dot, not the badge.
Everything else — the layouts, the animations, the copy, the order of the surfaces — is open. Those six are what make it this application rather than a competent reader with a chat feature.
Colophon
The Server specifies the machine. The Protocol specifies what may be recorded. The Site and The Landing cover the public property. This document covers the application.
Seven pens with meanings. One journal. One machine. Nothing recorded.