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

Closed
kayg wants to merge 0 commits from issue/43-real-ui-4 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 and generic components. controls/ are thin wrappers over the #42 primitives: squish switches, selector capsules, svelte-sonner toasts with honest Undo, and the spring check on task boxes in notes (presentational only, [x] is written at once).
  • 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.
  • No server changes: the list uses the paged notes.list (#59) and notes.pin, refreshing the newest page on journal events. Daily notes use daily.open, setup uses the bound tokens from #51, and "Still updating…" follows incomplete (#52).

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, and the click switches the editor in its own frame.
  • Esc in the editor selected a block while closing a sheet, so the block bar covered the page. Esc now closes the sheet first.
  • Every bulleted list crashed WebKit (the bullet's font-size: 0). There's a regression test.

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
  • 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 and generic components. `controls/` are thin wrappers over the #42 primitives: squish switches, selector capsules, svelte-sonner toasts with honest Undo, and the spring check on task boxes in notes (presentational only, `[x]` is written at once). - `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`. - No server changes: the list uses the paged `notes.list` (#59) and `notes.pin`, refreshing the newest page on journal events. Daily notes use `daily.open`, setup uses the bound tokens from #51, and "Still updating…" follows `incomplete` (#52). **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, and the click switches the editor in its own frame. - Esc in the editor selected a block while closing a sheet, so the block bar covered the page. Esc now closes the sheet first. - Every bulleted list crashed WebKit (the bullet's `font-size: 0`). There's a regression test. **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 - 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 13 commits 2026-10-13 20:02:03 +00:00
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
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
Fonts never swap in late (font-display: optional), so a slow first load can't redraw text
Some checks failed
CI / rust (pull_request) Successful in 47s
CI / web (pull_request) Failing after 2m7s
0bdef47a54
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 #68: rebased on the #42 primitives and the paged notes.list (#59), same commit; re-running CI (two WebKit page loads timed out on a loaded runner).

Superseded by https://git.kayg.org/kayg/calternal/pulls/68: rebased on the #42 primitives and the paged notes.list (#59), same commit; re-running CI (two WebKit page loads timed out on a loaded runner).
kayg closed this pull request 2026-10-13 20:05:35 +00:00
Some checks failed
CI / rust (pull_request) Successful in 47s
CI / web (pull_request) Failing after 2m7s

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!67
No description provided.