Real UI: the mockup design on the real engine, the whole flow end to end #60

Closed
kayg wants to merge 10 commits from issue/43-real-ui-2 into dev
Owner

Closes #43

The approved mockup design (#13, rounds 1–3) on the real engine and server, so the whole flow works on next.calternal.cloud.

What works end to end (proven by e2e/flow.spec.ts against a real server with no development user):

  1. Setup with a token bound to an existing person (calternal user create): no name asked. A first-owner token asks for a name only when the server says so.
  2. A passkey (virtual authenticator in the test), then today's note.
  3. Typing, tags in accent colour, + Log (the engine's plusLog, ⌘⇧; / Ctrl+Shift+;).
  4. The list with live title/snippet/tags/dates: notes.list and save events now carry them.
  5. Opening other notes, and hover margin controls (handle, → make it a note, ⋯ opening the one menu).
  6. The one bottom bar: tabs (Notes/Settings) → note tools → text bar → block bar. Style, Insert and Info sheets grow out of it.
  7. Settings: appearance, account, real signed-in devices with revoke, sign out. Signing back in with the passkey.

Pieces

  • packages/ui: tokens, glass, motion helpers, warm tooltip, copy-in-place, generic components, and controls/ (Selector, Toggle, toast) as thin placeholder wrappers. src/primitives/ is left for #42.
  • apps/web: the mockup's screens wired to real data. lib/editing.svelte.ts bridges the bar and CodeMirror, with every change as a plain markdown edit. lib/notes.svelte.ts is the list store, seeded by notes.list and kept live by journal events. Daily notes use daily.open.
  • Server: crates/notes/src/summary.rs (list fields, cached by file size and modified time) and summary data on saved/changed/created/renamed events.

Found and fixed on the way

  • Source mode used to switch to a monospace font, reflowing the whole note (CI caught it as a late layout shift). It keeps the note's font now.
  • Esc in the editor selected a block while closing a sheet, so the block bar covered the page. Esc now closes the sheet first.
  • "Still updating…" follows the server's incomplete flag from #52.
  • Every bulleted list crashed WebKit (the bullet's font-size: 0). There's a regression test.
  • An O(n²) cache prune made a warm 10k-note notes.list take 2 s.

Perf

  • 10k notes: the list is virtual (fixed rows, only visible ones rendered).
  • Scroll JS costs about 0.2 ms. Frame time on this GPU-less dev box is 33 ms without blur and 117 ms with the glass blur. On a GPU that's normal; the perf-VM gate (#44) should measure it.
  • Opening a note from the list took about 190 ms here (debug server, loaded box).

Stubbed with TODOs (each needs a server action or another issue):

  • linked/unlinked mentions
  • the per-note version log in Info
  • delete with Trash (N5)
  • tag rename everywhere (#9)
  • move blocks to another note
  • Unsplash, shuffle and upload backdrops
  • pins and preferences (on this device only for now)

Tests: web e2e 61 passed (Chromium and WebKit at 390 and 1440, plus the flow), 8 skipped by design. Editor unit tests 72 passed, notes Rust tests pass, fmt and clippy clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T

Closes #43 The approved mockup design (#13, rounds 1–3) on the real engine and server, so the whole flow works on next.calternal.cloud. **What works end to end** (proven by `e2e/flow.spec.ts` against a real server with no development user): 1. Setup with a token bound to an existing person (`calternal user create`): no name asked. A first-owner token asks for a name only when the server says so. 2. A passkey (virtual authenticator in the test), then today's note. 3. Typing, tags in accent colour, + Log (the engine's `plusLog`, ⌘⇧; / Ctrl+Shift+;). 4. The list with live title/snippet/tags/dates: `notes.list` and save events now carry them. 5. Opening other notes, and hover margin controls (handle, → make it a note, ⋯ opening the one menu). 6. The one bottom bar: tabs (Notes/Settings) → note tools → text bar → block bar. Style, Insert and Info sheets grow out of it. 7. Settings: appearance, account, real signed-in devices with revoke, sign out. Signing back in with the passkey. **Pieces** - `packages/ui`: tokens, glass, motion helpers, warm tooltip, copy-in-place, generic components, and `controls/` (Selector, Toggle, toast) as thin placeholder wrappers. `src/primitives/` is left for #42. - `apps/web`: the mockup's screens wired to real data. `lib/editing.svelte.ts` bridges the bar and CodeMirror, with every change as a plain markdown edit. `lib/notes.svelte.ts` is the list store, seeded by `notes.list` and kept live by journal events. Daily notes use `daily.open`. - Server: `crates/notes/src/summary.rs` (list fields, cached by file size and modified time) and summary data on saved/changed/created/renamed events. **Found and fixed on the way** - Source mode used to switch to a monospace font, reflowing the whole note (CI caught it as a late layout shift). It keeps the note's font now. - Esc in the editor selected a block while closing a sheet, so the block bar covered the page. Esc now closes the sheet first. - "Still updating…" follows the server's `incomplete` flag from #52. - Every bulleted list crashed WebKit (the bullet's `font-size: 0`). There's a regression test. - An O(n²) cache prune made a warm 10k-note `notes.list` take 2 s. **Perf** - 10k notes: the list is virtual (fixed rows, only visible ones rendered). - Scroll JS costs about 0.2 ms. Frame time on this GPU-less dev box is 33 ms without blur and 117 ms with the glass blur. On a GPU that's normal; the perf-VM gate (#44) should measure it. - Opening a note from the list took about 190 ms here (debug server, loaded box). **Stubbed with TODOs (each needs a server action or another issue):** - linked/unlinked mentions - the per-note version log in Info - delete with Trash (N5) - tag rename everywhere (#9) - move blocks to another note - Unsplash, shuffle and upload backdrops - pins and preferences (on this device only for now) **Tests:** web e2e 61 passed (Chromium and WebKit at 390 and 1440, plus the flow), 8 skipped by design. Editor unit tests 72 passed, notes Rust tests pass, fmt and clippy clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
kayg added 10 commits 2026-10-13 19:47:19 +00:00
notes.list now returns what a list shows (title, snippet, tags, date,
last edited, day, words, modified time), read from each file and cached
by size and modified time so a second list of 10,000 notes reads only
what changed. Saved, changed, created and renamed events carry the same
fields, so lists update live without a refetch.

Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Web: Esc closes a sheet before it selects a block; Still updating follows the server's incomplete flag
Some checks failed
CI / rust (pull_request) Successful in 1m0s
CI / web (pull_request) Failing after 1m57s
bc794f8ae7
Part of #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Author
Owner

Superseded by #66: rebased on the #42 primitives and the paged notes.list (#59), plus the source-mode reflow fix.

Superseded by https://git.kayg.org/kayg/calternal/pulls/66: rebased on the #42 primitives and the paged notes.list (#59), plus the source-mode reflow fix.
kayg closed this pull request 2026-10-13 19:57:11 +00:00
Some checks failed
CI / rust (pull_request) Successful in 1m0s
CI / web (pull_request) Failing after 1m57s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal!60
No description provided.